mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-01 00:19:07 +02:00
[interpreter] Move taproot commitment and witness program check to BaseSignatureChecker
This commit is contained in:
parent
eb646111cd
commit
70ec9f2034
@ -1781,6 +1781,35 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool GenericTransactionSignatureChecker<T>::CheckTaprootCommitment(
|
||||
const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const
|
||||
{
|
||||
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
|
||||
assert(program.size() >= uint256::size());
|
||||
//! The internal pubkey (x-only, so no Y coordinate parity).
|
||||
const XOnlyPubKey p{Span{control}.subspan(1, TAPROOT_CONTROL_BASE_SIZE - 1)};
|
||||
//! The output pubkey (taken from the scriptPubKey).
|
||||
const XOnlyPubKey q{program};
|
||||
// Compute the Merkle root from the leaf and the provided path.
|
||||
const uint256 merkle_root = ComputeTaprootMerkleRoot(control, tapleaf_hash);
|
||||
// Verify that the output pubkey matches the tweaked internal pubkey, after correcting for parity.
|
||||
return q.CheckTapTweak(p, merkle_root, control[0] & 1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool GenericTransactionSignatureChecker<T>::CheckWitnessScriptHash(
|
||||
Span<const unsigned char> program,
|
||||
const CScript& exec_script) const
|
||||
{
|
||||
assert(program.size() >= uint256::size());
|
||||
uint256 hash_exec_script;
|
||||
CSHA256().Write(exec_script.data(), exec_script.size()).Finalize(hash_exec_script.begin());
|
||||
return memcmp(hash_exec_script.begin(), program.data(), uint256::size()) == 0;
|
||||
}
|
||||
|
||||
// explicit instantiation
|
||||
template class GenericTransactionSignatureChecker<CTransaction>;
|
||||
template class GenericTransactionSignatureChecker<CMutableTransaction>;
|
||||
@ -1856,20 +1885,6 @@ uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint25
|
||||
return k;
|
||||
}
|
||||
|
||||
static bool VerifyTaprootCommitment(const std::vector<unsigned char>& control, const std::vector<unsigned char>& program, const uint256& tapleaf_hash)
|
||||
{
|
||||
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
|
||||
assert(program.size() >= uint256::size());
|
||||
//! The internal pubkey (x-only, so no Y coordinate parity).
|
||||
const XOnlyPubKey p{Span{control}.subspan(1, TAPROOT_CONTROL_BASE_SIZE - 1)};
|
||||
//! The output pubkey (taken from the scriptPubKey).
|
||||
const XOnlyPubKey q{program};
|
||||
// Compute the Merkle root from the leaf and the provided path.
|
||||
const uint256 merkle_root = ComputeTaprootMerkleRoot(control, tapleaf_hash);
|
||||
// Verify that the output pubkey matches the tweaked internal pubkey, after correcting for parity.
|
||||
return q.CheckTapTweak(p, merkle_root, control[0] & 1);
|
||||
}
|
||||
|
||||
static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror, bool is_p2sh)
|
||||
{
|
||||
CScript exec_script; //!< Actually executed script (last stack item in P2WSH; implied P2PKH script in P2WPKH; leaf script in P2TR)
|
||||
@ -1884,9 +1899,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
|
||||
}
|
||||
const valtype& script_bytes = SpanPopBack(stack);
|
||||
exec_script = CScript(script_bytes.begin(), script_bytes.end());
|
||||
uint256 hash_exec_script;
|
||||
CSHA256().Write(exec_script.data(), exec_script.size()).Finalize(hash_exec_script.begin());
|
||||
if (memcmp(hash_exec_script.begin(), program.data(), 32)) {
|
||||
if (!checker.CheckWitnessScriptHash(program, exec_script)) {
|
||||
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
|
||||
}
|
||||
return ExecuteWitnessScript(stack, exec_script, flags, SigVersion::WITNESS_V0, checker, execdata, serror);
|
||||
@ -1927,7 +1940,7 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
|
||||
return set_error(serror, SCRIPT_ERR_TAPROOT_WRONG_CONTROL_SIZE);
|
||||
}
|
||||
execdata.m_tapleaf_hash = ComputeTapleafHash(control[0] & TAPROOT_LEAF_MASK, script);
|
||||
if (!VerifyTaprootCommitment(control, program, execdata.m_tapleaf_hash)) {
|
||||
if (!checker.CheckTaprootCommitment(control, program, execdata.m_tapleaf_hash)) {
|
||||
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
|
||||
}
|
||||
execdata.m_tapleaf_hash_init = true;
|
||||
|
@ -265,6 +265,18 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual ~BaseSignatureChecker() = default;
|
||||
};
|
||||
|
||||
@ -301,6 +313,11 @@ public:
|
||||
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
|
||||
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
||||
bool CheckSequence(const CScriptNum& nSequence) const override;
|
||||
bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const override;
|
||||
bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const override;
|
||||
};
|
||||
|
||||
using TransactionSignatureChecker = GenericTransactionSignatureChecker<CTransaction>;
|
||||
@ -332,6 +349,18 @@ public:
|
||||
{
|
||||
return m_checker.CheckSequence(nSequence);
|
||||
}
|
||||
|
||||
bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const override
|
||||
{
|
||||
return m_checker.CheckTaprootCommitment(control, program, tapleaf_hash);
|
||||
}
|
||||
bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const override
|
||||
{
|
||||
return m_checker.CheckWitnessScriptHash(program, exec_script);
|
||||
}
|
||||
};
|
||||
|
||||
/** Compute the BIP341 tapleaf hash from leaf version & script. */
|
||||
|
@ -704,6 +704,19 @@ public:
|
||||
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return sig.size() != 0; }
|
||||
bool CheckLockTime(const CScriptNum& nLockTime) const override { return true; }
|
||||
bool CheckSequence(const CScriptNum& nSequence) const override { return true; }
|
||||
|
||||
bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -299,6 +299,18 @@ const struct CheckerContext: BaseSignatureChecker {
|
||||
}
|
||||
bool CheckLockTime(const CScriptNum& nLockTime) const override { return nLockTime.GetInt64() & 1; }
|
||||
bool CheckSequence(const CScriptNum& nSequence) const override { return nSequence.GetInt64() & 1; }
|
||||
|
||||
bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} CHECKER_CTX;
|
||||
|
||||
//! Context to check for duplicates when instancing a Node.
|
||||
|
@ -44,6 +44,18 @@ public:
|
||||
return m_fuzzed_data_provider.ConsumeBool();
|
||||
}
|
||||
|
||||
bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const override
|
||||
{
|
||||
return m_fuzzed_data_provider.ConsumeBool();
|
||||
}
|
||||
bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const override
|
||||
{
|
||||
return m_fuzzed_data_provider.ConsumeBool();
|
||||
}
|
||||
|
||||
virtual ~FuzzedSignatureChecker() = default;
|
||||
};
|
||||
} // namespace
|
||||
|
@ -289,6 +289,19 @@ public:
|
||||
// Delegate to Satisfier.
|
||||
return ctx.CheckOlder(sequence.GetInt64());
|
||||
}
|
||||
|
||||
bool CheckTaprootCommitment(const std::vector<unsigned char>& control,
|
||||
const std::vector<unsigned char>& program,
|
||||
const uint256& tapleaf_hash) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckWitnessScriptHash(Span<const unsigned char> program,
|
||||
const CScript& exec_script) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
using Fragment = miniscript::Fragment;
|
||||
|
Loading…
x
Reference in New Issue
Block a user