Skip to content

chain: COSE-signed checkpoints and the conformance suite#423

Open
ion-alpha-dev wants to merge 5 commits into
mainfrom
provetrail-freeze-bytes
Open

chain: COSE-signed checkpoints and the conformance suite#423
ion-alpha-dev wants to merge 5 commits into
mainfrom
provetrail-freeze-bytes

Conversation

@ion-alpha-dev

@ion-alpha-dev ion-alpha-dev commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

What

Moves five commits that were made directly on local main onto a branch so they land through review. No code changes beyond what those commits already contain.

  • 0cb28a5 feat(catalog): pin token v0.1.2 and solana-signer v0.1.1
  • 518995f chain: sign checkpoints under COSE algorithm -19 and the vendor-tree media type
  • 9baa8b3 chain/conformance: run-record vectors are L2, per the tier definition
  • 2c9561c chain: harden the reference verifier and complete the conformance suite
  • e3e9aa5 chain/conformance: pin the empty-string ruling with a vector

Why

The chain and COSE work was committed straight to a local main and never pushed, so it had no branch, no CI run and no reviewer. Two other branches were then cut from that state, which meant unreviewed commits were propagating. This puts the original work behind a PR and gives the branches cut from it a reviewed base.

How to verify

  • CI covers it: build, vet, race tests, lint, govulncheck, plus the conformance vectors.
  • Locally, ./dev/check runs the same gates.
  • The conformance suite is the substantive check here: go test ./chain/... exercises the reference verifier against the pinned vectors, including the empty-string ruling added in e3e9aa5.

Notes for reviewers

…media type

RFC 9864 (Oct 2025) deprecated the polymorphic EdDSA identifier (-8) in
favour of fully-specified Ed25519 (-19), and RFC 6838 s3.1 makes unfaceted
application/provetrail-* names unobtainable outside the standards tree, so
the checkpoint protected header now carries alg -19 and
application/vnd.provetrail.checkpoint+cbor. The signature bytes are
unchanged Ed25519.

go-cose v1.3.0 predates RFC 9864 and its NewSigner/NewVerifier reject -19,
so ed25519CoseSigner/ed25519CoseVerifier carry the label themselves; Sign1
sign/verify only compare the header algorithm against the signer's, so no
fork of the library is needed.

Conformance crypto vectors regenerated in one event (go test
./chain/conformance -update); this is the single pre-freeze byte change the
Provetrail v0.1.0 gate allows.
The crypto.run.* vectors were tagged L3 while CONFORMANCE.md placed
run-record root integrity at L2, where the tier definition (Merkle-leaf
integrity over carried bytes) puts it. Retag the five run vectors L2 and
keep event_proof and consistency at L3 as the standalone transparency
proofs. Manifest-only regeneration; no vector bytes changed.
Verifier hardening, no wire-byte changes:
- decodeCheckpoint enforces payload canonicality (re-encode and compare)
  and a full SHA-256 root; checkpointPayload refuses to sign a short root.
- VerifyRun refuses an empty record with record.empty before the size
  comparison, so a signed size-0 checkpoint cannot make emptiness pass.
- VerifyEventProof names record.index_out_of_range for an index outside
  the signed size and merkle.missing_node for a path shorter than the
  tree shape requires (delivered length computed via Rehash).
- toCanonical enforces the closed actor category (enc.invalid_actor).
- Tree.Root returns the RFC 6962 empty root for an empty tree, matching
  its own documentation.

Conformance suite grows 34 -> 64 vectors: structural schema and boundary
coverage (seq gaps, ints beyond 2^53, unicode keys, bstr payloads,
full-envelope rejects) and the crypto mutant matrix (checkpoint header and
payload axes, run-container framing axes, operational proof codes).
SPEC Section 8.2 rules that required string fields are encoded even when
empty, as zero-length text strings. valid.empty_strings.01 pins the ruling.
gofumpt and gofmt disagree about alignment when a map key is a wide rune,
and the lint gate follows gofumpt. Whitespace only.
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