diff --git a/src/musig.cpp b/src/musig.cpp index 706874be2cf..4031b87d06d 100644 --- a/src/musig.cpp +++ b/src/musig.cpp @@ -119,10 +119,10 @@ bool MuSig2SecNonce::IsValid() return m_impl->IsValid(); } -uint256 MuSig2SessionID(const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256& sighash) +uint256 MuSig2SessionID(const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256& sighash, const std::vector& pubnonce) { HashWriter hasher; - hasher << script_pubkey << part_pubkey << sighash; + hasher << script_pubkey << part_pubkey << sighash << pubnonce; return hasher.GetSHA256(); } diff --git a/src/musig.h b/src/musig.h index f518ae81ba2..1b86d116701 100644 --- a/src/musig.h +++ b/src/musig.h @@ -56,7 +56,11 @@ public: bool IsValid(); }; -uint256 MuSig2SessionID(const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256& sighash); +/** + * Computes an arbitrary unique session ID to identify ongoing signing sessions. + * It is the SHA256 of the aggregate xonly key, the participant pubkey, the sighash, and the pubnonce + */ +uint256 MuSig2SessionID(const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256& sighash, const std::vector& pubnonce); std::optional> CreateMuSig2AggregateSig(const std::vector& participants, const CPubKey& aggregate_pubkey, const std::vector>& tweaks, const uint256& sighash, const std::map>& pubnonces, const std::map& partial_sigs); diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 6cbcf07e5e2..372ed03d8d9 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -123,7 +123,7 @@ std::vector MutableTransactionSignatureCreator::CreateMuSig2Nonce(const if (out.empty()) return {}; // Store the secnonce in the SigningProvider - provider.SetMuSig2SecNonce(MuSig2SessionID(script_pubkey, part_pubkey, *sighash), std::move(secnonce)); + provider.SetMuSig2SecNonce(MuSig2SessionID(script_pubkey, part_pubkey, *sighash, out), std::move(secnonce)); return out; } @@ -156,7 +156,9 @@ bool MutableTransactionSignatureCreator::CreateMuSig2PartialSig(const SigningPro if (!sighash.has_value()) return false; // Retrieve the secnonce - uint256 session_id = MuSig2SessionID(script_pubkey, part_pubkey, *sighash); + auto part_pubnonce_it = pubnonces.find(part_pubkey); + if (part_pubnonce_it == pubnonces.end()) return false; + uint256 session_id = MuSig2SessionID(script_pubkey, part_pubkey, *sighash, part_pubnonce_it->second); std::optional> secnonce = provider.GetMuSig2SecNonce(session_id); if (!secnonce || !secnonce->get().IsValid()) return false; diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 1bc5249ca81..06ee020a79c 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -299,7 +299,7 @@ private: * must be done in order to prevent nonce reuse. * * The session id is an arbitrary value set by the signer in order for the signing logic - * to find ongoing signing sessions. It is the SHA256 of aggregate xonly key, + participant pubkey + sighash. + * to find ongoing signing sessions, see MuSig2SessionID. */ mutable std::map m_musig2_secnonces;