aboutsummaryrefslogtreecommitdiff
path: root/src/script/interpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/interpreter.cpp')
-rw-r--r--src/script/interpreter.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index af8fd4912e..aef6e28118 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1522,6 +1522,12 @@ bool GenericTransactionSignatureChecker<T>::VerifyECDSASignature(const std::vect
}
template <class T>
+bool GenericTransactionSignatureChecker<T>::VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const
+{
+ return pubkey.VerifySchnorr(sighash, sig);
+}
+
+template <class T>
bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vector<unsigned char>& vchSigIn, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
{
CPubKey pubkey(vchPubKey);
@@ -1544,6 +1550,30 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
}
template <class T>
+bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey_in, SigVersion sigversion, ScriptError* serror) const
+{
+ assert(sigversion == SigVersion::TAPROOT);
+ // Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this.
+ assert(pubkey_in.size() == 32);
+ if (sig.size() != 64 && sig.size() != 65) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_SIZE);
+
+ XOnlyPubKey pubkey{pubkey_in};
+
+ uint8_t hashtype = SIGHASH_DEFAULT;
+ if (sig.size() == 65) {
+ hashtype = SpanPopBack(sig);
+ if (hashtype == SIGHASH_DEFAULT) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);
+ }
+ uint256 sighash;
+ assert(this->txdata);
+ if (!SignatureHashSchnorr(sighash, *txTo, nIn, hashtype, sigversion, *this->txdata)) {
+ return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);
+ }
+ if (!VerifySchnorrSignature(sig, pubkey, sighash)) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG);
+ return true;
+}
+
+template <class T>
bool GenericTransactionSignatureChecker<T>::CheckLockTime(const CScriptNum& nLockTime) const
{
// There are two kinds of nLockTime: lock-by-blockheight