Skip to content

Commit

Permalink
refactor: move SignSchnorr logic to KeyPair
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
josibake committed Jul 20, 2024
1 parent 9edb74f commit c71c75c
Showing 1 changed file with 18 additions and 11 deletions.
29 changes: 18 additions & 11 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,19 +271,11 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)

bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> 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<const secp256k1_keypair*>(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<const secp256k1_keypair*>(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;
}

Expand Down Expand Up @@ -435,6 +427,21 @@ KeyPair::KeyPair(const CKey& key, const uint256* merkle_root)
if (!ret) ClearKeyPairData();
}

bool KeyPair::SignSchnorr(const uint256& hash, Span<unsigned char> 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<const secp256k1_keypair*>(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<const secp256k1_keypair*>(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();
Expand Down

0 comments on commit c71c75c

Please sign in to comment.