OBSERVE. CHECK. DISCOVER.

Provenia
Audit Lab.

Two dossiers.
Which one tells the whole story?

Select two files from your computer and discover which dossier passes the audit.

Your originals stay on your device. The server receives only the SHA-256 hashes, names, and sizes needed for the challenge.

Loading public references for the lab…

01 / PREPARE YOUR INVESTIGATION

Your files, your evidence

0 of 2 files

Choose exactly two files. Each entry gets its own record, even when names or content are identical.

Any file type · up to 50 MiB per file
Names up to 120 characters · generation and rounds held in memory

ENTRY 1

No file selected

ENTRY 2

No file selected

You will have up to 15 minutes in this session.
Your originals remain local.

03 / CONSULT AS NEEDED

Help following the clues

The hint, guide, and references are available before you guess. Opening or closing these sections keeps your files and round intact.

Get a hint

A hash works like a fingerprint. Changing the bytes changes the result. A signature lets you detect changes and identify which key signed; compare that key with the public reference.

A timestamp links a hash to a certified time. It must refer to the correct hash and come from the authorized authority. It shows that a hash existed at a given time; it does not identify who created the file or when the content was created.

View the audit walkthrough

Audit A and B separately, with both originals in entry order. Every step can be performed without the Provenia verifier, and your originals are never sent over the network.

Download local audit tools and guide ↓

Extract the tools into a folder. Install Python 3.12 or later and run these commands from that folder:

# macOS / Linux
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python scripts/audit.py "Dossier-A.zip" --original "path/file-1" --original "path/file-2" --trust public
.venv/bin/python scripts/audit.py "Dossier-B.zip" --original "path/file-1" --original "path/file-2" --trust public

# Windows PowerShell
python -m venv .venv
.venv/Scripts/python -m pip install -r requirements.txt
.venv/Scripts/python scripts/audit.py "Dossier-A.zip" --original "path/file-1" --original "path/file-2" --trust public
.venv/Scripts/python scripts/audit.py "Dossier-B.zip" --original "path/file-1" --original "path/file-2" --trust public

Use the commands for your operating system. The auditor uses MuPDF, ASN.1, and cryptography; it does not import the generator or know the answer. VERIFIED passes; FAILED reports a failure; PARTIAL indicates incomplete evidence or trust and does not pass this round. An unavailable reference makes the audit inconclusive.

  1. Open the ZIP carefully

    Where: the ZIP file listing. How: use python3 -m zipfile -l "Dossier-A.zip" (macOS/Linux) or python -m zipfile -l "Dossier-A.zip" (Windows) and repeat for B. Expect: exactly Dossier.pdf and Dossier.json, at the root or in the same top-level folder. There must be no duplicate entries, encryption, absolute paths, or ... Missing artifacts or improper paths disqualify the package. The auditor checks limits before reading; do not automatically extract suspicious files.

  2. Compare both originals

    Where: records[i].title, file_name, file_size_bytes and file_hash in the JSON. How: run sha256sum "file" (Linux), shasum -a 256 "file" (macOS), or Get-FileHash -Algorithm SHA256 -LiteralPath "file" (Windows PowerShell) for each original, or use the auditor. Expect: two records, numbered by entry, with matching name, size, and hash. Compare by entry even when names match; comparing only the set of hashes is insufficient. A difference indicates substituted content, incorrect association, or an omitted file.

  3. Confirm the JSON key and signature

    Where: the signature section and the public key listing on this page. How: the auditor removes only the signature member and uses json.dumps(..., indent=4, ensure_ascii=False, sort_keys=False).encode("utf-8"). It verifies Ed25519 with the Base64 signature and calculates SHA-256 of the DER SubjectPublicKeyInfo of the PEM key. Expect: a valid signature, a calculated fingerprint matching the declared value, and published, currently valid, unrevoked PEM and key_id. An invalid signature indicates a change. An unknown key may sign correctly but has partial trust and does not pass the round.

  4. Check the PDF signature and hash

    Where: the PDF digital signature, dossier.pdf_hash and the signer reference above. How: the auditor checks CMS, the ByteRange ranges, chain, and identity against the public certificates. Also compare sha256sum "Dossier.pdf" (Linux), shasum -a 256 "Dossier.pdf" (macOS), or Get-FileHash -Algorithm SHA256 -LiteralPath "Dossier.pdf" (Windows PowerShell) with the JSON. Expect: an intact PAdES signature covering the delivery, an authorized certificate, and the DocMDP P=1 policy (no changes). SHA-256 must be calculated from the final signed PDF. A valid chain with a different signer does not authorize issuance. Keep the public PDF root only in the auditor public folder; no system installation is needed.

  5. Read the temporal evidence for each record

    Obtain the timestamp root from this page, outside the ZIPs. Check its SHA-256 fingerprint over the DER certificate with the command below (ignore colons and letter case when comparing). Do not use the PDF root for this step.

    openssl x509 -in "public/tsa-root.pem" -noout -fingerprint -sha256

    Where: external_timestamp in each record. How: the auditor decodes timestamp_response_base64 as a complete RFC 3161 response, reads TSTInfo, and verifies CMS and the chain to tsa-root.pem. Expect: SHA-256 of messageImprint matching the record hash, nonce matching the declared value, a valid signature, a certificate with critical timestamp-only EKU, and authority identity and policy matching the references below. The chain must reach the timestamp root whose fingerprint you checked; the auditor uses this PEM only locally. genTime in UTC, serial, policy, and fingerprint must match the summaries. A substituted hash binds the timestamp to other content; a mismatched summary changes the displayed date; an invalid signature or different root removes trust. Without a complete token or nonce, evidence is partial. The declared creation date is distinct from the certified time.

  6. Follow the record chain

    Where: uuid, sequence_number, based_on.record_uuid, based_on.sequence_number and created_at_utc. How: resolve each link target or consult the chain diagnostic. Expect: unique UUIDs, numbers 1 and 2, the second linked to the first, consistent chronology, no cycles or future references. A dangling link or cycle demonstrates an inconsistent chain. This is a training link and does not establish actual derivation between your files.

Note the differences before confirming your guess. The guide remains available throughout the investigation.

View public references

PUBLIC REFERENCES / OUTSIDE THE PACKAGES

Trust starts here

Check identities against this page, independently of what each ZIP declares. These references apply to both dossiers.

PDF · training chain

Authorized signer
Loading…
Signer certificate fingerprint
Loading…
Public PDF root fingerprint
Loading…

Download public PDF root ↓ · Signer certificate ↓

The training PDF root is private to the lab and is not a publicly trusted or qualified certificate authority. Use it only for PDF auditing without installing it on your system. Official Provenia issuance uses a different chain of trust.

Timestamps · RFC 3161

Loading timestamp reference…

Timestamp root SHA-256 fingerprint (DER certificate)
Loading…
Timestamp root identity
Loading…
Authorized timestamp identities
    View authorized timestamp policies
      Download authorized timestamp root ↓

      The timestamp root is used only for timestamps; it differs from the PDF root.

      04 / YOUR VERDICT

      Which dossier passes the audit?

      Generate the pair and check the evidence before choosing.

      Select the dossier that passes the checks