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

1 participant