provenance-verify (Python)
A clean-room, zero-platform-dependency offline verifier for the TruthLayer ledger and EvidenceVault (TruthCert) certificate trust chain.
provenance-verify independently checks the cryptographic claims of both platforms from public artifacts alone — no platform endpoint, cooperation, or continued existence required. It reimplements every trust-critical primitive (RFC 8785 JSON canonicalization, RFC 6962 Merkle trees, Ed25519, ML-DSA-65, SLH-DSA-SHA2-128f, OpenTimestamps→Bitcoin, Lamport OTS) from the published format spec, depending only on audited public cryptography libraries (cryptography, dilithium-py, slh-dsa, blake3).
Why "independent" matters. The platforms ship their own verifiers, but those run identical logic to the code that produced the artifacts — a bug or tampering in that code would pass both. This package shares no code with either platform. It is a genuine second implementation whose agreement with the platform is proven, not assumed: against a byte-identical cross-implementation conformance corpus and a live field-for-field diff against the TypeScript
provenance-verifyover shared fixtures.
This is the Python sibling of the TypeScript provenance-verify npm package. Both verify the same artifacts and produce the same verdicts. MIT licensed. Python ≥ 3.10.
Install
Status: not yet published to PyPI. Until the first release lands, install from source:
pip install ./tools/independent-verify-py
Once published (via the gated publish.yml → pypi-provenance-verify):
pip install provenance-verify
CLI
# Verify a TruthLayer sealed agent-day (event chain → hourly sub-seals → daily
# root → Bitcoin anchor) from a local artifact bundle (or --base-url <url>):
provenance-verify ledger --tenant-id <t> --agent-id <a> --date <YYYY-MM-DD> --dir <bundle>
# Verify an EvidenceVault certificate (Ed25519 + ML-DSA-65 + SLH-DSA hybrid):
provenance-verify cert --cert-id <c> --tenant-id <t> --dir <bundle>
# Verify the full provenance→certificate chain, including the Merkle-root join:
provenance-verify chain --tenant-id <t> --agent-id <a> --date <d> \
--cert-id <c> --cert-tenant <t> --dir <bundle>
# Self-test the crypto core against the bundled cross-implementation corpus:
provenance-verify conformance
Exit codes: 0 ok · 1 a check failed (fail-closed) · 2 usage error.
Library
from provenance_verify import DirSource, verify_certificate_from_artifacts, verify_day
cert = verify_certificate_from_artifacts(
DirSource("bundle"), {"certId": "cert_...", "tenantId": "tnt_..."}
)
print(cert["ok"], cert["checks"])
What it verifies
- RFC 8785 (JCS) canonicalization, byte-identical to the JavaScript signer — including the ECMAScript
Number::toStringnumber format and UTF-16 key ordering. - RFC 6962 / RFC 9162 Merkle inclusion and consistency proofs (
0x00leaf /0x01node domain separation), plus the frozen Bitcoin-style v1 tree. - Hybrid-AND signatures — a certificate/seal is valid only if every family verifies: Ed25519 (RFC 8032) + ML-DSA-65 (FIPS 204) + SLH-DSA-SHA2-128f (FIPS 205).
- The trust root — two-level tenant root → time-bounded agent subkey resolution, and SLH-DSA root certifications.
- The OpenTimestamps → Bitcoin anchor — the stored calendar proof is parsed and executed to the claimed block; an unparseable/unexecutable proof is an error, never silently "pending".
- The Lamport one-time anchor — the SHA-256-only floor beneath the hybrid stack.
- Fail-closed discipline — unknown formats, hash suites, and signature suites are rejected; missing required artifacts fail closed.
Proof of faithfulness
The port is not merely internally consistent — its agreement with the reference implementation is tested:
tests/test_conformance.pyruns the sharedcanon-vectors.jsoncorpus (JCS canonical strings + SHA-256, v1/v2 Merkle roots for leaf counts 1..32) and asserts every value matches byte-for-byte.tests/test_cross_validation.pyruns the TypeScriptprovenance-verifyCLI and this implementation over the same fixtures and asserts they agree onok,validity, and the entirechecksmap, field-for-field.tests/test_fixtures.pyverifies real green bundles end-to-end and confirms tampered payloads/seals and missing registries fail closed.
pip install -e ".[test]" && pytest
Metadata
Release files for provenance-verify 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| provenance_verify-0.1.2.tar.gz | 42.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| provenance_verify-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 91.7 kB
Release files / provenance_verify-0.1.2.tar.gz
| Download URL | provenance_verify-0.1.2.tar.gz |
|---|---|
| Size | 42.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cd49153829b2b2edc4584ca811ff1f474175c10549efc0b37761b94fd7ca5ec8
|
|
BLAKE2b-256 checksum How to use checksums |
a0887d6ff22796e911ab744d2ac9b077829a41d74335da9a0fd62fd98e8bb6b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / provenance_verify-0.1.2-py3-none-any.whl
| Download URL | provenance_verify-0.1.2-py3-none-any.whl |
|---|---|
| Size | 49.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c486cd8f6de9ab9f46e54585b71a3559fd758e1efb63214f4912b9deda8efbc4
|
|
BLAKE2b-256 checksum How to use checksums |
75501d66d8e7229ad3add2a06bfd50cdc1ccbd4a0b534953cabe73fb657efd50
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|