/Users/eugenesiegel/btc/bitcoin/src/musig.cpp
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2024-present The Bitcoin Core developers | 
| 2 |  | // Distributed under the MIT software license, see the accompanying | 
| 3 |  | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | 
| 4 |  |  | 
| 5 |  | #include <musig.h> | 
| 6 |  |  | 
| 7 |  | #include <secp256k1_musig.h> | 
| 8 |  |  | 
| 9 |  | bool GetMuSig2KeyAggCache(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache) | 
| 10 | 0 | { | 
| 11 |  |     // Parse the pubkeys | 
| 12 | 0 |     std::vector<secp256k1_pubkey> secp_pubkeys; | 
| 13 | 0 |     std::vector<const secp256k1_pubkey*> pubkey_ptrs; | 
| 14 | 0 |     for (const CPubKey& pubkey : pubkeys) { | 
| 15 | 0 |         if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &secp_pubkeys.emplace_back(), pubkey.data(), pubkey.size())) { | 
| 16 | 0 |             return false; | 
| 17 | 0 |         } | 
| 18 | 0 |     } | 
| 19 | 0 |     pubkey_ptrs.reserve(secp_pubkeys.size()); | 
| 20 | 0 |     for (const secp256k1_pubkey& p : secp_pubkeys) { | 
| 21 | 0 |         pubkey_ptrs.push_back(&p); | 
| 22 | 0 |     } | 
| 23 |  |  | 
| 24 |  |     // Aggregate the pubkey | 
| 25 | 0 |     if (!secp256k1_musig_pubkey_agg(secp256k1_context_static, nullptr, &keyagg_cache, pubkey_ptrs.data(), pubkey_ptrs.size())) { | 
| 26 | 0 |         return false; | 
| 27 | 0 |     } | 
| 28 | 0 |     return true; | 
| 29 | 0 | } | 
| 30 |  |  | 
| 31 |  | std::optional<CPubKey> GetCPubKeyFromMuSig2KeyAggCache(secp256k1_musig_keyagg_cache& keyagg_cache) | 
| 32 | 0 | { | 
| 33 |  |     // Get the plain aggregated pubkey | 
| 34 | 0 |     secp256k1_pubkey agg_pubkey; | 
| 35 | 0 |     if (!secp256k1_musig_pubkey_get(secp256k1_context_static, &agg_pubkey, &keyagg_cache)) { | 
| 36 | 0 |         return std::nullopt; | 
| 37 | 0 |     } | 
| 38 |  |  | 
| 39 |  |     // Turn into CPubKey | 
| 40 | 0 |     unsigned char ser_agg_pubkey[CPubKey::COMPRESSED_SIZE]; | 
| 41 | 0 |     size_t ser_agg_pubkey_len = CPubKey::COMPRESSED_SIZE; | 
| 42 | 0 |     secp256k1_ec_pubkey_serialize(secp256k1_context_static, ser_agg_pubkey, &ser_agg_pubkey_len, &agg_pubkey, SECP256K1_EC_COMPRESSED); | Line | Count | Source |  | 224 | 0 | #define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) | Line | Count | Source |  | 205 | 0 | #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) | 
 | #define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) | Line | Count | Source |  | 210 | 0 | #define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) | 
 | 
 | 
| 43 | 0 |     return CPubKey(ser_agg_pubkey, ser_agg_pubkey + ser_agg_pubkey_len); | 
| 44 | 0 | } | 
| 45 |  |  | 
| 46 |  | std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys) | 
| 47 | 0 | { | 
| 48 | 0 |     secp256k1_musig_keyagg_cache keyagg_cache; | 
| 49 | 0 |     if (!GetMuSig2KeyAggCache(pubkeys, keyagg_cache)) { | 
| 50 | 0 |         return std::nullopt; | 
| 51 | 0 |     } | 
| 52 | 0 |     return GetCPubKeyFromMuSig2KeyAggCache(keyagg_cache); | 
| 53 | 0 | } |