← Back to tutorials

How to verify evidence (online or fully offline)

Two methods: verify a Proof ID in the public verifier, or verify an Evidence ZIP — online via drop-in upload, or fully offline with standard open-source tools.

Verification answers one precise question: Has this evidence been changed since it was created — and is its time anchor still cryptographically valid?

Tutorial Verification Proof ID Evidence ZIP Offline-verifiable ~6 min read
Quick overview

You can verify in two ways: by Proof ID (online) or by Evidence ZIP (online via verifier upload, or fully offline with python3 + openssl + ots). Results are deterministic: Match or Modified, with a per-layer breakdown showing what passed and what failed.

What verification means

Verification is intentionally simple and deterministic: it checks whether evidence is byte- identical to the original captured record, and whether the cryptographic time anchors are still valid. It does not judge truthfulness or who is right — it verifies integrity.

Under the hood, every GPA proof is anchored in four independent integrity layers — file hashes, an append-only hash chain, a Bitcoin OpenTimestamps anchor, and an eIDAS qualified timestamp. Verification checks them. Tampering with any of them — even reformatting JSON whitespace — fails the check.

Method 1 — Verify a Proof ID (online)

A Proof ID is a permanent identifier for a captured record. Anyone with the Proof ID (or the proof link) can verify it online via the public verifier — no account, no install, no setup.

  1. Open the verifier page.
  2. Paste the Proof ID, or open the proof link directly.
  3. Review the result — captured artifacts plus integrity status across all four layers.
What you'll see

The verifier renders the captured artifacts side-by-side with their integrity status:

  • the captured screenshot, extracted text, and source/final URL
  • capture timestamp and content fingerprints (SHA-256)
  • Bitcoin anchor status (anchored block + transaction, if confirmed)
  • eIDAS qualified-timestamp status (TSA name, time, signature validity)
Open verification

Use the public verifier to check a Proof ID, or upload an Evidence ZIP for full multi-layer verification.

Method 2 — Verify an Evidence ZIP

ZIP verification is designed for sharing and long-term archiving. It can be performed two ways: online via the verifier (drop-in upload, instant report) or fully offline using the bilingual README inside the ZIP and standard open-source tools.

Online — drop-in upload

If you have internet access and just want a quick answer, the verifier handles the entire process for you:

  1. Open the verifier page.
  2. Drop the Evidence ZIP onto the upload area (no need to extract it).
  3. Get a per-layer report — file integrity, hash chain, eIDAS timestamp, Bitcoin anchor — each marked PASS or FAIL.

Offline — no GPA, no internet, no account

Every external dependency that verification needs is bundled inside the ZIP itself: the manifest, the hash chain entries, the Bitcoin OpenTimestamps receipt, the qualified TSA's full certificate chain, and a frozen snapshot of the EU Trusted List. The bilingual (English + Czech) README.md inside the ZIP walks you through the four verification steps with copy-paste commands — one step per integrity layer:

  1. Step 1 — File integrity — A python3 script reads manifest.json, recomputes SHA-256 of every file in the package, and compares. PASS = nothing has been added, removed, or modified.
  2. Step 2 — eIDAS qualified timestamp — openssl ts -verify checks the RFC 3161 token against the timestamped payload using the bundled TSA certificate chain. (A pure-Python alternative is included for environments without openssl.) PASS = the data existed at the timestamped moment, signed by the qualified TSA recorded in the EU Trusted List.
  3. Step 3 — Bitcoin OpenTimestamps anchor — The ots client verifies the receipt against the Bitcoin blockchain (or upload it to opentimestamps.org, or check the transaction on a public block explorer like mempool.space). PASS = the chain head was committed to a specific Bitcoin block.
  4. Step 4 — Hash chain — A python3 script walks chain/proof_chain.jsonl, recomputes each entry hash from prev_hash, event type, proof ID and data hash, and confirms the link to chain_head.json. PASS = the internal event log is intact.

All 4 PASS → the package is cryptographically intact. The Bitcoin step is the only one that needs network access (or you can verify the transaction ID on a public explorer instead). Steps 1, 2, and 4 work entirely offline.

Tools you'll need

Three open-source tools cover the entire offline procedure:

  • python3 — everything works on Linux, macOS, and Windows. Used for steps 1, 2 (alternative path), and 4.
  • openssl — standard on Linux/macOS; on Windows use Git Bash or WSL. Used for the canonical eIDAS verification (step 2).
  • ots (from pip install opentimestamps-client) — for the Bitcoin anchor (step 3). Optional — you can also verify by uploading the receipt to opentimestamps.org or by checking the Bitcoin transaction on a block explorer.

Want to know exactly which file in the ZIP is consumed by each step? See the Evidence ZIP — every file inside tutorial.

How to interpret the results

Results are deterministic. Match means the evidence is byte-identical to the original record and all integrity layers pass. Modified means at least one layer failed — the evidence cannot be trusted as the original.

When you see Modified, the per-layer report tells you exactly which layer failed — that's usually enough to demonstrate that the package is not the original exported evidence.

Common failure patterns and what they mean
  • a single file's SHA-256 differs from the manifest → that file was edited (e.g. a screenshot pixel changed, text replaced, or a JSON file reformatted)
  • a chain entry hash mismatch → someone tried to insert, remove, or modify an event in the proof's history
  • eIDAS signature invalid or imprint mismatch → the timestamped payload was altered, or the TSR was substituted
  • Bitcoin anchor verification fails → the OpenTimestamps receipt no longer commits to the same chain head (or the receipt itself was tampered with)

What verification does not do

  • It does not assess truthfulness — only whether the captured content is intact and whether the time anchors are valid.
  • It does not replace legal counsel.
  • It does not decide admissibility — that's determined by authorities and jurisdiction.
  • It does not fix a Modified result. Once a ZIP is tampered with, only the original (untampered) ZIP will verify.

Verification only answers: “Is this evidence original and unchanged, and is its time anchor cryptographically valid?”

Next tutorial

Continue with: Evidence ZIP — every file inside, offline-verifiable.

Not legal advice. Admissibility depends on jurisdiction and circumstances.