How verification works
Verifying a capsule is three independent checks, in order. The capsule_id shows the record is intact. The signature proves who sealed it. The receipt proves the log included it. None requires trusting the operator — all run from the bytes, offline.
Check 1 — the capsule_id
The verifier recomputes the capsule_id: the SHA-256 of the canonical capsule. A carried value is never trusted. If any field changed after sealing, the recomputed value differs and the check fails.
Check 2 — the signature
A Producer Envelope is a COSE_Sign1 whose payload is the 32-byte capsule_id. Given the producer's public key, the verifier confirms the signature covers that id. This establishes who sealed the record. A capsule can carry more than one envelope, and each is checked on its own; one with none is intact but unattributed.
capsule_id, a SHA-256 over the canonical capsule, and it does not depend on any signature. The specification makes signing optional: a producer MAY add one or more COSE_Sign1 Producer Envelopes over the capsule_id. The reference producer, capsule-emit, signs every capsule it seals, by default, with a per-ledger Ed25519 key; its only unsigned path is the separately named log() call.Check 3 — the inclusion proof
The transparency service returns a receipt: a signed proof that the statement's leaf digest sits in the log's verifiable data structure (for an RFC 9162 log, a Merkle tree) at a given size. Given the log's public key and the leaf digest, the verifier recomputes the path to the signed tree head. This establishes that the record was recorded and is discoverable — not held privately by the operator.
# verify a receipt's inclusion proof, offline
from scitt_cose import verify_receipt
r = verify_receipt(receipt, leaf_entry_hex=leaf,
log_public_key_pem=log_key)
print(r.ok) # -> True
Staying append-only over time
Beyond a single inclusion proof, a verifier can request a consistency proof between two signed tree heads to confirm the log only ever appended — it never rewrote or removed earlier entries. Inclusion answers “is my record in the log?”; consistency answers “has the log stayed honest between then and now?”
What you do not have to trust
- You do not trust the operator — every claim is checkable from the bytes.
- You do not need the raw inputs or outputs — verification uses digests.
- You do not need network access to the operator — you need the public key and the proof.
capsule-emit: Why anchoring makes it trustworthy ↗ · The public log, explained ↗