diff --git a/src/musig.cpp b/src/musig.cpp index c361a7ea890..7ebb8e55258 100644 --- a/src/musig.cpp +++ b/src/musig.cpp @@ -7,7 +7,7 @@ #include -bool GetMuSig2KeyAggCache(const std::vector& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache) +static bool GetMuSig2KeyAggCache(const std::vector& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache) { // Parse the pubkeys std::vector secp_pubkeys; @@ -29,7 +29,7 @@ bool GetMuSig2KeyAggCache(const std::vector& pubkeys, secp256k1_musig_k return true; } -std::optional GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_cache& keyagg_cache) +static std::optional GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_cache& keyagg_cache) { // Get the plain aggregated pubkey secp256k1_pubkey agg_pubkey; @@ -44,13 +44,21 @@ std::optional GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_ca return CPubKey(ser_agg_pubkey, ser_agg_pubkey + ser_agg_pubkey_len); } -std::optional MuSig2AggregatePubkeys(const std::vector& pubkeys) +std::optional MuSig2AggregatePubkeys(const std::vector& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache, const std::optional& expected_aggregate) { - secp256k1_musig_keyagg_cache keyagg_cache; if (!GetMuSig2KeyAggCache(pubkeys, keyagg_cache)) { return std::nullopt; } - return GetCPubKeyFromMuSig2KeyAggCache(keyagg_cache); + std::optional agg_key = GetCPubKeyFromMuSig2KeyAggCache(keyagg_cache); + if (!agg_key.has_value()) return std::nullopt; + if (expected_aggregate.has_value() && expected_aggregate != agg_key) return std::nullopt; + return agg_key; +} + +std::optional MuSig2AggregatePubkeys(const std::vector& pubkeys) +{ + secp256k1_musig_keyagg_cache keyagg_cache; + return MuSig2AggregatePubkeys(pubkeys, keyagg_cache, std::nullopt); } CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey& pubkey) diff --git a/src/musig.h b/src/musig.h index 40da1f10b97..bb469df4a9a 100644 --- a/src/musig.h +++ b/src/musig.h @@ -18,11 +18,10 @@ struct secp256k1_musig_secnonce; using namespace util::hex_literals; constexpr uint256 MUSIG_CHAINCODE{"868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965"_hex_u8}; -//! Create a secp256k1_musig_keyagg_cache from the pubkeys in their current order. This is necessary for most MuSig2 operations -bool GetMuSig2KeyAggCache(const std::vector& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache); -//! Retrieve the full aggregate pubkey from the secp256k1_musig_keyagg_cache -std::optional GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_cache& cache); -//! Compute the full aggregate pubkey from the given participant pubkeys in their current order +//! Compute the full aggregate pubkey from the given participant pubkeys in their current order. +//! Outputs the secp256k1_musig_keyagg_cache and validates that the computed aggregate pubkey matches an expected aggregate pubkey. +//! This is necessary for most MuSig2 operations. +std::optional MuSig2AggregatePubkeys(const std::vector& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache, const std::optional& expected_aggregate); std::optional MuSig2AggregatePubkeys(const std::vector& pubkeys); //! Construct the BIP 328 synthetic xpub for a pubkey