mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-18 13:17:55 +02:00
Merge b38fb19b7e into merged_master (Bitcoin PR bitcoin/bitcoin#30051)
This commit is contained in:
commit
e29ecdc7e4
4 changed files with 183 additions and 21 deletions
61
src/key.cpp
61
src/key.cpp
|
|
@ -281,27 +281,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) {
|
||||
|
|
@ -377,6 +358,11 @@ ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, c
|
|||
return output;
|
||||
}
|
||||
|
||||
KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const
|
||||
{
|
||||
return KeyPair(*this, merkle_root);
|
||||
}
|
||||
|
||||
CKey GenerateRandomKey(bool compressed) noexcept
|
||||
{
|
||||
CKey key;
|
||||
|
|
@ -434,6 +420,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, 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;
|
||||
unsigned char pubkey_bytes[32];
|
||||
assert(secp256k1_keypair_xonly_pub(secp256k1_context_sign, &pubkey, nullptr, keypair));
|
||||
assert(secp256k1_xonly_pubkey_serialize(secp256k1_context_sign, pubkey_bytes, &pubkey));
|
||||
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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue