diff options
Diffstat (limited to 'src/script/sign.cpp')
-rw-r--r-- | src/script/sign.cpp | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/src/script/sign.cpp b/src/script/sign.cpp index d77515f16c..3b8071d9d1 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -18,16 +18,16 @@ typedef std::vector<unsigned char> valtype; -MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, int hash_type) - : txTo{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, checker{txTo, nIn, amount, MissingDataBehavior::FAIL}, +MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, int hash_type) + : m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, checker{&m_txto, nIn, amount, MissingDataBehavior::FAIL}, m_txdata(nullptr) { } -MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type) - : txTo{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, - checker{txdata ? MutableTransactionSignatureChecker{txTo, nIn, amount, *txdata, MissingDataBehavior::FAIL} : - MutableTransactionSignatureChecker{txTo, nIn, amount, MissingDataBehavior::FAIL}}, +MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type) + : m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, + checker{txdata ? MutableTransactionSignatureChecker{&m_txto, nIn, amount, *txdata, MissingDataBehavior::FAIL} : + MutableTransactionSignatureChecker{&m_txto, nIn, amount, MissingDataBehavior::FAIL}}, m_txdata(txdata) { } @@ -50,7 +50,7 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid // BASE/WITNESS_V0 signatures don't support explicit SIGHASH_DEFAULT, use SIGHASH_ALL instead. const int hashtype = nHashType == SIGHASH_DEFAULT ? SIGHASH_ALL : nHashType; - uint256 hash = SignatureHash(scriptCode, *txTo, nIn, hashtype, amount, sigversion, m_txdata); + uint256 hash = SignatureHash(scriptCode, m_txto, nIn, hashtype, amount, sigversion, m_txdata); if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)hashtype); @@ -80,7 +80,7 @@ bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider& execdata.m_tapleaf_hash = *leaf_hash; } uint256 hash; - if (!SignatureHashSchnorr(hash, execdata, *txTo, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false; + if (!SignatureHashSchnorr(hash, execdata, m_txto, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false; sig.resize(64); // Use uint256{} as aux_rnd for now. if (!key.SignSchnorr(hash, sig, merkle_root, {})) return false; @@ -150,6 +150,7 @@ static bool CreateTaprootScriptSig(const BaseSignatureCreator& creator, Signatur auto it = sigdata.taproot_script_sigs.find(lookup_key); if (it != sigdata.taproot_script_sigs.end()) { sig_out = it->second; + return true; } if (creator.CreateSchnorrSig(provider, sig_out, pubkey, &leaf_hash, nullptr, sigversion)) { sigdata.taproot_script_sigs[lookup_key] = sig_out; @@ -164,11 +165,22 @@ static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatu if (leaf_version != TAPROOT_LEAF_TAPSCRIPT) return false; SigVersion sigversion = SigVersion::TAPSCRIPT; - uint256 leaf_hash = (CHashWriter(HASHER_TAPLEAF) << uint8_t(leaf_version) << script).GetSHA256(); + uint256 leaf_hash = (HashWriter{HASHER_TAPLEAF} << uint8_t(leaf_version) << script).GetSHA256(); // <xonly pubkey> OP_CHECKSIG if (script.size() == 34 && script[33] == OP_CHECKSIG && script[0] == 0x20) { XOnlyPubKey pubkey{Span{script}.subspan(1, 32)}; + + KeyOriginInfo info; + if (provider.GetKeyOriginByXOnly(pubkey, info)) { + auto it = sigdata.taproot_misc_pubkeys.find(pubkey); + if (it == sigdata.taproot_misc_pubkeys.end()) { + sigdata.taproot_misc_pubkeys.emplace(pubkey, std::make_pair(std::set<uint256>({leaf_hash}), info)); + } else { + it->second.first.insert(leaf_hash); + } + } + std::vector<unsigned char> sig; if (CreateTaprootScriptSig(creator, sigdata, provider, sig, pubkey, leaf_hash, sigversion)) { result = Vector(std::move(sig)); @@ -205,17 +217,29 @@ static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatu static bool SignTaproot(const SigningProvider& provider, const BaseSignatureCreator& creator, const WitnessV1Taproot& output, SignatureData& sigdata, std::vector<valtype>& result) { TaprootSpendData spenddata; + TaprootBuilder builder; // Gather information about this output. if (provider.GetTaprootSpendData(output, spenddata)) { sigdata.tr_spenddata.Merge(spenddata); } + if (provider.GetTaprootBuilder(output, builder)) { + sigdata.tr_builder = builder; + } // Try key path spending. { + KeyOriginInfo info; + if (provider.GetKeyOriginByXOnly(sigdata.tr_spenddata.internal_key, info)) { + auto it = sigdata.taproot_misc_pubkeys.find(sigdata.tr_spenddata.internal_key); + if (it == sigdata.taproot_misc_pubkeys.end()) { + sigdata.taproot_misc_pubkeys.emplace(sigdata.tr_spenddata.internal_key, std::make_pair(std::set<uint256>(), info)); + } + } + std::vector<unsigned char> sig; if (sigdata.taproot_key_path_sig.size() == 0) { - if (creator.CreateSchnorrSig(provider, sig, spenddata.internal_key, nullptr, &spenddata.merkle_root, SigVersion::TAPROOT)) { + if (creator.CreateSchnorrSig(provider, sig, sigdata.tr_spenddata.internal_key, nullptr, &sigdata.tr_spenddata.merkle_root, SigVersion::TAPROOT)) { sigdata.taproot_key_path_sig = sig; } } @@ -540,7 +564,7 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C { assert(nIn < txTo.vin.size()); - MutableTransactionSignatureCreator creator(&txTo, nIn, amount, nHashType); + MutableTransactionSignatureCreator creator(txTo, nIn, amount, nHashType); SignatureData sigdata; bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata); @@ -563,7 +587,7 @@ namespace { class DummySignatureChecker final : public BaseSignatureChecker { public: - DummySignatureChecker() {} + DummySignatureChecker() = default; bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; } bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return true; } }; @@ -679,7 +703,7 @@ bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, SignatureData sigdata = DataFromTransaction(mtx, i, coin->second.out); // Only sign SIGHASH_SINGLE if there's a corresponding output: if (!fHashSingle || (i < mtx.vout.size())) { - ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata); + ProduceSignature(*keystore, MutableTransactionSignatureCreator(mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata); } UpdateInput(txin, sigdata); |