Skip to content

test: cross-check P2TR signing against an independent implementation - #29

Open
BitHighlander wants to merge 1 commit into
test/getaddress-taprootfrom
test/signtx-taproot
Open

test: cross-check P2TR signing against an independent implementation#29
BitHighlander wants to merge 1 commit into
test/getaddress-taprootfrom
test/signtx-taproot

Conversation

@BitHighlander

Copy link
Copy Markdown
Owner

Stacked on #28base is test/getaddress-taproot.

Spends a P2TR input on the emulator and compares the 64-byte witness byte for byte against a signature computed outside the firmware.

Why not a round trip

Verifying the device's signature with our own verifier would pass even if the device committed to the wrong transaction. So the expected value comes from a standalone Python implementation of BIP-340/341 written from the specs, keyed from BIP-86's own published xprv for m/86'/0'/0'/0/0, and self-checked against BIP-86's published internal and output keys before being trusted. BIP-340 signing is deterministic given aux_rand, so equality is meaningful rather than a smoke test.

It caught a real bug

BIP-143 hashes prevouts/sequences/outputs with double sha256 (hasher_sign is HASHER_SHA2D for Bitcoin); BIP-341 specifies single sha256. The firmware was reusing the BIP-143 accumulators, so it produced a cryptographically valid signature over a commitment nobody authorised — invisible to any self-consistent check. Fixed in the companion firmware branch.

A synthetic prev-tx fixture ships in txcache so this runs offline.

Same gating caveat as #28: TAPROOT_FIRMWARE_VERSION = "7.16.0" while CMakeLists.txt is 7.15.0, so it SKIPS until the project version bumps.

Spends a P2TR input on the emulator and compares the 64-byte witness byte
for byte against a signature computed outside the firmware.

The expected value is not a round trip through our own verifier -- that
would pass even if the device committed to the wrong transaction.  It comes
from a standalone Python implementation of BIP-340/341 written from the
specs, keyed from BIP-86's own published xprv for m/86'/0'/0'/0/0, and
self-checked against BIP-86's published internal and output keys before
being used.  BIP-340 signing is deterministic given aux_rand, so equality is
meaningful.

This caught a real bug.  BIP-143 hashes prevouts/sequences/outputs with
DOUBLE sha256 (hasher_sign is HASHER_SHA2D for Bitcoin) while BIP-341
specifies SINGLE sha256, so reusing the BIP-143 accumulators produced a
cryptographically valid signature over the wrong commitment -- exactly the
failure a self-consistent test cannot see.

Includes a synthetic prev-tx fixture in txcache so the test runs offline.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant