mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
tests: implement BIP341 test vectors
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <test/data/script_tests.json.h>
|
||||
#include <test/data/bip341_wallet_vectors.json.h>
|
||||
|
||||
#include <core_io.h>
|
||||
#include <fs.h>
|
||||
@@ -1743,4 +1744,79 @@ BOOST_AUTO_TEST_CASE(script_assets_test)
|
||||
file.close();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bip341_keypath_test_vectors)
|
||||
{
|
||||
UniValue tests;
|
||||
tests.read((const char*)json_tests::bip341_wallet_vectors, sizeof(json_tests::bip341_wallet_vectors));
|
||||
|
||||
const auto& vectors = tests["keyPathSpending"];
|
||||
|
||||
for (const auto& vec : vectors.getValues()) {
|
||||
auto txhex = ParseHex(vec["given"]["rawUnsignedTx"].get_str());
|
||||
CMutableTransaction tx;
|
||||
VectorReader(SER_NETWORK, PROTOCOL_VERSION, txhex, 0) >> tx;
|
||||
std::vector<CTxOut> utxos;
|
||||
for (const auto& utxo_spent : vec["given"]["utxosSpent"].getValues()) {
|
||||
auto script_bytes = ParseHex(utxo_spent["scriptPubKey"].get_str());
|
||||
CScript script{script_bytes.begin(), script_bytes.end()};
|
||||
CAmount amount{utxo_spent["amountSats"].get_int()};
|
||||
utxos.emplace_back(amount, script);
|
||||
}
|
||||
|
||||
PrecomputedTransactionData txdata;
|
||||
txdata.Init(tx, std::vector<CTxOut>{utxos}, true);
|
||||
|
||||
BOOST_CHECK(txdata.m_bip341_taproot_ready);
|
||||
BOOST_CHECK_EQUAL(HexStr(txdata.m_spent_amounts_single_hash), vec["intermediary"]["hashAmounts"].get_str());
|
||||
BOOST_CHECK_EQUAL(HexStr(txdata.m_outputs_single_hash), vec["intermediary"]["hashOutputs"].get_str());
|
||||
BOOST_CHECK_EQUAL(HexStr(txdata.m_prevouts_single_hash), vec["intermediary"]["hashPrevouts"].get_str());
|
||||
BOOST_CHECK_EQUAL(HexStr(txdata.m_spent_scripts_single_hash), vec["intermediary"]["hashScriptPubkeys"].get_str());
|
||||
BOOST_CHECK_EQUAL(HexStr(txdata.m_sequences_single_hash), vec["intermediary"]["hashSequences"].get_str());
|
||||
|
||||
for (const auto& input : vec["inputSpending"].getValues()) {
|
||||
int txinpos = input["given"]["txinIndex"].get_int();
|
||||
int hashtype = input["given"]["hashType"].get_int();
|
||||
|
||||
// Load key.
|
||||
auto privkey = ParseHex(input["given"]["internalPrivkey"].get_str());
|
||||
CKey key;
|
||||
key.Set(privkey.begin(), privkey.end(), true);
|
||||
|
||||
// Load Merkle root.
|
||||
uint256 merkle_root;
|
||||
if (!input["given"]["merkleRoot"].isNull()) {
|
||||
merkle_root = uint256{ParseHex(input["given"]["merkleRoot"].get_str())};
|
||||
}
|
||||
|
||||
// Compute and verify (internal) public key.
|
||||
XOnlyPubKey pubkey{key.GetPubKey()};
|
||||
BOOST_CHECK_EQUAL(HexStr(pubkey), input["intermediary"]["internalPubkey"].get_str());
|
||||
|
||||
// Sign and verify signature.
|
||||
FlatSigningProvider provider;
|
||||
provider.keys[key.GetPubKey().GetID()] = key;
|
||||
MutableTransactionSignatureCreator creator(&tx, txinpos, utxos[txinpos].nValue, &txdata, hashtype);
|
||||
std::vector<unsigned char> signature;
|
||||
BOOST_CHECK(creator.CreateSchnorrSig(provider, signature, pubkey, nullptr, &merkle_root, SigVersion::TAPROOT));
|
||||
BOOST_CHECK_EQUAL(HexStr(signature), input["expected"]["witness"][0].get_str());
|
||||
|
||||
// We can't observe the tweak used inside the signing logic, so verify by recomputing it.
|
||||
BOOST_CHECK_EQUAL(HexStr(pubkey.ComputeTapTweakHash(merkle_root.IsNull() ? nullptr : &merkle_root)), input["intermediary"]["tweak"].get_str());
|
||||
|
||||
// We can't observe the sighash used inside the signing logic, so verify by recomputing it.
|
||||
ScriptExecutionData sed;
|
||||
sed.m_annex_init = true;
|
||||
sed.m_annex_present = false;
|
||||
uint256 sighash;
|
||||
BOOST_CHECK(SignatureHashSchnorr(sighash, sed, tx, txinpos, hashtype, SigVersion::TAPROOT, txdata, MissingDataBehavior::FAIL));
|
||||
BOOST_CHECK_EQUAL(HexStr(sighash), input["intermediary"]["sigHash"].get_str());
|
||||
|
||||
// To verify the sigmsg, hash the expected sigmsg, and compare it with the (expected) sighash.
|
||||
BOOST_CHECK_EQUAL(HexStr((CHashWriter(HASHER_TAPSIGHASH) << MakeSpan(ParseHex(input["intermediary"]["sigMsg"].get_str()))).GetSHA256()), input["intermediary"]["sigHash"].get_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
Reference in New Issue
Block a user