Chapter 01 · the instrument
Paste a Primus zkTLS attestation. This page recomputes the digest byte for byte, the way
PrimusZKTLS.sol and the JS SDK do, recovers the signer from the raw hash, and lays the
packed bytes out as a tape. Everything on the tape is protected by the signature. Everything
beside it can be rewritten by whoever hands you the JSON. Nothing leaves your browser.
Seven fields, concatenated with no padding and no separators, then hashed once with keccak256. Segment widths are drawn to real byte length. Click a segment to read the bytes that went in.
attestors and signatures are fields of the attestation struct, but they are not
inputs to encodeAttestation. The on-chain verifier does not care: it ignores the
claimed attestor list and checks the recovered address against its own registry. An off-chain
verifier that reads attestation.attestors[0].attestorAddr and treats it as the
signer is reading an unsigned field.
A valid signature answers one question: did the attestor sign this exact tape. The remaining questions are the integrator's, and the base contract does not answer them for you.
Change anything with a solid tick and the digest moves, so the signature stops recovering to the attestor. Change anything with a dashed tick and the digest does not move at all.
The full attestation object from startAttestation, or the JSON you post to your
backend. It is parsed in the page and never sent anywhere. No attestation handy? Generate one in
the Primus
zkTLS Playground and paste it here. The playground labels its runs a simulation, but the
attestations come back signed by the production attestor, so they verify here exactly like any
other.
encodeRequest hashes url, header, method and body. encodeResponse
hashes every keyName, parseType and parsePath in order. Those two hashes are packed together
with recipient, data, attConditions, timestamp and additionParams, and the whole thing is
hashed once more.
The attestor signs that digest directly, with no \x19Ethereum Signed Message
prefix, so recovery runs on the raw 32 bytes. A 65-byte signature with v of 27 or 28 recovers
exactly one address, and the verifier accepts it only if that address sits in the contract's
attestor registry.
Recipient binding, endpoint pinning, response-path pinning, freshness and replay are all integration concerns. Each one is a line of code you either wrote or did not. This page shows you which.
Everything below can be settled with the bench above. If one of them surprises you, go back and press the button.
Chapter 02 takes the same attestation and asks a narrower question: of everything inside that TLS session, what actually left it, and in what form.
All ten chapters