Evidence
Checking an evidence package
An evidence package from Perlata is a zip with a fixed layout. You can check it with tools that are on almost every machine, without us in the room. This page describes what is in it, what you can check and what each check establishes. The authoritative description travels inside the package itself, as the file format.md; where this page differs from it, that one applies.
What the package contains
The file names are English and do not change with the language of the document, so a checking program can look for a fixed name rather than for five spellings.
- manifest.json lists every file with its size and its SHA-256.
- events.json holds the chain: each event with its sequence number, its moment, its content, the hash of the previous link, its own chain hash and a seal.
- proofs.json holds the paths from the events to the root of their hour.
- anchors/ holds, per hourly root, the timestamp as the timestamp authority issued it, as an RFC 3161 token.
- seals.json holds the public keys the seals are verified with.
- The evidence document in two forms, to read, plus the message as it was sent and the notification as it was handed to the sending service.
The four checks
They build on one another: the first shows that the files have not changed, the last that the chain already existed at a moment a third party established.
- The files against the manifest. Compute the SHA-256 of each file and compare it with the list. If one differs, the package changed after it was recorded.
- The chain. Every event carries the hash of the one before it, and the first carries a starting value that binds the chain to one delivery of one sender. A correct run of events therefore cannot be moved onto a different delivery.
- The seals. Each seal is over the raw bytes of the chain hash, with ECDSA over P-256 and SHA-256. You verify it with openssl dgst and the public key from the package.
- The timestamp. The root of the hour was submitted to a timestamp authority; you verify the token in anchors/ with openssl ts and that authority's certificate.
What a check does and does not establish
The chain and the seals establish that nothing changed after the record was made. They do not establish when the record existed, because the hashes are ours and the times sit in our own data. That is what the timestamp is for: a third party saw the root of that hour and signed for it.
The seals are ours. The package does not establish who controls the key, and says so itself. So you fetch the timestamp authority's certificate from that authority rather than from us; otherwise you are checking our chain with a link of our own.
If the anchors/ directory is absent, there is no external timestamp for that period, and the evidence document says so in as many words. The chain is then fixed relative to itself, but the moment at which it existed has not been established independently.
If you put the stored notification next to the copy that arrived at the recipient, the headers differ and so does the SHA-256. That is not a sign of later change: the sending service adds headers of its own on the way out. What can be compared is the content, and the hash in the manifest establishes that the stored file has not changed since.
What you need
Openssl and some way to read JSON, and that is all. The chain and the seals are checked with no network at all. For the timestamp you need the authority's certificate once, which you fetch from that authority yourself.
The exact command lines are in format.md inside the package, including the two flags a check fails on while nothing is wrong: the root is passed as a digest rather than as a file, and the token is read with the flag for a bare token.
Version 1.0, 17 August 2026. This page describes the format perlata.evidence-package.v1. Questions about a package you received? Write to [email protected].