Inside Bitcoin
Opening the selected file…
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) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#include <script/sign.h>8#include <addresstype.h>9#include <coins.h>10#include <consensus/amount.h>11#include <hash.h>12#include <key.h>13#include <musig.h>14#include <policy/policy.h>15#include <prevector.h>16#include <primitives/transaction.h>17#include <script/keyorigin.h>18#include <script/miniscript.h>19#include <script/script.h>20#include <script/script_error.h>21#include <script/signingprovider.h>22#include <script/solver.h>23#include <script/verify_flags.h>24#include <serialize.h>25#include <uint256.h>26#include <util/check.h>27#include <util/translation.h>28#include <util/vector.h>30#include <algorithm>31#include <array>32#include <cstddef>33#include <functional>34#include <iterator>35#include <span>36#include <string>38typedef std::vector<unsigned char> valtype;40MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, const SignOptions& options)41: m_txto{tx}, nIn{input_idx}, m_options{options}, amount{amount}, checker{&m_txto, nIn, amount, MissingDataBehavior::FAIL},42m_txdata(nullptr)43{44}46MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, const SignOptions& options)47: m_txto{tx}, nIn{input_idx}, m_options{options}, amount{amount},48checker{txdata ? MutableTransactionSignatureChecker{&m_txto, nIn, amount, *txdata, MissingDataBehavior::FAIL} :49MutableTransactionSignatureChecker{&m_txto, nIn, amount, MissingDataBehavior::FAIL}},50m_txdata(txdata)51{52}54bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const55{56assert(sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0);58CKey key;59if (!provider.GetKey(address, key))60return false;62// Signing with uncompressed keys is disabled in witness scripts63if (sigversion == SigVersion::WITNESS_V0 && !key.IsCompressed())64return false;66// Signing without known amount does not work in witness scripts.67if (sigversion == SigVersion::WITNESS_V0 && !MoneyRange(amount)) return false;69// BASE/WITNESS_V0 signatures don't support explicit SIGHASH_DEFAULT, use SIGHASH_ALL instead.70const int hashtype = m_options.sighash_type == SIGHASH_DEFAULT ? SIGHASH_ALL : m_options.sighash_type;72uint256 hash = SignatureHash(scriptCode, m_txto, nIn, hashtype, amount, sigversion, m_txdata);73if (!key.Sign(hash, vchSig))74return false;75vchSig.push_back((unsigned char)hashtype);76return true;77}79std::optional<uint256> MutableTransactionSignatureCreator::ComputeSchnorrSignatureHash(const uint256* leaf_hash, SigVersion sigversion) const80{81assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);83// BIP341/BIP342 signing needs lots of precomputed transaction data. While some84// (non-SIGHASH_DEFAULT) sighash modes exist that can work with just some subset85// of data present, for now, only support signing when everything is provided.86if (!m_txdata || !m_txdata->m_bip341_taproot_ready || !m_txdata->m_spent_outputs_ready) return std::nullopt;88ScriptExecutionData execdata;89execdata.m_annex_init = true;90execdata.m_annex_present = false; // Only support annex-less signing for now.91if (sigversion == SigVersion::TAPSCRIPT) {92execdata.m_codeseparator_pos_init = true;93execdata.m_codeseparator_pos = 0xFFFFFFFF; // Only support non-OP_CODESEPARATOR BIP342 signing for now.94if (!leaf_hash) return std::nullopt; // BIP342 signing needs leaf hash.95execdata.m_tapleaf_hash_init = true;96execdata.m_tapleaf_hash = *leaf_hash;97}98uint256 hash;99if (!SignatureHashSchnorr(hash, execdata, m_txto, nIn, m_options.sighash_type, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return std::nullopt;100return hash;101}103bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider& provider, std::vector<unsigned char>& sig, const XOnlyPubKey& pubkey, const uint256* leaf_hash, const uint256* merkle_root, SigVersion sigversion) const104{105CKey key;106if (!provider.GetKeyByXOnly(pubkey, key)) return false;108std::optional<uint256> hash = ComputeSchnorrSignatureHash(leaf_hash, sigversion);109if (!hash.has_value()) return false;111sig.resize(64);112// Use uint256{} as aux_rnd for now.113if (!key.SignSchnorr(*hash, sig, merkle_root, {})) return false;114if (m_options.sighash_type) sig.push_back(m_options.sighash_type);115return true;116}118std::vector<uint8_t> MutableTransactionSignatureCreator::CreateMuSig2Nonce(const SigningProvider& provider, const CPubKey& aggregate_pubkey, const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256* leaf_hash, const uint256* merkle_root, SigVersion sigversion, const SignatureData& sigdata) const119{120assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);122// Retrieve the private key123CKey key;124if (!provider.GetKey(part_pubkey.GetID(), key)) return {};126// Retrieve participant pubkeys127auto it = sigdata.musig2_pubkeys.find(aggregate_pubkey);128if (it == sigdata.musig2_pubkeys.end()) return {};129const std::vector<CPubKey>& pubkeys = it->second;130if (std::find(pubkeys.begin(), pubkeys.end(), part_pubkey) == pubkeys.end()) return {};132// Compute sighash133std::optional<uint256> sighash = ComputeSchnorrSignatureHash(leaf_hash, sigversion);134if (!sighash.has_value()) return {};136MuSig2SecNonce secnonce;137std::vector<uint8_t> out = ::CreateMuSig2Nonce(secnonce, *sighash, key, aggregate_pubkey, pubkeys);138if (out.empty()) return {};140// Store the secnonce in the SigningProvider141provider.SetMuSig2SecNonce(MuSig2SessionID(script_pubkey, part_pubkey, *sighash, out), std::move(secnonce));143return out;144}146bool MutableTransactionSignatureCreator::CreateMuSig2PartialSig(const SigningProvider& provider, uint256& partial_sig, const CPubKey& aggregate_pubkey, const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256* leaf_hash, const std::vector<std::pair<uint256, bool>>& tweaks, SigVersion sigversion, const SignatureData& sigdata) const147{148assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);150// Retrieve private key151CKey key;152if (!provider.GetKey(part_pubkey.GetID(), key)) return false;154// Retrieve participant pubkeys155auto it = sigdata.musig2_pubkeys.find(aggregate_pubkey);156if (it == sigdata.musig2_pubkeys.end()) return false;157const std::vector<CPubKey>& pubkeys = it->second;158if (std::find(pubkeys.begin(), pubkeys.end(), part_pubkey) == pubkeys.end()) return {};160// Retrieve pubnonces161auto this_leaf_aggkey = std::make_pair(script_pubkey, leaf_hash ? *leaf_hash : uint256());162auto pubnonce_it = sigdata.musig2_pubnonces.find(this_leaf_aggkey);163if (pubnonce_it == sigdata.musig2_pubnonces.end()) return false;164const std::map<CPubKey, std::vector<uint8_t>>& pubnonces = pubnonce_it->second;166// Check if enough pubnonces167if (pubnonces.size() != pubkeys.size()) return false;169// Compute sighash170std::optional<uint256> sighash = ComputeSchnorrSignatureHash(leaf_hash, sigversion);171if (!sighash.has_value()) return false;173// Retrieve the secnonce174auto part_pubnonce_it = pubnonces.find(part_pubkey);175if (part_pubnonce_it == pubnonces.end()) return false;176uint256 session_id = MuSig2SessionID(script_pubkey, part_pubkey, *sighash, part_pubnonce_it->second);177std::optional<std::reference_wrapper<MuSig2SecNonce>> secnonce = provider.GetMuSig2SecNonce(session_id);178if (!secnonce || !secnonce->get().IsValid()) return false;180// Compute the sig181std::optional<uint256> sig = ::CreateMuSig2PartialSig(*sighash, key, aggregate_pubkey, pubkeys, pubnonces, *secnonce, tweaks);182if (!sig) return false;183partial_sig = std::move(*sig);185// Delete the secnonce now that we're done with it186assert(!secnonce->get().IsValid());187provider.DeleteMuSig2Session(session_id);189return true;190}192bool MutableTransactionSignatureCreator::CreateMuSig2AggregateSig(const std::vector<CPubKey>& participants, std::vector<uint8_t>& sig, const CPubKey& aggregate_pubkey, const CPubKey& script_pubkey, const uint256* leaf_hash, const std::vector<std::pair<uint256, bool>>& tweaks, SigVersion sigversion, const SignatureData& sigdata) const193{194assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);195if (!participants.size()) return false;197// Retrieve pubnonces and partial sigs198auto this_leaf_aggkey = std::make_pair(script_pubkey, leaf_hash ? *leaf_hash : uint256());199auto pubnonce_it = sigdata.musig2_pubnonces.find(this_leaf_aggkey);200if (pubnonce_it == sigdata.musig2_pubnonces.end()) return false;201const std::map<CPubKey, std::vector<uint8_t>>& pubnonces = pubnonce_it->second;202auto partial_sigs_it = sigdata.musig2_partial_sigs.find(this_leaf_aggkey);203if (partial_sigs_it == sigdata.musig2_partial_sigs.end()) return false;204const std::map<CPubKey, uint256>& partial_sigs = partial_sigs_it->second;206// Check if enough pubnonces and partial sigs207if (pubnonces.size() != participants.size()) return false;208if (partial_sigs.size() != participants.size()) return false;210// Compute sighash211std::optional<uint256> sighash = ComputeSchnorrSignatureHash(leaf_hash, sigversion);212if (!sighash.has_value()) return false;214std::optional<std::vector<uint8_t>> res = ::CreateMuSig2AggregateSig(participants, aggregate_pubkey, tweaks, *sighash, pubnonces, partial_sigs);215if (!res) return false;216sig = res.value();217if (m_options.sighash_type) sig.push_back(m_options.sighash_type);219return true;220}222static bool GetCScript(const SigningProvider& provider, const SignatureData& sigdata, const CScriptID& scriptid, CScript& script)223{224if (provider.GetCScript(scriptid, script)) {225return true;226}227// Look for scripts in SignatureData228if (CScriptID(sigdata.redeem_script) == scriptid) {229script = sigdata.redeem_script;230return true;231} else if (CScriptID(sigdata.witness_script) == scriptid) {232script = sigdata.witness_script;233return true;234}235return false;236}238static bool GetPubKey(const SigningProvider& provider, const SignatureData& sigdata, const CKeyID& address, CPubKey& pubkey)239{240// Look for pubkey in all partial sigs241const auto it = sigdata.signatures.find(address);242if (it != sigdata.signatures.end()) {243pubkey = it->second.first;244return true;245}246// Look for pubkey in pubkey lists247const auto& pk_it = sigdata.misc_pubkeys.find(address);248if (pk_it != sigdata.misc_pubkeys.end()) {249pubkey = pk_it->second.first;250return true;