@ -271,27 +271,8 @@ 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 ) ;
secp256k1_keypair keypair ;
if ( ! secp256k1_keypair_create ( secp256k1_context_sign , & keypair , UCharCast ( begin ( ) ) ) ) return false ;
if ( merkle_root ) {
secp256k1_xonly_pubkey pubkey ;
if ( ! secp256k1_keypair_xonly_pub ( secp256k1_context_sign , & pubkey , nullptr , & keypair ) ) return false ;
unsigned char pubkey_bytes [ 32 ] ;
if ( ! secp256k1_xonly_pubkey_serialize ( secp256k1_context_sign , pubkey_bytes , & pubkey ) ) return false ;
uint256 tweak = XOnlyPubKey ( pubkey_bytes ) . ComputeTapTweakHash ( merkle_root - > IsNull ( ) ? nullptr : merkle_root ) ;
if ( ! secp256k1_keypair_xonly_tweak_add ( secp256k1_context_static , & keypair , tweak . data ( ) ) ) return false ;
}
bool ret = secp256k1_schnorrsig_sign32 ( secp256k1_context_sign , sig . data ( ) , hash . data ( ) , & keypair , 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 , & keypair ) ;
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 ) ) ;
return ret ;
KeyPair kp = ComputeKeyPair ( merkle_root ) ;
return kp . SignSchnorr ( hash , sig , aux ) ;
}
bool CKey : : Load ( const CPrivKey & seckey , const CPubKey & vchPubKey , bool fSkipCheck = false ) {
@ -363,9 +344,9 @@ ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, c
return output ;
}
KeyPair CKey : : ComputeKeyPair ( ) const
KeyPair CKey : : ComputeKeyPair ( const uint256 * merkle_root ) const
{
return KeyPair ( * this );
return KeyPair ( * this , merkle_root );
}
CKey GenerateRandomKey ( bool compressed ) noexcept
@ -425,16 +406,39 @@ void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
if ( ( nDepth = = 0 & & ( nChild ! = 0 | | ReadLE32 ( vchFingerprint ) ! = 0 ) ) | | code [ 41 ] ! = 0 ) key = CKey ( ) ;
}
KeyPair : : KeyPair ( const CKey & key )
KeyPair : : KeyPair ( const CKey & key , const uint256 * merkle_root )
{
static_assert ( std : : tuple_size < KeyType > ( ) = = sizeof ( secp256k1_keypair ) ) ;
MakeKeyPairData ( ) ;
auto keypair = reinterpret_cast < secp256k1_keypair * > ( m_keypair - > data ( ) ) ;
bool success = secp256k1_keypair_create ( secp256k1_context_sign , keypair , UCharCast ( key . data ( ) ) ) ;
if ( success & & merkle_root ) {
secp256k1_xonly_pubkey pubkey ;
if ( ! secp256k1_keypair_xonly_pub ( secp256k1_context_sign , & pubkey , nullptr , keypair ) ) return ;
unsigned char pubkey_bytes [ 32 ] ;
if ( ! secp256k1_xonly_pubkey_serialize ( secp256k1_context_sign , pubkey_bytes , & pubkey ) ) return ;
uint256 tweak = XOnlyPubKey ( pubkey_bytes ) . ComputeTapTweakHash ( merkle_root - > IsNull ( ) ? nullptr : merkle_root ) ;
success = secp256k1_keypair_xonly_tweak_add ( secp256k1_context_static , keypair , tweak . data ( ) ) ;
}
if ( ! success ) ClearKeyPairData ( ) ;
}
bool KeyPair : : SignSchnorr ( const uint256 & hash , Span < unsigned char > sig , const uint256 & aux ) const
{
assert ( sig . size ( ) = = 64 ) ;
if ( ! IsValid ( ) ) return false ;
auto keypair = reinterpret_cast < const secp256k1_keypair * > ( m_keypair - > data ( ) ) ;
bool ret = secp256k1_schnorrsig_sign32 ( secp256k1_context_sign , sig . data ( ) , hash . data ( ) , keypair , 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 , keypair ) ;
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 ( ) ;