Add MuSig2SecNonce class for secure allocation of musig nonces

This commit is contained in:
Ava Chow
2024-03-25 16:13:58 -04:00
parent 9baff05e49
commit c06a1dc86f
2 changed files with 74 additions and 0 deletions

View File

@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <musig.h>
#include <support/allocators/secure.h>
#include <secp256k1_musig.h>
@@ -62,3 +63,43 @@ CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey& pubkey)
extpub.pubkey = pubkey;
return extpub;
}
class MuSig2SecNonceImpl
{
private:
//! The actual secnonce itself
secure_unique_ptr<secp256k1_musig_secnonce> m_nonce;
public:
MuSig2SecNonceImpl() : m_nonce{make_secure_unique<secp256k1_musig_secnonce>()} {}
// Delete copy constructors
MuSig2SecNonceImpl(const MuSig2SecNonceImpl&) = delete;
MuSig2SecNonceImpl& operator=(const MuSig2SecNonceImpl&) = delete;
secp256k1_musig_secnonce* Get() const { return m_nonce.get(); }
void Invalidate() { m_nonce.reset(); }
bool IsValid() { return m_nonce != nullptr; }
};
MuSig2SecNonce::MuSig2SecNonce() : m_impl{std::make_unique<MuSig2SecNonceImpl>()} {}
MuSig2SecNonce::MuSig2SecNonce(MuSig2SecNonce&&) noexcept = default;
MuSig2SecNonce& MuSig2SecNonce::operator=(MuSig2SecNonce&&) noexcept = default;
MuSig2SecNonce::~MuSig2SecNonce() = default;
secp256k1_musig_secnonce* MuSig2SecNonce::Get() const
{
return m_impl->Get();
}
void MuSig2SecNonce::Invalidate()
{
return m_impl->Invalidate();
}
bool MuSig2SecNonce::IsValid()
{
return m_impl->IsValid();
}

View File

@@ -11,6 +11,8 @@
#include <vector>
struct secp256k1_musig_keyagg_cache;
class MuSig2SecNonceImpl;
struct secp256k1_musig_secnonce;
//! MuSig2 chaincode as defined by BIP 328
using namespace util::hex_literals;
@@ -26,4 +28,35 @@ std::optional<CPubKey> MuSig2AggregatePubkeys(const std::vector<CPubKey>& pubkey
//! Construct the BIP 328 synthetic xpub for a pubkey
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey& pubkey);
/**
* MuSig2SecNonce encapsulates a secret nonce in use in a MuSig2 signing session.
* Since this nonce persists outside of libsecp256k1 signing code, we must handle
* its construction and destruction ourselves.
* The secret nonce must be kept a secret, otherwise the private key may be leaked.
* As such, it needs to be treated in the same way that CKeys are treated.
* So this class handles the secure allocation of the secp256k1_musig_secnonce object
* that libsecp256k1 uses, and only gives out references to this object to avoid
* any possibility of copies being made. Furthermore, objects of this class are not
* copyable to avoid nonce reuse.
*/
class MuSig2SecNonce
{
private:
std::unique_ptr<MuSig2SecNonceImpl> m_impl;
public:
MuSig2SecNonce();
MuSig2SecNonce(MuSig2SecNonce&&) noexcept;
MuSig2SecNonce& operator=(MuSig2SecNonce&&) noexcept;
~MuSig2SecNonce();
// Delete copy constructors
MuSig2SecNonce(const MuSig2SecNonce&) = delete;
MuSig2SecNonce& operator=(const MuSig2SecNonce&) = delete;
secp256k1_musig_secnonce* Get() const;
void Invalidate();
bool IsValid();
};
#endif // BITCOIN_MUSIG_H