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) 2020-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 <chainparams.h>6#include <key.h>7#include <key_io.h>8#include <outputtype.h>9#include <policy/policy.h>10#include <pubkey.h>11#include <rpc/util.h>12#include <script/keyorigin.h>13#include <script/script.h>14#include <script/sign.h>15#include <script/signingprovider.h>16#include <script/solver.h>17#include <streams.h>18#include <test/fuzz/FuzzedDataProvider.h>19#include <test/fuzz/fuzz.h>20#include <test/fuzz/util.h>21#include <test/util/random.h>22#include <util/chaintype.h>23#include <util/strencodings.h>25#include <array>26#include <cassert>27#include <cstddef>28#include <cstdint>29#include <numeric>30#include <optional>31#include <string>32#include <vector>34void initialize_key()35{36static ECC_Context ecc_context{};37SelectParams(ChainType::REGTEST);38}40FUZZ_TARGET(key, .init = initialize_key)41{42SeedRandomStateForTest(SeedRand::ZEROS);43const CKey key = [&] {44CKey k;45k.Set(buffer.begin(), buffer.end(), true);46return k;47}();48if (!key.IsValid()) {49return;50}52{53assert(key.begin() + key.size() == key.end());54assert(key.IsCompressed());55assert(key.size() == 32);56assert(DecodeSecret(EncodeSecret(key)) == key);57}59{60CKey invalid_key;61assert(!(invalid_key == key));62assert(!invalid_key.IsCompressed());63assert(!invalid_key.IsValid());64assert(invalid_key.size() == 0);65}67{68CKey uncompressed_key;69uncompressed_key.Set(buffer.begin(), buffer.end(), false);70assert(!(uncompressed_key == key));71assert(!uncompressed_key.IsCompressed());72assert(key.size() == 32);73assert(uncompressed_key.begin() + uncompressed_key.size() == uncompressed_key.end());74assert(uncompressed_key.IsValid());75}77{78CKey copied_key;79copied_key.Set(key.begin(), key.end(), key.IsCompressed());80assert(copied_key == key);81}83const uint256 random_uint256 = Hash(buffer);85{86CKey child_key;87ChainCode child_chaincode;88const bool ok = key.Derive(child_key, child_chaincode, 0, ChainCode{random_uint256});89assert(ok);90assert(child_key.IsValid());91assert(!(child_key == key));92assert(child_chaincode != random_uint256);93}95const CPubKey pubkey = key.GetPubKey();97{98assert(pubkey.size() == 33);99assert(key.VerifyPubKey(pubkey));100assert(pubkey.GetHash() != random_uint256);101assert(pubkey.begin() + pubkey.size() == pubkey.end());102assert(pubkey.data() == pubkey.begin());103assert(pubkey.IsCompressed());104assert(pubkey.IsValid());105assert(pubkey.IsFullyValid());106assert(HexToPubKey(HexStr(pubkey)) == pubkey);107}109{110DataStream data_stream{};111pubkey.Serialize(data_stream);113CPubKey pubkey_deserialized;114pubkey_deserialized.Unserialize(data_stream);115assert(pubkey_deserialized == pubkey);116}118{119const CScript tx_pubkey_script = GetScriptForRawPubKey(pubkey);120assert(!tx_pubkey_script.IsPayToScriptHash());121assert(!tx_pubkey_script.IsPayToWitnessScriptHash());122assert(!tx_pubkey_script.IsPushOnly());123assert(!tx_pubkey_script.IsUnspendable());124assert(tx_pubkey_script.HasValidOps());125assert(tx_pubkey_script.size() == 35);127const CScript tx_multisig_script = GetScriptForMultisig(1, {pubkey});128assert(!tx_multisig_script.IsPayToScriptHash());129assert(!tx_multisig_script.IsPayToWitnessScriptHash());130assert(!tx_multisig_script.IsPushOnly());131assert(!tx_multisig_script.IsUnspendable());132assert(tx_multisig_script.HasValidOps());133assert(tx_multisig_script.size() == 37);135FillableSigningProvider fillable_signing_provider;136assert(!IsSegWitOutput(fillable_signing_provider, tx_pubkey_script));137assert(!IsSegWitOutput(fillable_signing_provider, tx_multisig_script));138assert(fillable_signing_provider.GetKeys().size() == 0);139assert(!fillable_signing_provider.HaveKey(pubkey.GetID()));141const bool ok_add_key = fillable_signing_provider.AddKey(key);142assert(ok_add_key);143assert(fillable_signing_provider.HaveKey(pubkey.GetID()));145FillableSigningProvider fillable_signing_provider_pub;146assert(!fillable_signing_provider_pub.HaveKey(pubkey.GetID()));148const bool ok_add_key_pubkey = fillable_signing_provider_pub.AddKeyPubKey(key, pubkey);149assert(ok_add_key_pubkey);150assert(fillable_signing_provider_pub.HaveKey(pubkey.GetID()));152TxoutType which_type_tx_pubkey;153const bool is_standard_tx_pubkey = IsStandard(tx_pubkey_script, which_type_tx_pubkey);154assert(is_standard_tx_pubkey);155assert(which_type_tx_pubkey == TxoutType::PUBKEY);157TxoutType which_type_tx_multisig;158const bool is_standard_tx_multisig = IsStandard(tx_multisig_script, which_type_tx_multisig);159assert(is_standard_tx_multisig);160assert(which_type_tx_multisig == TxoutType::MULTISIG);162std::vector<std::vector<unsigned char>> v_solutions_ret_tx_pubkey;163const TxoutType outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);164assert(outtype_tx_pubkey == TxoutType::PUBKEY);165assert(v_solutions_ret_tx_pubkey.size() == 1);166assert(v_solutions_ret_tx_pubkey[0].size() == 33);168std::vector<std::vector<unsigned char>> v_solutions_ret_tx_multisig;169const TxoutType outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);170assert(outtype_tx_multisig == TxoutType::MULTISIG);171assert(v_solutions_ret_tx_multisig.size() == 3);172assert(v_solutions_ret_tx_multisig[0].size() == 1);173assert(v_solutions_ret_tx_multisig[1].size() == 33);174assert(v_solutions_ret_tx_multisig[2].size() == 1);176OutputType output_type{};177const CTxDestination tx_destination{PKHash{pubkey}};178assert(output_type == OutputType::LEGACY);179assert(IsValidDestination(tx_destination));180assert(PKHash{pubkey} == *std::get_if<PKHash>(&tx_destination));182const CScript script_for_destination = GetScriptForDestination(tx_destination);183assert(script_for_destination.size() == 25);185const std::string destination_address = EncodeDestination(tx_destination);186assert(DecodeDestination(destination_address) == tx_destination);188CKeyID key_id = pubkey.GetID();189assert(!key_id.IsNull());190assert(key_id == CKeyID{key_id});191assert(key_id == GetKeyForDestination(fillable_signing_provider, tx_destination));193CPubKey pubkey_out;194const bool ok_get_pubkey = fillable_signing_provider.GetPubKey(key_id, pubkey_out);195assert(ok_get_pubkey);197CKey key_out;198const bool ok_get_key = fillable_signing_provider.GetKey(key_id, key_out);199assert(ok_get_key);200assert(fillable_signing_provider.GetKeys().size() == 1);201assert(fillable_signing_provider.HaveKey(key_id));203KeyOriginInfo key_origin_info;204const bool ok_get_key_origin = fillable_signing_provider.GetKeyOrigin(key_id, key_origin_info);205assert(!ok_get_key_origin);206}208{209const std::vector<unsigned char> vch_pubkey{pubkey.begin(), pubkey.end()};210assert(CPubKey::ValidSize(vch_pubkey));211assert(!CPubKey::ValidSize({pubkey.begin(), pubkey.begin() + pubkey.size() - 1}));213const CPubKey pubkey_ctor_1{vch_pubkey};214assert(pubkey == pubkey_ctor_1);216const CPubKey pubkey_ctor_2{vch_pubkey.begin(), vch_pubkey.end()};217assert(pubkey == pubkey_ctor_2);219CPubKey pubkey_set;220pubkey_set.Set(vch_pubkey.begin(), vch_pubkey.end());221assert(pubkey == pubkey_set);222}224{225const CPubKey invalid_pubkey{};226assert(!invalid_pubkey.IsValid());227assert(!invalid_pubkey.IsFullyValid());228assert(!(pubkey == invalid_pubkey));229assert(pubkey != invalid_pubkey);230assert(pubkey < invalid_pubkey);231}233{234// Cover CPubKey's operator[](unsigned int pos)235unsigned int sum = 0;236for (size_t i = 0; i < pubkey.size(); ++i) {237sum += pubkey[i];238}239assert(std::accumulate(pubkey.begin(), pubkey.end(), 0U) == sum);240}242{243CPubKey decompressed_pubkey = pubkey;244assert(decompressed_pubkey.IsCompressed());246const bool ok = decompressed_pubkey.Decompress();247assert(ok);248assert(!decompressed_pubkey.IsCompressed());249assert(decompressed_pubkey.size() == 65);250}
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.