From c71c75cb13dbc523bb58d0f63a8a63eaaf2d6565 Mon Sep 17 00:00:00 2001 From: josibake Date: Tue, 16 Jul 2024 19:26:58 +0200 Subject: [PATCH] refactor: move SignSchnorr logic to KeyPair Move `SignSchnorr` to `KeyPair`. This makes `CKey::SignSchnorr` now compute a `KeyPair` object and then call `KeyPair::SignSchorr`. The signing logic is move-only with the exception of changing `keypair.data()` to `my_keypair->data()`, since we now have access to the private member `m_keypair`. Instead of calling memory_cleanse on the `secp256k1_keypair`, invalidate `KeyPair` by creating an empty one. --- src/key.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/key.cpp b/src/key.cpp index 1b330b907c82f..ed467488d35ba 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -271,19 +271,11 @@ bool CKey::SignCompact(const uint256 &hash, std::vector& vchSig) bool CKey::SignSchnorr(const uint256& hash, Span sig, const uint256* merkle_root, const uint256& aux) const { - assert(sig.size() == 64); - bool ret = true; KeyPair keypair = ComputeKeyPair(merkle_root); if (!keypair.IsValid()) return false; - ret &= secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), reinterpret_cast(keypair.data()), aux.data()); - if (ret) { - // Additional verification step to prevent using a potentially corrupted signature - secp256k1_xonly_pubkey pubkey_verify; - ret &= secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey_verify, nullptr, reinterpret_cast(keypair.data())); - ret &= secp256k1_schnorrsig_verify(secp256k1_context_static, sig.data(), hash.begin(), 32, &pubkey_verify); - } - if (!ret) memory_cleanse(sig.data(), sig.size()); - memory_cleanse(&keypair, sizeof(keypair)); + bool ret = keypair.SignSchnorr(hash, sig, aux); + /* Clear the keypair */ + keypair = KeyPair(); return ret; } @@ -435,6 +427,21 @@ KeyPair::KeyPair(const CKey& key, const uint256* merkle_root) if (!ret) ClearKeyPairData(); } +bool KeyPair::SignSchnorr(const uint256& hash, Span sig, const uint256& aux) const +{ + assert(sig.size() == 64); + bool ret = 1; + ret &= secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), reinterpret_cast(m_keypair->data()), aux.data()); + if (ret) { + // Additional verification step to prevent using a potentially corrupted signature + secp256k1_xonly_pubkey pubkey_verify; + ret &= secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey_verify, nullptr, reinterpret_cast(m_keypair->data())); + ret &= secp256k1_schnorrsig_verify(secp256k1_context_static, sig.data(), hash.begin(), 32, &pubkey_verify); + } + if (!ret) memory_cleanse(sig.data(), sig.size()); + return ret; +} + bool ECC_InitSanityCheck() { CKey key = GenerateRandomKey(); CPubKey pubkey = key.GetPubKey();