@@ -271,27 +271,8 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
271
271
272
272
bool CKey::SignSchnorr (const uint256& hash, Span<unsigned char > sig, const uint256* merkle_root, const uint256& aux) const
273
273
{
274
- assert (sig.size () == 64 );
275
- secp256k1_keypair keypair;
276
- if (!secp256k1_keypair_create (secp256k1_context_sign, &keypair, UCharCast (begin ()))) return false ;
277
- if (merkle_root) {
278
- secp256k1_xonly_pubkey pubkey;
279
- if (!secp256k1_keypair_xonly_pub (secp256k1_context_sign, &pubkey, nullptr , &keypair)) return false ;
280
- unsigned char pubkey_bytes[32 ];
281
- if (!secp256k1_xonly_pubkey_serialize (secp256k1_context_sign, pubkey_bytes, &pubkey)) return false ;
282
- uint256 tweak = XOnlyPubKey (pubkey_bytes).ComputeTapTweakHash (merkle_root->IsNull () ? nullptr : merkle_root);
283
- if (!secp256k1_keypair_xonly_tweak_add (secp256k1_context_static, &keypair, tweak.data ())) return false ;
284
- }
285
- bool ret = secp256k1_schnorrsig_sign32 (secp256k1_context_sign, sig.data (), hash.data (), &keypair, aux.data ());
286
- if (ret) {
287
- // Additional verification step to prevent using a potentially corrupted signature
288
- secp256k1_xonly_pubkey pubkey_verify;
289
- ret = secp256k1_keypair_xonly_pub (secp256k1_context_static, &pubkey_verify, nullptr , &keypair);
290
- ret &= secp256k1_schnorrsig_verify (secp256k1_context_static, sig.data (), hash.begin (), 32 , &pubkey_verify);
291
- }
292
- if (!ret) memory_cleanse (sig.data (), sig.size ());
293
- memory_cleanse (&keypair, sizeof (keypair));
294
- return ret;
274
+ KeyPair kp = ComputeKeyPair (merkle_root);
275
+ return kp.SignSchnorr (hash, sig, aux);
295
276
}
296
277
297
278
bool CKey::Load (const CPrivKey &seckey, const CPubKey &vchPubKey, bool fSkipCheck =false ) {
@@ -363,9 +344,9 @@ ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, c
363
344
return output;
364
345
}
365
346
366
- KeyPair CKey::ComputeKeyPair () const
347
+ KeyPair CKey::ComputeKeyPair (const uint256* merkle_root ) const
367
348
{
368
- return KeyPair (*this );
349
+ return KeyPair (*this , merkle_root );
369
350
}
370
351
371
352
CKey GenerateRandomKey (bool compressed) noexcept
@@ -425,16 +406,39 @@ void CExtKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
425
406
if ((nDepth == 0 && (nChild != 0 || ReadLE32 (vchFingerprint) != 0 )) || code[41 ] != 0 ) key = CKey ();
426
407
}
427
408
428
- KeyPair::KeyPair (const CKey& key)
409
+ KeyPair::KeyPair (const CKey& key, const uint256* merkle_root )
429
410
{
430
411
static_assert (std::tuple_size<KeyType>() == sizeof (secp256k1_keypair));
431
412
MakeKeyPairData ();
432
413
auto keypair = reinterpret_cast <secp256k1_keypair*>(m_keypair->data ());
433
-
434
414
bool success = secp256k1_keypair_create (secp256k1_context_sign, keypair, UCharCast (key.data ()));
415
+ if (success && merkle_root) {
416
+ secp256k1_xonly_pubkey pubkey;
417
+ if (!secp256k1_keypair_xonly_pub (secp256k1_context_sign, &pubkey, nullptr , keypair)) return ;
418
+ unsigned char pubkey_bytes[32 ];
419
+ if (!secp256k1_xonly_pubkey_serialize (secp256k1_context_sign, pubkey_bytes, &pubkey)) return ;
420
+ uint256 tweak = XOnlyPubKey (pubkey_bytes).ComputeTapTweakHash (merkle_root->IsNull () ? nullptr : merkle_root);
421
+ success = secp256k1_keypair_xonly_tweak_add (secp256k1_context_static, keypair, tweak.data ());
422
+ }
435
423
if (!success) ClearKeyPairData ();
436
424
}
437
425
426
+ bool KeyPair::SignSchnorr (const uint256& hash, Span<unsigned char > sig, const uint256& aux) const
427
+ {
428
+ assert (sig.size () == 64 );
429
+ if (!IsValid ()) return false ;
430
+ auto keypair = reinterpret_cast <const secp256k1_keypair*>(m_keypair->data ());
431
+ bool ret = secp256k1_schnorrsig_sign32 (secp256k1_context_sign, sig.data (), hash.data (), keypair, aux.data ());
432
+ if (ret) {
433
+ // Additional verification step to prevent using a potentially corrupted signature
434
+ secp256k1_xonly_pubkey pubkey_verify;
435
+ ret = secp256k1_keypair_xonly_pub (secp256k1_context_static, &pubkey_verify, nullptr , keypair);
436
+ ret &= secp256k1_schnorrsig_verify (secp256k1_context_static, sig.data (), hash.begin (), 32 , &pubkey_verify);
437
+ }
438
+ if (!ret) memory_cleanse (sig.data (), sig.size ());
439
+ return ret;
440
+ }
441
+
438
442
bool ECC_InitSanityCheck () {
439
443
CKey key = GenerateRandomKey ();
440
444
CPubKey pubkey = key.GetPubKey ();
0 commit comments