Skip to content

test(p2bk): pin the NUT-28 example proofs and V4 token vector - #786

Merged
robwoodgate merged 1 commit into
cashubtc:mainfrom
robwoodgate:test/nut28-vector-pins
Jul 16, 2026
Merged

test(p2bk): pin the NUT-28 example proofs and V4 token vector#786
robwoodgate merged 1 commit into
cashubtc:mainfrom
robwoodgate:test/nut28-vector-pins

Conversation

@robwoodgate

Copy link
Copy Markdown
Collaborator

Summary

Pins the NUT-28 test vectors (cashubtc/nuts#402) in three layers, so a symmetric sender/receiver drift cannot pass by self-consistency:

  • Unit (test/crypto/NUT28.test.ts): the P2PK and HTLC example proofs verbatim, through maybeDeriveP2BKPrivateKeys, signP2PKProof and spend verification. The HTLC proof pins the slot order fixed in fix(p2bk): align HTLC key slots with the [data, ...pubkeys, ...refund] order (NUT-28) #763: hashlock at slot 0 unblinded, pubkeys key at slot 1, refund key at slot 2, spendable via both pathways.
  • Token (test/utils/core.test.ts): the example V4 token decodes to the exact proofs (including dleq and p2pk_e) and re-encodes byte-for-byte, pinning the pe/d wire format against cross-wallet drift. The vector's CBOR was verified independently of this library.
  • Integration (test/integration.test.ts): new send and receive p2bk HTLC round trip (mint, HTLC blindKeys send, receive with privkey plus preimage witness). The shared expectP2BKLockedToBob helper replaces the hand-rolled ECDH check and uses deriveP2BKSecretKeys directly, which has no legacy slot 0 fallback, so a sender regression to slot 0 blinding fails the assertion even though receive would still work via the fallback.

Also drops a DLEQ reblind check that belonged to NUT-12, not P2BK.

Tests

npm run prtasks passes (195 files). Full integration suite passes against a fresh CDK 0.17.2 mint (46/46).

Pins the P2PK and HTLC example proofs from the NUT-28 test vectors
through the wallet derive/sign/verify path, and the example V4 token
through decode and byte-stable re-encode (pe and dleq wire format).

Adds an HTLC P2BK integration test (hashlock unblinded at slot 0,
lock key at slot 1, receive with preimage). The ITest slot check now
uses deriveP2BKSecretKeys, which has no legacy slot 0 fallback, in
place of hand-rolled ECDH; the derivation itself is anchored by the
fixed vectors in the unit tests.
@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.32%. Comparing base (36360a0) to head (f7f0ab9).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #786      +/-   ##
==========================================
+ Coverage   95.26%   95.32%   +0.05%     
==========================================
  Files          54       54              
  Lines        5175     5175              
  Branches     1284     1284              
==========================================
+ Hits         4930     4933       +3     
  Misses        105      105              
+ Partials      140      137       -3     
Flag Coverage Δ
integration 39.22% <ø> (+0.59%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@robwoodgate
robwoodgate merged commit ff3a5aa into cashubtc:main Jul 16, 2026
18 checks passed
@robwoodgate
robwoodgate deleted the test/nut28-vector-pins branch July 16, 2026 07:17
@github-project-automation github-project-automation Bot moved this from Backlog to Done in cashu-ts Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant