From fb8720f1e09f4e41802f07be53fb220d6f6c127f Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Mon, 5 Feb 2024 15:09:40 -0500 Subject: [PATCH] sign: Refactor Schnorr sighash computation out of CreateSchnorrSig There will be other functions within MutableTransactionSignatureCreator that need to compute the same sighash, so make it a separate member function. --- src/script/sign.cpp | 26 ++++++++++++++++++-------- src/script/sign.h | 2 ++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 33cbc38be41..1e40d5328fc 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -59,17 +59,14 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid return true; } -bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider& provider, std::vector& sig, const XOnlyPubKey& pubkey, const uint256* leaf_hash, const uint256* merkle_root, SigVersion sigversion) const +std::optional MutableTransactionSignatureCreator::ComputeSchnorrSignatureHash(const uint256* leaf_hash, SigVersion sigversion) const { assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT); - CKey key; - if (!provider.GetKeyByXOnly(pubkey, key)) return false; - // BIP341/BIP342 signing needs lots of precomputed transaction data. While some // (non-SIGHASH_DEFAULT) sighash modes exist that can work with just some subset // of data present, for now, only support signing when everything is provided. - if (!m_txdata || !m_txdata->m_bip341_taproot_ready || !m_txdata->m_spent_outputs_ready) return false; + if (!m_txdata || !m_txdata->m_bip341_taproot_ready || !m_txdata->m_spent_outputs_ready) return std::nullopt; ScriptExecutionData execdata; execdata.m_annex_init = true; @@ -77,15 +74,28 @@ bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider& if (sigversion == SigVersion::TAPSCRIPT) { execdata.m_codeseparator_pos_init = true; execdata.m_codeseparator_pos = 0xFFFFFFFF; // Only support non-OP_CODESEPARATOR BIP342 signing for now. - if (!leaf_hash) return false; // BIP342 signing needs leaf hash. + if (!leaf_hash) return std::nullopt; // BIP342 signing needs leaf hash. execdata.m_tapleaf_hash_init = true; execdata.m_tapleaf_hash = *leaf_hash; } uint256 hash; - if (!SignatureHashSchnorr(hash, execdata, m_txto, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false; + if (!SignatureHashSchnorr(hash, execdata, m_txto, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return std::nullopt; + return hash; +} + +bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider& provider, std::vector& sig, const XOnlyPubKey& pubkey, const uint256* leaf_hash, const uint256* merkle_root, SigVersion sigversion) const +{ + assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT); + + CKey key; + if (!provider.GetKeyByXOnly(pubkey, key)) return false; + + std::optional hash = ComputeSchnorrSignatureHash(leaf_hash, sigversion); + if (!hash.has_value()) return false; + sig.resize(64); // Use uint256{} as aux_rnd for now. - if (!key.SignSchnorr(hash, sig, merkle_root, {})) return false; + if (!key.SignSchnorr(*hash, sig, merkle_root, {})) return false; if (nHashType) sig.push_back(nHashType); return true; } diff --git a/src/script/sign.h b/src/script/sign.h index fe2c470bc64..5af6392b128 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -45,6 +45,8 @@ class MutableTransactionSignatureCreator : public BaseSignatureCreator const MutableTransactionSignatureChecker checker; const PrecomputedTransactionData* m_txdata; + std::optional ComputeSchnorrSignatureHash(const uint256* leaf_hash, SigVersion sigversion) const; + public: MutableTransactionSignatureCreator(const CMutableTransaction& tx LIFETIMEBOUND, unsigned int input_idx, const CAmount& amount, int hash_type); MutableTransactionSignatureCreator(const CMutableTransaction& tx LIFETIMEBOUND, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type);