How verification works

Every TrustNotch proof is self-contained. Verification runs entirely on your machine — no API call, no account, no TrustNotch server. Here is exactly what the verifier checks and why each step matters.

What a proof bundle contains

Once an entry's batch is anchored, TrustNotch can produce a proof bundle: a single document with everything needed to verify the entry offline.

Receipt

An Ed25519 signature over the entry's RFC 6962 leaf hash, issued at submission time. Proves the exact content that was accepted.

Merkle path

The sibling hashes needed to recompute every node from this leaf up to the batch's Merkle root, per RFC 6962.

Bitcoin anchor

An OpenTimestamps proof that chains the batch root to a Bitcoin block header hash — establishing that the batch existed before that block was mined.

Three checks, all local

  1. Verify the receipt

    The verifier computes the RFC 6962 leaf hash of the submitted content — SHA-256(0x00 || entry) — and checks the Ed25519 signature in the receipt against TrustNotch's public key. If the entry's content was changed after submission, the signature check fails.

    Public keys are fetched once from the public /v1/keys directory, or loaded from a local file via TRUSTNOTCH_PUBKEYS_PATH. After that initial fetch, no further server contact is needed.

  2. Verify Merkle inclusion

    Using the sibling hashes in the Merkle path, the verifier recomputes each interior node up to the batch root, following the RFC 6962 construction: interior nodes are SHA-256(0x01 || left || right). The computed root must match the root committed in both the receipt and the OpenTimestamps proof.

    This step proves the entry is in the specific batch, not merely that the batch root is anchored somewhere. An entry that was not included cannot produce a valid Merkle path to the committed root.

  3. Verify the Bitcoin anchor

    The OpenTimestamps proof encodes a hash chain from the batch root to a Bitcoin block header hash. The verifier checks this chain structurally — confirming each hashing operation in the chain is correct. A valid chain establishes that the batch root was committed before the referenced Bitcoin block was mined.

    Bitcoin anchoring is asynchronous: the signed receipt is returned at submission time, and the Bitcoin anchor accrues over the following hours as the OpenTimestamps calendars aggregate and a block is mined. The receipt alone proves the exact content; the Bitcoin anchor bounds it in time.

The guarantee that holds without us

All three checks run locally. The math does not involve TrustNotch — once a proof is in your hands, it is yours. A proof that verifies today will verify in ten years, even if TrustNotch has shut down.

This is deliberately different from "trust our immutability claims." A signed receipt from a vendor that controls its own database is an assertion; a proof that recomputes against Bitcoin's public ledger is independently checkable evidence. The distinction matters in a compliance audit or legal proceeding where "we say it's immutable" is not acceptable.

Because the verifier is open source, anyone can read what it does. There is no black box — the verification logic is the same whether you run the trustnotch CLI, the verify_proof MCP tool, or implement the three checks yourself from the RFC 6962 and OpenTimestamps specs.

Install the standalone verifier

The trustnotch verifier is open source, published to PyPI with provenance attestation, and has no runtime dependency on TrustNotch.

# Install
pip install trustnotch

# Verify a proof bundle offline
trustnotch verify proof.json