diff options
Diffstat (limited to 'src/key.cpp')
-rw-r--r-- | src/key.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/key.cpp b/src/key.cpp index 5666adebb8..7bef3d529b 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -7,10 +7,13 @@ #include <crypto/common.h> #include <crypto/hmac_sha512.h> +#include <hash.h> #include <random.h> #include <secp256k1.h> +#include <secp256k1_extrakeys.h> #include <secp256k1_recovery.h> +#include <secp256k1_schnorrsig.h> static secp256k1_context* secp256k1_context_sign = nullptr; @@ -258,6 +261,24 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) return true; } +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, 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(GetVerifyContext(), &keypair, tweak.data())) return false; + } + bool ret = secp256k1_schnorrsig_sign(secp256k1_context_sign, sig.data(), hash.data(), &keypair, aux ? (unsigned char*)aux->data() : nullptr); + memory_cleanse(&keypair, sizeof(keypair)); + return ret; +} + bool CKey::Load(const CPrivKey &seckey, const CPubKey &vchPubKey, bool fSkipCheck=false) { if (!ec_seckey_import_der(secp256k1_context_sign, (unsigned char*)begin(), seckey.data(), seckey.size())) return false; |