1 // Copyright (c) 2024-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
4 5 #ifndef BITCOIN_MUSIG_H
6 #define BITCOIN_MUSIG_H
7 8 #include <pubkey.h>
9 10 #include <optional>
11 #include <vector>
12 13 class CKey;
14 struct secp256k1_musig_keyagg_cache;
15 class MuSig2SecNonceImpl;
16 struct secp256k1_musig_secnonce;
17 18 constexpr size_t MUSIG2_PUBNONCE_SIZE{66};
19 20 //! Compute the full aggregate pubkey from the given participant pubkeys in their current order.
21 //! Outputs the secp256k1_musig_keyagg_cache and validates that the computed aggregate pubkey matches an expected aggregate pubkey.
22 //! This is necessary for most MuSig2 operations.
23 std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys, secp256k1_musig_keyagg_cache& keyagg_cache, const std::optional<CPubKey>& expected_aggregate);
24 std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkeys);
25 26 //! Construct the BIP 328 synthetic xpub for a pubkey
27 CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey& pubkey);
28 29 /**
30 * MuSig2SecNonce encapsulates a secret nonce in use in a MuSig2 signing session.
31 * Since this nonce persists outside of libsecp256k1 signing code, we must handle
32 * its construction and destruction ourselves.
33 * The secret nonce must be kept a secret, otherwise the private key may be leaked.
34 * As such, it needs to be treated in the same way that CKeys are treated.
35 * So this class handles the secure allocation of the secp256k1_musig_secnonce object
36 * that libsecp256k1 uses, and only gives out references to this object to avoid
37 * any possibility of copies being made. Furthermore, objects of this class are not
38 * copyable to avoid nonce reuse.
39 */
40 class MuSig2SecNonce
41 {
42 private:
43 std::unique_ptr<MuSig2SecNonceImpl> m_impl;
44 45 public:
46 MuSig2SecNonce();
47 MuSig2SecNonce(MuSig2SecNonce&&) noexcept;
48 MuSig2SecNonce& operator=(MuSig2SecNonce&&) noexcept;
49 ~MuSig2SecNonce();
50 51 // Delete copy constructors
52 MuSig2SecNonce(const MuSig2SecNonce&) = delete;
53 MuSig2SecNonce& operator=(const MuSig2SecNonce&) = delete;
54 55 secp256k1_musig_secnonce* Get() const;
56 void Invalidate();
57 bool IsValid();
58 };
59 60 /**
61 * Computes an arbitrary unique session ID to identify ongoing signing sessions.
62 * It is the SHA256 of the signing (aggregate) pubkey, the participant pubkey, the sighash, and the pubnonce
63 */
64 uint256 MuSig2SessionID(const CPubKey& script_pubkey, const CPubKey& part_pubkey, const uint256& sighash, const std::vector<uint8_t>& pubnonce);
65 66 std::vector<uint8_t> CreateMuSig2Nonce(MuSig2SecNonce& secnonce, const uint256& sighash, const CKey& our_seckey, const CPubKey& aggregate_pubkey, const std::vector<CPubKey>& pubkeys);
67 std::optional<uint256> CreateMuSig2PartialSig(const uint256& hash, const CKey& our_seckey, const CPubKey& aggregate_pubkey, const std::vector<CPubKey>& pubkeys, const std::map<CPubKey, std::vector<uint8_t>>& pubnonces, MuSig2SecNonce& secnonce, const std::vector<std::pair<uint256, bool>>& tweaks);
68 std::optional<std::vector<uint8_t>> CreateMuSig2AggregateSig(const std::vector<CPubKey>& participants, const CPubKey& aggregate_pubkey, const std::vector<std::pair<uint256, bool>>& tweaks, const uint256& sighash, const std::map<CPubKey, std::vector<uint8_t>>& pubnonces, const std::map<CPubKey, uint256>& partial_sigs);
69 70 #endif // BITCOIN_MUSIG_H
71