How verification works
Verifying a capsule is two independent checks. The signature proves who sealed it. The receipt proves the log included it. Neither check requires trusting the operator — both run from the bytes, offline.
Check 1 — the signature
The capsule is a COSE_Sign1 structure. Given the issuer's public key, the verifier confirms the signature covers the protected header and payload. If any field changed after signing, the check fails. This establishes who made the statement and that it is intact.
Check 2 — the inclusion proof
The transparency service returns a receipt: a signed proof that the statement's leaf digest sits in the log's 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 ↗