mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-24 10:17:45 -03:00
[fuzz] Introduce script_flags_mocked to cover segwit v{0,1} script
This commit is contained in:
parent
70ec9f2034
commit
f9bc6ba48d
1 changed files with 89 additions and 2 deletions
|
@ -3,6 +3,7 @@
|
|||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <consensus/amount.h>
|
||||
#include <crypto/siphash.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <serialize.h>
|
||||
|
@ -15,7 +16,75 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
FUZZ_TARGET(script_flags)
|
||||
namespace {
|
||||
|
||||
inline uint64_t HashSig(Span<const unsigned char> sig)
|
||||
{
|
||||
CSipHasher hasher{0xdead, 0xbeef};
|
||||
hasher.Write(sig);
|
||||
return hasher.Finalize();
|
||||
}
|
||||
// Reduce a CScriptNum to one bit
|
||||
inline bool HashScriptNum(const CScriptNum& num)
|
||||
{
|
||||
CSipHasher hasher{0xdead, 0xbeef};
|
||||
hasher.Write(num.getvch());
|
||||
return hasher.Finalize() & 1;
|
||||
}
|
||||
|
||||
class FuzzedSignatureChecker : public BaseSignatureChecker
|
||||
{
|
||||
public:
|
||||
FuzzedSignatureChecker(const CTransaction* tx, unsigned int in,
|
||||
const CAmount& amount, const PrecomputedTransactionData& tx_data,
|
||||
MissingDataBehavior mdb) {}
|
||||
|
||||
bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& pub_key,
|
||||
const CScript& script_code, SigVersion sig_version) const override
|
||||
{
|
||||
return !sig.empty() && (HashSig(sig) & 1);
|
||||
}
|
||||
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pub_key,
|
||||
SigVersion sig_version, ScriptExecutionData& exec_data,
|
||||
ScriptError* script_error = nullptr) const override
|
||||
{
|
||||
uint64_t fuzz_hash{HashSig(sig)};
|
||||
bool sig_ok = fuzz_hash & 1;
|
||||
if (!sig_ok && script_error) {
|
||||
constexpr std::array<ScriptError, 3> schnorr_errs = {
|
||||
SCRIPT_ERR_SCHNORR_SIG,
|
||||
SCRIPT_ERR_SCHNORR_SIG_SIZE,
|
||||
SCRIPT_ERR_SCHNORR_SIG_HASHTYPE};
|
||||
*script_error = schnorr_errs[(fuzz_hash >> 1) % schnorr_errs.size()];
|
||||
}
|
||||
|
||||
return sig_ok;
|
||||
}
|
||||
bool CheckLockTime(const CScriptNum& lock_time) const override
|
||||
{
|
||||
return HashScriptNum(lock_time);
|
||||
}
|
||||
bool CheckSequence(const CScriptNum& sequence) const override
|
||||
{
|
||||
return HashScriptNum(sequence);
|
||||
}
|
||||
|
||||
bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const override
|
||||
{
|
||||
return !program.empty() && (program[0] & 1);
|
||||
}
|
||||
|
||||
bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const override
|
||||
{
|
||||
return !program.empty() && (program[0] & 1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SigChecker>
|
||||
void CheckScriptFlags(FuzzBufferType buffer)
|
||||
{
|
||||
if (buffer.size() > 100'000) return;
|
||||
DataStream ds{buffer};
|
||||
|
@ -45,7 +114,7 @@ FUZZ_TARGET(script_flags)
|
|||
|
||||
for (unsigned i = 0; i < tx.vin.size(); ++i) {
|
||||
const CTxOut& prevout = txdata.m_spent_outputs.at(i);
|
||||
const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL};
|
||||
const SigChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL};
|
||||
|
||||
ScriptError serror;
|
||||
const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror);
|
||||
|
@ -69,3 +138,21 @@ FUZZ_TARGET(script_flags)
|
|||
return;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
/**
|
||||
* Both of the following harnesses test that all script verification flags only
|
||||
* tighten the interpreter rules (i.e. they represent soft-forks).
|
||||
*/
|
||||
|
||||
FUZZ_TARGET(script_flags)
|
||||
{
|
||||
CheckScriptFlags<TransactionSignatureChecker>(buffer);
|
||||
}
|
||||
|
||||
// Signature validation is mocked out through FuzzedSignatureChecker
|
||||
FUZZ_TARGET(script_flags_mocked)
|
||||
{
|
||||
CheckScriptFlags<FuzzedSignatureChecker>(buffer);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue