Check a FenceChat export
A FenceChat export is a PDF of someone’s message history. This page tells you two things about it: whether it really came from FenceChat, and whether anything has been left out. It takes a few seconds, and you do not need to know anything technical.
1. Find the check file
Every FenceChat PDF export has a check file that goes with it. The PDF is what you read. The check file is small, and its name ends in -manifest.json. The check file is what you need here.
That file holds a fingerprint of each message, and our signature. It has no message text in it.
Only got the PDF? Ask the person who gave it to you for the check file. If the export is your own, make it again: when the PDF has downloaded, use the “Download check file” link in your Archive.
2. Put that file here
What a green answer means
- The list of messages really did come from FenceChat.
- Nobody has changed it since.
- No message has been taken out, added in, or moved.
What it cannot tell you
- Whether what people said in those messages is true.
- Whether anything changed in the few minutes before a message was sealed. Messages are fingerprinted when they are sealed into the archive, usually within about five minutes of arriving and always before an export is made. The check shows nothing has changed since sealing, not since the exact moment a message arrived. The original message as received is always kept alongside the filtered version.
- Whether a court will accept the export. That is up to the court.
- Whether one printed page someone handed you belongs to this list. Someone with technical skills can check a single message against its fingerprint, using the notes at the bottom of this page.
If you were sent the text instead of the file
Sometimes people copy the contents into an email rather than sending the file. Paste them here instead.
Notes for an IT expert (you can ignore this)
Our signing key is an Ed25519 key pair. The public half is published, so an export can be
verified by anyone, offline, with ordinary tools, and still verified if FenceChat no longer
exists. The key is at https://fencechat.com/.well-known/fencechat-archive-key.json.
Opening that address in a browser shows a page of raw text rather than a designed page. That is
expected: it is a data file meant for software, not a broken page.
The key that signs exports now is fc-archive-2026-10. The SHA-256 hash of its
32-byte public key is
074b01913824a41436b68844e80b12175b85088e8c02cf0d3bf09a210a89d0c9.
A FenceChat custodian’s certificate prints the same hash, so you can confirm you have the right key.
To work it out yourself, decode public_key_base64url from the key file to its 32 bytes
and hash those bytes (not the text of the key).
Each message carries a SHA-256 content hash over a versioned, separator-delimited form of its
evidentiary fields. Chain hashes are
SHA-256(version + U+001F + previous chain hash + U+001F + content hash) -- note the
U+001F unit separator between each part; it is invisible in a terminal or editor, so a
reimplementation that quietly drops it will compute a different hash for what looks like an
identical string. The first message in an account chains from sixty-four zeros. The manifest is
signed over its canonical form: JSON with keys sorted at every level and no whitespace.
# 1. Fetch the public key curl -s https://fencechat.com/.well-known/fencechat-archive-key.json # 2. Canonicalise the manifest: keys sorted at every level, no whitespace. # Those are the exact bytes that were signed. # 3. Verify the Ed25519 signature over those bytes with the published key. # Any Ed25519 implementation will do, including openssl pkeyutl -verify.
Each message’s content hash is SHA-256 of the version (fcav3) followed by these
fields, each joined by U+001F: id, fence_address, channel, direction, received_at, from_email, from_name,
subject, filtered_subject, original_body, filtered_body, then filter_applied, threat_detected and held as
1 or 0. Text is NFC-normalised, and NUL and U+001F characters are removed from inside each field. Exports made since 21 October 2026 contain fingerprints only. Earlier export files also carried a
records list of these fields, so each hash could be recomputed from the message itself.
This page checks four things and reports a pass only if all of them hold: the signature over the canonical manifest, the recomputed chain across every entry, the chain head recorded in the manifest, and (when the file includes the messages) each message’s text against its content hash.