bip360: add spend-path test vectors - #2232
Open
jeanpablojp wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The existing test vectors are construction-only: script tree in; leaf
hashes, Merkle root, scriptPubKey, address and control blocks out. There
are no spending transactions or signatures, unlike BIP 341's
wallet-test-vectors.json, so everyone implementing consensus has to
invent their own spend coverage. This PR adds the spend-path vectors
offered in the Delving write-up
(https://delvingbitcoin.org/t/bip-360-p2mr-implemented-in-bitcoin-core-on-regtest-vector-results-measurements-spec-feedback/2751).
I generated them from the regtest implementation discussed there.
The schema mirrors bip-0341/wallet-test-vectors.json, adapted to an
output type whose only spend path is the script path. One transaction
with six inputs covers the valid cases, with per-input
given/intermediary/expectedand the BIP 341 sighash midstatepieces at the group level. A separate
invalidSpendingarray has nineself-contained transactions that must fail validation. The
errorfield uses short spec-level descriptions; implementations map them
onto their own error codes (several deliberately collapse onto one code
in ours). For inputs spent without a signature,
privkey/hashType/annex/sigMsg/sigHash are null rather than absent.
Valid cases:
p2mr_single_leaf_script_tree(from p2mr_construction.json) spent atdepth 0 with no signature: demonstrates the v0.12.0 anyone-can-spend
rule on a published tree
p2mr_different_version_leaves(also from p2mr_construction.json)spent through its 0xfa leaf: unknown leaf versions are unencumbered
maximum, pinning the accepting side of the depth limit
Invalid cases: bit-flipped signature, tampered Merkle path, control
byte with the low bit unset, single-element witness, two-element
witness ending in an annex, empty witness, and control blocks of 0, 34
and 1+32*129 bytes. That covers all three clauses of the control block
size rule, so the depth limit is pinned from both sides.
Everything can be regenerated from scratch: private keys are
sha256("p2mr_spending/key/<n>"), prevout txidssha256("p2mr_spending/prevout/<n>"), and signing is BIP 340 with anall-zero aux. The two reused trees are asserted to reproduce their
published construction vectors, so the two files cross-check each
other.
One case bakes in an interpretation the spec text leaves implicit:
p2mr_spend_control_byte_low_bit_zeroexpects failure when the controlbyte's low bit is 0. Script Validation says the bit "is unused and must
be 1" and the footnote describes it catching deserialization bugs "with
an immediate error", but the validation steps have no explicit "Fail
if" clause for it, unlike every other rule in that section. If the
intended reading is non-enforcement, this vector should be dropped and
the footnote reworded; either way the text could make it explicit.
Verified against a Bitcoin Core implementation of the BIP: every valid
input passes VerifyScript and every invalid case fails with the
expected script error
(https://github.com/jeanpablojp/bitcoin/tree/p2mr-regtest,
src/test/p2mr_vector_tests.cpp). The generator is
test/functional/tool_p2mr_spend_vectors.py on the same branch.