Metadata-Version: 2.4
Name: trustnotch
Version: 0.1.1
Summary: Offline verifier for TrustNotch tamper-evident audit-log proofs.
Keywords: audit,verifier,merkle,opentimestamps,tamper-evident
Author: Sandro Chekalov
Author-email: Sandro Chekalov <sandro@trustnotch.com>
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: System :: Logging
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Dist: cryptography>=48.0.0
Requires-Dist: opentimestamps>=0.4.5
Requires-Python: >=3.12
Project-URL: Homepage, https://trustnotch.com
Project-URL: Repository, https://github.com/trustnotch/trustnotch
Project-URL: Issues, https://github.com/trustnotch/trustnotch/issues
Description-Content-Type: text/markdown

# trustnotch

Offline verifier for [TrustNotch](https://trustnotch.com) tamper-evident audit-log proofs (`proof-format-v1`).

Verify any proof bundle on your own machine — no database, no network, no dependence on the TrustNotch server. You supply the trusted keys; `trustnotch` checks the cryptography. If TrustNotch went away tomorrow, every proof it ever issued would still be verifiable with this package alone.

Requires Python 3.12+. Apache-2.0 licensed.

## Install

```
pip install trustnotch
```

Or run the CLI without installing it:

```
uvx trustnotch verify bundle.json
```

## Command line

```
trustnotch verify [--keys PATH | --offline] [--json] BUNDLE
```

- `BUNDLE` — path to a proof-bundle JSON file.
- `--keys PATH` — verify signatures against your own `pubkeys.json` (default: the keys bundled with this package).
- `--offline` — skip the receipt (signature) tier; verify inclusion and anchor only, no keys required.
- `--json` — emit machine-readable JSON.

It prints each tier's status; add `--json` for a structured result.

## Library

```python
import json
from pathlib import Path
from trustnotch.verify import verify, load_pubkeys, load_bundled_pubkeys

bundle = json.loads(Path("proof.json").read_text())

# verify against the keys shipped with this package…
result = verify(bundle, load_bundled_pubkeys())

# …or against keys you supply
trusted = load_pubkeys(json.loads(Path("pubkeys.json").read_text()))
result = verify(bundle, trusted)

if result.receipt_and_inclusion_ok:
    ...
```

## What it checks

`verify()` reports each tier **independently** and deliberately offers no single "verified" boolean (see `proof-format-v1` §6) — you decide which tiers must hold for your threat model:

- **receipt** — the bundle's signature verifies against a trusted key.
- **inclusion** — the entry is provably included under the signed Merkle root (RFC 6962).
- **anchor_structural** — the OpenTimestamps proof is well-formed and commits the Merkle root to a Bitcoin timestamp. This is a *structural* check of the timestamp proof; confirming the anchoring transaction against the live Bitcoin chain is a separate step that requires chain data.

## About this repository

This is the source of the published [`trustnotch`](https://pypi.org/project/trustnotch/) package. The PyPI wheel is built from exactly this tree, and the repository is kept in sync with the package at each release, so the code you audit here is the code that runs.
