Skip to content

Commit cfa5752

Browse files
committed
Optimize CHECKSIGADD Script Validation
1 parent 807169e commit cfa5752

File tree

4 files changed

+18
-11
lines changed

4 files changed

+18
-11
lines changed

src/script/interpreter.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -1500,7 +1500,7 @@ static bool HandleMissingData(MissingDataBehavior mdb)
15001500
}
15011501

15021502
template<typename T>
1503-
bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb)
1503+
bool SignatureHashSchnorr(uint256& hash_out, ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb)
15041504
{
15051505
uint8_t ext_flag, key_version;
15061506
switch (sigversion) {
@@ -1568,9 +1568,12 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata
15681568
// Data about the output (if only one).
15691569
if (output_type == SIGHASH_SINGLE) {
15701570
if (in_pos >= tx_to.vout.size()) return false;
1571-
CHashWriter sha_single_output(SER_GETHASH, 0);
1572-
sha_single_output << tx_to.vout[in_pos];
1573-
ss << sha_single_output.GetSHA256();
1571+
if (!execdata.m_output_hash) {
1572+
CHashWriter sha_single_output(SER_GETHASH, 0);
1573+
sha_single_output << tx_to.vout[in_pos];
1574+
execdata.m_output_hash = sha_single_output.GetSHA256();
1575+
}
1576+
ss << execdata.m_output_hash.value();
15741577
}
15751578

15761579
// Additional data for BIP 342 signatures
@@ -1692,7 +1695,7 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
16921695
}
16931696

16941697
template <class T>
1695-
bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey_in, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror) const
1698+
bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey_in, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const
16961699
{
16971700
assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);
16981701
// Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this.

src/script/interpreter.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <span.h>
1212
#include <primitives/transaction.h>
1313

14+
#include <optional>
1415
#include <vector>
1516
#include <stdint.h>
1617

@@ -215,6 +216,9 @@ struct ScriptExecutionData
215216
bool m_validation_weight_left_init = false;
216217
//! How much validation weight is left (decremented for every successful non-empty signature check).
217218
int64_t m_validation_weight_left;
219+
220+
//! The hash of the corresponding output
221+
std::optional<uint256> m_output_hash;
218222
};
219223

220224
/** Signature hash sizes */
@@ -244,7 +248,7 @@ class BaseSignatureChecker
244248
return false;
245249
}
246250

247-
virtual bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const
251+
virtual bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const
248252
{
249253
return false;
250254
}
@@ -272,7 +276,7 @@ enum class MissingDataBehavior
272276
};
273277

274278
template<typename T>
275-
bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb);
279+
bool SignatureHashSchnorr(uint256& hash_out, ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb);
276280

277281
template <class T>
278282
class GenericTransactionSignatureChecker : public BaseSignatureChecker
@@ -292,7 +296,7 @@ class GenericTransactionSignatureChecker : public BaseSignatureChecker
292296
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
293297
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
294298
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
295-
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
299+
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
296300
bool CheckLockTime(const CScriptNum& nLockTime) const override;
297301
bool CheckSequence(const CScriptNum& nSequence) const override;
298302
};
@@ -313,7 +317,7 @@ class DeferringSignatureChecker : public BaseSignatureChecker
313317
return m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion);
314318
}
315319

316-
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override
320+
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override
317321
{
318322
return m_checker.CheckSchnorrSignature(sig, pubkey, sigversion, execdata, serror);
319323
}

src/script/sign.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ class DummySignatureChecker final : public BaseSignatureChecker
542542
public:
543543
DummySignatureChecker() {}
544544
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; }
545-
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror) const override { return true; }
545+
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return true; }
546546
};
547547
const DummySignatureChecker DUMMY_CHECKER;
548548

src/test/fuzz/signature_checker.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class FuzzedSignatureChecker : public BaseSignatureChecker
3434
return m_fuzzed_data_provider.ConsumeBool();
3535
}
3636

37-
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override
37+
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override
3838
{
3939
return m_fuzzed_data_provider.ConsumeBool();
4040
}

0 commit comments

Comments
 (0)