Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2012-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <key.h>7#include <common/system.h>8#include <key_io.h>9#include <span.h>10#include <streams.h>11#include <secp256k1_extrakeys.h>12#include <test/util/common.h>13#include <test/util/random.h>14#include <test/util/setup_common.h>15#include <uint256.h>16#include <util/strencodings.h>17#include <util/string.h>19#include <string>20#include <vector>22#include <boost/test/unit_test.hpp>24using namespace util::hex_literals;25using util::ToString;27static const std::string strSecret1 = "5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj";28static const std::string strSecret2 = "5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3";29static const std::string strSecret1C = "Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw";30static const std::string strSecret2C = "L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g";31static const std::string addr1 = "1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ";32static const std::string addr2 = "1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ";33static const std::string addr1C = "1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs";34static const std::string addr2C = "1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs";36static const std::string strAddressBad = "1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF";39BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)41BOOST_AUTO_TEST_CASE(key_test1)42{43CKey key1 = DecodeSecret(strSecret1);44BOOST_CHECK(key1.IsValid());45BOOST_CHECK(!key1.IsCompressed());46CKey key2 = DecodeSecret(strSecret2);47BOOST_CHECK(key2.IsValid());48BOOST_CHECK(!key2.IsCompressed());49CKey key1C = DecodeSecret(strSecret1C);50BOOST_CHECK(key1C.IsValid());51BOOST_CHECK(key1C.IsCompressed());52CKey key2C = DecodeSecret(strSecret2C);53BOOST_CHECK(key2C.IsValid());54BOOST_CHECK(key2C.IsCompressed());55CKey bad_key = DecodeSecret(strAddressBad);56BOOST_CHECK(!bad_key.IsValid());58CPubKey pubkey1 = key1. GetPubKey();59CPubKey pubkey2 = key2. GetPubKey();60CPubKey pubkey1C = key1C.GetPubKey();61CPubKey pubkey2C = key2C.GetPubKey();63BOOST_CHECK(key1.VerifyPubKey(pubkey1));64BOOST_CHECK(!key1.VerifyPubKey(pubkey1C));65BOOST_CHECK(!key1.VerifyPubKey(pubkey2));66BOOST_CHECK(!key1.VerifyPubKey(pubkey2C));68BOOST_CHECK(!key1C.VerifyPubKey(pubkey1));69BOOST_CHECK(key1C.VerifyPubKey(pubkey1C));70BOOST_CHECK(!key1C.VerifyPubKey(pubkey2));71BOOST_CHECK(!key1C.VerifyPubKey(pubkey2C));73BOOST_CHECK(!key2.VerifyPubKey(pubkey1));74BOOST_CHECK(!key2.VerifyPubKey(pubkey1C));75BOOST_CHECK(key2.VerifyPubKey(pubkey2));76BOOST_CHECK(!key2.VerifyPubKey(pubkey2C));78BOOST_CHECK(!key2C.VerifyPubKey(pubkey1));79BOOST_CHECK(!key2C.VerifyPubKey(pubkey1C));80BOOST_CHECK(!key2C.VerifyPubKey(pubkey2));81BOOST_CHECK(key2C.VerifyPubKey(pubkey2C));83BOOST_CHECK(DecodeDestination(addr1) == CTxDestination(PKHash(pubkey1)));84BOOST_CHECK(DecodeDestination(addr2) == CTxDestination(PKHash(pubkey2)));85BOOST_CHECK(DecodeDestination(addr1C) == CTxDestination(PKHash(pubkey1C)));86BOOST_CHECK(DecodeDestination(addr2C) == CTxDestination(PKHash(pubkey2C)));88for (int n=0; n<16; n++)89{90std::string strMsg = strprintf("Very secret message %i: 11", n);91uint256 hashMsg = Hash(strMsg);93// normal signatures95std::vector<unsigned char> sign1, sign2, sign1C, sign2C;97BOOST_CHECK(key1.Sign (hashMsg, sign1));98BOOST_CHECK(key2.Sign (hashMsg, sign2));99BOOST_CHECK(key1C.Sign(hashMsg, sign1C));100BOOST_CHECK(key2C.Sign(hashMsg, sign2C));102BOOST_CHECK( pubkey1.Verify(hashMsg, sign1));103BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2));104BOOST_CHECK( pubkey1.Verify(hashMsg, sign1C));105BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2C));107BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1));108BOOST_CHECK( pubkey2.Verify(hashMsg, sign2));109BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1C));110BOOST_CHECK( pubkey2.Verify(hashMsg, sign2C));112BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1));113BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2));114BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1C));115BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2C));117BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1));118BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2));119BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1C));120BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2C));122// compact signatures (with key recovery)124std::vector<unsigned char> csign1, csign2, csign1C, csign2C;126BOOST_CHECK(key1.SignCompact (hashMsg, csign1));127BOOST_CHECK(key2.SignCompact (hashMsg, csign2));128BOOST_CHECK(key1C.SignCompact(hashMsg, csign1C));129BOOST_CHECK(key2C.SignCompact(hashMsg, csign2C));131CPubKey rkey1, rkey2, rkey1C, rkey2C;133BOOST_CHECK(rkey1.RecoverCompact (hashMsg, csign1));134BOOST_CHECK(rkey2.RecoverCompact (hashMsg, csign2));135BOOST_CHECK(rkey1C.RecoverCompact(hashMsg, csign1C));136BOOST_CHECK(rkey2C.RecoverCompact(hashMsg, csign2C));138BOOST_CHECK(rkey1 == pubkey1);139BOOST_CHECK(rkey2 == pubkey2);140BOOST_CHECK(rkey1C == pubkey1C);141BOOST_CHECK(rkey2C == pubkey2C);142}144// test deterministic signing146std::vector<unsigned char> detsig, detsigc;147std::string strMsg = "Very deterministic message";148uint256 hashMsg = Hash(strMsg);149BOOST_CHECK(key1.Sign(hashMsg, detsig));150BOOST_CHECK(key1C.Sign(hashMsg, detsigc));151BOOST_CHECK(detsig == detsigc);152BOOST_CHECK_EQUAL(HexStr(detsig), "304402205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d022014ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6");154BOOST_CHECK(key2.Sign(hashMsg, detsig));155BOOST_CHECK(key2C.Sign(hashMsg, detsigc));156BOOST_CHECK(detsig == detsigc);157BOOST_CHECK_EQUAL(HexStr(detsig), "3044022052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd5022061d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d");159BOOST_CHECK(key1.SignCompact(hashMsg, detsig));160BOOST_CHECK(key1C.SignCompact(hashMsg, detsigc));161BOOST_CHECK_EQUAL(HexStr(detsig), "1c5dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6");162BOOST_CHECK_EQUAL(HexStr(detsigc), "205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6");164BOOST_CHECK(key2.SignCompact(hashMsg, detsig));165BOOST_CHECK(key2C.SignCompact(hashMsg, detsigc));166BOOST_CHECK_EQUAL(HexStr(detsig), "1c52d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d");167BOOST_CHECK_EQUAL(HexStr(detsigc), "2052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d");168}170BOOST_AUTO_TEST_CASE(key_signature_tests)171{172// When entropy is specified, we should see at least one high R signature within 20 signatures173CKey key = DecodeSecret(strSecret1);174std::string msg = "A message to be signed";175uint256 msg_hash = Hash(msg);176std::vector<unsigned char> sig;177bool found = false;179for (int i = 1; i <=20; ++i) {180sig.clear();181BOOST_CHECK(key.Sign(msg_hash, sig, false, i));182found = sig[3] == 0x21 && sig[4] == 0x00;183if (found) {184break;185}186}187BOOST_CHECK(found);189// When entropy is not specified, we should always see low R signatures that are less than or equal to 70 bytes in 256 tries190// The low R signatures should always have the value of their "length of R" byte less than or equal to 32191// We should see at least one signature that is less than 70 bytes.192bool found_small = false;193bool found_big = false;194bool bad_sign = false;195for (int i = 0; i < 256; ++i) {196sig.clear();197std::string msg = "A message to be signed" + ToString(i);198msg_hash = Hash(msg);199if (!key.Sign(msg_hash, sig)) {200bad_sign = true;201break;202}203// sig.size() > 70 implies sig[3] > 32, because S is always low.204// But check both conditions anyway, just in case this implication is broken for some reason205if (sig[3] > 32 || sig.size() > 70) {206found_big = true;207break;208}209found_small |= sig.size() < 70;210}211BOOST_CHECK(!bad_sign);212BOOST_CHECK(!found_big);213BOOST_CHECK(found_small);214}216static CPubKey UnserializePubkey(const std::vector<uint8_t>& data)217{218DataStream stream{};219stream << data;220CPubKey pubkey;221stream >> pubkey;222return pubkey;223}225static unsigned int GetLen(unsigned char chHeader)226{227if (chHeader == 2 || chHeader == 3)228return CPubKey::COMPRESSED_SIZE;229if (chHeader == 4 || chHeader == 6 || chHeader == 7)230return CPubKey::SIZE;231return 0;232}234static void CmpSerializationPubkey(const CPubKey& pubkey)235{236DataStream stream{};237stream << pubkey;238CPubKey pubkey2;239stream >> pubkey2;240BOOST_CHECK(pubkey == pubkey2);241}243BOOST_AUTO_TEST_CASE(pubkey_unserialize)244{245for (uint8_t i = 2; i <= 7; ++i) {246CPubKey key = UnserializePubkey({0x02});247BOOST_CHECK(!key.IsValid());248CmpSerializationPubkey(key);249key = UnserializePubkey(std::vector<uint8_t>(GetLen(i), i));250CmpSerializationPubkey(key);
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.