Skip to content

feat(tsp-js)!: TSP 1.0 (YTSP-BAA) — refuse the Rev 2 and Rev 3 drafts, require the sender VID - #374

Merged
stormer78 merged 1 commit into
mainfrom
feat/tsp-js-1.0
Oct 22, 2026
Merged

stormer78 merged 1 commit into
mainfrom
feat/tsp-js-1.0

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

Moves @openvtc/vti-tsp-js to the released TSP 1.0 specification (tswg-tsp-specification#86, ccda6b3), in step with affinidi-tsp 0.3.0 (affinidi/affinidi-tdk-rs#967, published) and the reference tsp_sdk 0.16.0.

The change

  • Packs YTSP-BAA (1.0), was YTSP-AAC (Rev 3). unpack, decodeEnvelope and peekRevision refuse every MAJOR but 1 as E_TSP_REVISION, naming the version found — Rev 3 (AAC), its pre-merge draft (ABA) and Rev 2 (AAB) included, all of which this package used to read.
  • The sender VID is required in every confidential payload (spec §3.2, §3.7 step 7). Rev 3 allowed the NULL VID under HPKE-Base; a NULL sender field is now refused. Packing is unchanged — we always wrote the VID.
  • The Rev 2 reader is deleted (the "one rm" CLAUDE.md anticipated), with its dispatcher arm, UnpackKeys.senderEncryptionKey, the revision field/type and the Rev 2 cesr constants. src/rev3/ → src/v1/. KNOWN_MINORS → KNOWN_VERSIONS; describeVersion added. CLAUDE.md's "TSP Rev 2 exception" paragraph now says the exception is gone and why.
  • core takes ^0.4.0 and stops passing the Rev 2-only sender X25519 key.

Not backwards compatible on the wire. The wallet and any VTA it talks TSP to must both be on 1.0 — VTA on affinidi-tsp 0.3 / affinidi-messaging-sdk 0.39. A VTA on 0.2.x is refused by name (E_TSP_REVISION), and refuses ours.

Evidence

  • Appendix A 1.0 vectors (tests/fixtures/spec-v1-vectors.json, identical to affinidi-tsp 0.3.0's, checked against the spec text and tsp_sdk 0.16.0's JSON): all HPKE-Base vectors open; the six we can pack re-pack byte for byte; new control-rfi-referral opened and its Signature_new verified.
  • Both directions against the published affinidi-tsp 0.3.0: a message it packed opens here with a matching thread digest (tests/interop.rust-vector.mjs), and a message packed here with the same fixed keys was opened by its direct::unpack — payload, sender, receiver, digest all match.
  • npm run lint, npm run build, npm test all green across workspaces: tsp-js 123/123, core 1070 pass / 0 fail (2 pre-existing schema skips), extension 1308/1308.

Release: @openvtc/vti-tsp-js 0.3.0 → 0.4.0 (needs publishing for core's ^0.4.0 to resolve outside the workspace). @openvtc/pnm-core has an Unreleased CHANGELOG entry.

Pre-merge checklist

  • No new reqwest::Client::new() / bare fetch(); all clients have finite timeouts (R1.2) — no network code touched
  • No lock held across a network await (R1.3) — N/A
  • No local state committed before its remote effect (R2.1) — N/A, codec change
  • Every retry is bounded + backed off (R1.4) — N/A
  • Accept/poll/listen loops survive transient errors (R1.5) — N/A; a draft-version inbound frame surfaces as a typed E_TSP_REVISION like any other refused frame
  • Acks/deletes happen only after durable handoff (R1.6) — N/A
  • New/changed wire types (R3.*) — TSP wire 0.2 → 1.0 and a stricter receive rule; matches affinidi-tsp 0.3.0 (already published), verified in both directions
  • Config absence = most restrictive (R5.*) — unknown MAJOR and NULL confidential sender both refused
  • Logs/status claim only what was verified (R6.*) — refusals carry the version found
  • "Process dies on the next line" (R2.1) — no mutations
  • Deviations flagged: R3.6 — wire-breaking; the VTA side shipped in affinidi-tdk-rs#967. No compatibility fold kept, per this repo's CLAUDE.md

…, require the sender VID

Moves @openvtc/vti-tsp-js to the released TSP 1.0 specification
(trustoverip/tswg-tsp-specification ccda6b3, PR #86), in step with
affinidi-tsp 0.3.0 and tsp_sdk 0.16.0.

- Packs YTSP-BAA (1.0). unpack, decodeEnvelope and peekRevision refuse every
  MAJOR but 1 as E_TSP_REVISION, naming the version found — Rev 3 (AAC), its
  pre-merge draft (ABA) and Rev 2 (AAB) included.
- A payload whose ESSR sender field is the NULL VID is refused (spec 3.2,
  3.7 step 7). Packing unchanged: the sender VID was always written.
- The Rev 2 reader and its dispatcher arm are deleted, with
  UnpackKeys.senderEncryptionKey, the revision field and type, and the Rev 2
  cesr constants. src/rev3/ is src/v1/. KNOWN_MINORS is KNOWN_VERSIONS;
  describeVersion added.
- Appendix A vectors replaced with 1.0's (identical to affinidi-tsp 0.3.0's);
  control-rfi-referral opened and Signature_new verified. The Rust interop
  vector is now packed by affinidi-tsp 0.3.0, and a message packed here was
  opened by that crate with a matching thread digest.
- 0.3.0 -> 0.4.0.

core: takes ^0.4.0; unpack no longer passes the Rev 2-only sender X25519 key.
CLAUDE.md: the TSP Rev 2 exception is gone.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
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