ledger · trust anchor · ml-dsa-44
The ledger trust anchor
PCRZERO seals its usage ledger into daily checkpoints and signs each one. Every daily seal is then anchored on-chain, externally witnessed on Solana mainnet. The document to pin is the machine-readable one:
https://pcrzero.com/ledger/anchors.json
That path is a promise. It is meant to be hard-coded, so it will not move. Fetch it, check a signature against it, and you can verify the ledger without asking us anything — including long after we are not here to ask.
The anchor
- kid
403bcd73e051e602b1b2e823f193c8d6e74aee8ed6cd37d524b8f82b7f89828c- algorithm
- ML-DSA-44 (FIPS 204)
- public key
- 1312 bytes, hex-encoded in the document
- status
- active
- effective from
- 2026-08-08T00:00:00Z
The kid is a lookup handle, not evidence: it is sha256 over the raw public key bytes, so it recomputes from the key itself. A document claiming a kid proves nothing — the proof is a signature that checks out against the key you pinned.
Checking it
In a browser, or anywhere with the Web Crypto API. The document is served with Access-Control-Allow-Origin: * so a verifier on any origin can read it:
const url = 'https://pcrzero.com/ledger/anchors.json';
const doc = await (await fetch(url)).json();
const anchor = doc.anchors.find(
(a) => (a.status ?? 'active') === 'active',
);
// the kid is a handle, not a proof — recompute it
// from the key you just fetched
const key = Uint8Array.from(
anchor.ml_dsa_public_key.match(/../g),
(h) => parseInt(h, 16),
);
const digest = await crypto.subtle.digest('SHA-256', key);
const kid = [...new Uint8Array(digest)]
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
kid === anchor.kid; // true — now verify a checkpointRe-fetch the document at least every 24 hours. It is served with Cache-Control: public, max-age=3600 and never longer, so a cached copy can never outlive a revocation by more than an hour.
The checkpoints
Every UTC day is sealed into a checkpoint: a canonical CBOR body carrying the period, the link to the seal before it, and the state root, signed with the key above. Each seal is published whole, at a path as stable as this one, and each is written into a Solana mainnet transaction whose memo is that checkpoint’s commitment.
The state below is read from the published packages themselves on every build, so a seal that is signed but not yet witnessed says so.
| seq | period (utc) | anchor |
|---|---|---|
4 | 2026-08-12 | confirmed31sbGTVL…cBbeybTA |
3 | 2026-08-11 | confirmed5LUp4Caw…ppanuqZu |
2 | 2026-08-10 | confirmed4G5GV6wJ…c9Axjkq2 |
1 | 2026-08-09 | confirmed2ijHBo33…24dGnrZp |
0 | 2026-08-08 | confirmed5CssNBti…kWTzb8KT |
An anchor is a timestamp, not a verdict. The transaction records that a commitment existed by a certain block. It does not read the ledger, re-run any work, or examine a signature, and no chain ever inspects what PCRZERO measured. What makes a checkpoint valid is the ML-DSA signature over its body — and that holds with no chain and no network at all.
What the pin promises
| rule | what it means for a verifier |
|---|---|
| An anchor is never removed | Keys are appended, newest last. A removed anchor is indistinguishable from one that never existed, which would break verification of everything it signed. |
| Status moves forward only | active → retired → revoked. An absent status means active. The set is closed: adding a value is a version event, not a patch. |
retired still verifies | Retirement ends a key’s authority to sign new periods. It never invalidates history — a checkpoint signed on day 100 must verify on day 10,000. |
revoked repudiates signatures | It impeaches a segment of a published record that does not rewrite, so it arrives as a published statement naming the affected periods — never as a quiet status change. |
| An unknown status is an error | Throw on it. Silently including trusts what you do not understand; silently dropping hides a partial set. A trust question is never guessed in either direction. |
This document is a distribution fact, not a cryptographic one. It tells you which key to check against; the proof is still the signature over the checkpoint body. A verifier that trusts this document without checking signatures has verified nothing.
Why it is not self-signed
The anchor document is not signed by the key it names. A document signed by its own subject proves only that whoever holds the key wrote it, which is the thing in question. Its authority is this origin over HTTPS — and its history, which is public and does not rewrite.
Rotation
When a key is replaced, the new anchor is published as active with the first period it will sign, and the outgoing one moves to retired with its last — in a single update. A window where both read active, or neither does, is a window where you cannot tell who was authoritative.
The checkpoint chain continues across a rotation. Rotation changes the signer, never the chain: a restarted chain is indistinguishable from an equivocation.
If something does not verify
Tell us and we will treat it as an incident, not a support ticket: security.txt carries the contact. A failing verification against this anchor is either our defect or our compromise, and both are ours to answer for.