Skip to content

Commit 82ea67c

Browse files
committed
musig: Add MuSig2AggregatePubkeys variant that validates the aggregate
A common pattern that MuSig2 functions will use is to aggregate the pubkeys to get the keyagg_cache and then validate the aggregated pubkey against a provided aggregate pubkey. A variant of MuSig2AggregatePubkeys is added which does that. The functionality of GetMuSig2KeyAggCache and GetCPubKeyFromMuSig2KeyAggCache are included in MuSig2AggregatePubkeys (and used internally) so there is no expectation that callers will need these so they are made static.
1 parent d99a081 commit 82ea67c

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

src/musig.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include <secp256k1_musig.h>
99

10-
bool GetMuSig2KeyAggCache(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache)
10+
static bool GetMuSig2KeyAggCache(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache)
1111
{
1212
// Parse the pubkeys
1313
std::vector<secp256k1_pubkey> secp_pubkeys;
@@ -29,7 +29,7 @@ bool GetMuSig2KeyAggCache(const std::vector<CPubKey>& pubkeys, secp256k1_musig_k
2929
return true;
3030
}
3131

32-
std::optional<CPubKey> GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_cache& keyagg_cache)
32+
static std::optional<CPubKey> GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_cache& keyagg_cache)
3333
{
3434
// Get the plain aggregated pubkey
3535
secp256k1_pubkey agg_pubkey;
@@ -44,13 +44,21 @@ std::optional<CPubKey> GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_ca
4444
return CPubKey(ser_agg_pubkey, ser_agg_pubkey + ser_agg_pubkey_len);
4545
}
4646

47-
std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys)
47+
std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache, const std::optional<CPubKey>& expected_aggregate)
4848
{
49-
secp256k1_musig_keyagg_cache keyagg_cache;
5049
if (!GetMuSig2KeyAggCache(pubkeys, keyagg_cache)) {
5150
return std::nullopt;
5251
}
53-
return GetCPubKeyFromMuSig2KeyAggCache(keyagg_cache);
52+
std::optional<CPubKey> agg_key = GetCPubKeyFromMuSig2KeyAggCache(keyagg_cache);
53+
if (!agg_key.has_value()) return std::nullopt;
54+
if (expected_aggregate.has_value() && expected_aggregate != agg_key) return std::nullopt;
55+
return agg_key;
56+
}
57+
58+
std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys)
59+
{
60+
secp256k1_musig_keyagg_cache keyagg_cache;
61+
return MuSig2AggregatePubkeys(pubkeys, keyagg_cache, std::nullopt);
5462
}
5563

5664
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey& pubkey)

src/musig.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ struct secp256k1_musig_secnonce;
1818
using namespace util::hex_literals;
1919
constexpr uint256 MUSIG_CHAINCODE{"868087ca02a6f974c4598924c36b57762d32cb45717167e300622c7167e38965"_hex_u8};
2020

21-
//! Create a secp256k1_musig_keyagg_cache from the pubkeys in their current order. This is necessary for most MuSig2 operations
22-
bool GetMuSig2KeyAggCache(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache);
23-
//! Retrieve the full aggregate pubkey from the secp256k1_musig_keyagg_cache
24-
std::optional<CPubKey> GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_cache& cache);
25-
//! Compute the full aggregate pubkey from the given participant pubkeys in their current order
21+
//! Compute the full aggregate pubkey from the given participant pubkeys in their current order.
22+
//! Outputs the secp256k1_musig_keyagg_cache and validates that the computed aggregate pubkey matches an expected aggregate pubkey.
23+
//! This is necessary for most MuSig2 operations.
24+
std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache, const std::optional<CPubKey>& expected_aggregate);
2625
std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys);
2726

2827
//! Construct the BIP 328 synthetic xpub for a pubkey

0 commit comments

Comments
 (0)