Merge bitcoin/bitcoin#33636: wallet: Expand MuSig test coverage and follow-ups

217dbbbb5e test: Add musig failure scenarios (Fabian Jahr)
c9519c260b musig: Check session id reuse (Fabian Jahr)
e755614be5 sign: Remove duplicate sigversion check (Fabian Jahr)
0f7f0692ca musig: Move MUSIG_CHAINCODE to musig.cpp (Fabian Jahr)

Pull request description:

  This is a follow-up to #29675 and primarily adds test coverage for some of the most prominent failure cases in the last commit.

  The following commits address a few left-over nit comments that didn't make it in before merge.

ACKs for top commit:
  achow101:
    ACK 217dbbbb5e
  rkrux:
    lgtm ACK 217dbbb

Tree-SHA512: d73807bc31791ef1825c42f127c7ddfbc70b2b7cf782bc11341666e32e86b787ffc7aed64caea992909cef3a85fc6629282d8209c173aadec77f72fd0da96c45
This commit is contained in:
Ava Chow
2025-12-22 17:14:35 -08:00
5 changed files with 147 additions and 54 deletions

View File

@@ -7,6 +7,13 @@
#include <secp256k1_musig.h>
//! MuSig2 chaincode as defined by BIP 328
using namespace util::hex_literals;
constexpr uint256 MUSIG_CHAINCODE{
// Use immediate lambda to work around GCC-14 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117966
[]() consteval { return uint256{"868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965"_hex_u8}; }(),
};
static bool GetMuSig2KeyAggCache(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache)
{
// Parse the pubkeys

View File

@@ -14,15 +14,6 @@ struct secp256k1_musig_keyagg_cache;
class MuSig2SecNonceImpl;
struct secp256k1_musig_secnonce;
//! MuSig2 chaincode as defined by BIP 328
using namespace util::hex_literals;
constexpr uint256 MUSIG_CHAINCODE{
// Use immediate lambda to work around GCC-14 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117966
[]() consteval { return uint256{"868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965"_hex_u8}; }(),
};
constexpr size_t MUSIG2_PUBNONCE_SIZE{66};
//! Compute the full aggregate pubkey from the given participant pubkeys in their current order.

View File

@@ -87,8 +87,6 @@ std::optional<uint256> MutableTransactionSignatureCreator::ComputeSchnorrSignatu
bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider& provider, std::vector<unsigned char>& 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;
@@ -342,7 +340,7 @@ static bool SignMuSig2(const BaseSignatureCreator& creator, SignatureData& sigda
sigdata.musig2_partial_sigs[pub_key_leaf_hash].emplace(part_pk, partial_sig);
}
}
// If there are any partial signatures, exit early
// If there are any partial signatures, continue with next aggregate pubkey
auto partial_sigs_it = sigdata.musig2_partial_sigs.find(pub_key_leaf_hash);
if (partial_sigs_it != sigdata.musig2_partial_sigs.end() && !partial_sigs_it->second.empty()) {
continue;

View File

@@ -122,7 +122,9 @@ std::map<CPubKey, std::vector<CPubKey>> FlatSigningProvider::GetAllMuSig2Partici
void FlatSigningProvider::SetMuSig2SecNonce(const uint256& session_id, MuSig2SecNonce&& nonce) const
{
if (!Assume(musig2_secnonces)) return;
musig2_secnonces->emplace(session_id, std::move(nonce));
auto [it, inserted] = musig2_secnonces->try_emplace(session_id, std::move(nonce));
// No secnonce should exist for this session yet.
Assert(inserted);
}
std::optional<std::reference_wrapper<MuSig2SecNonce>> FlatSigningProvider::GetMuSig2SecNonce(const uint256& session_id) const