provenance-verify
v0.1.2
Published
Clean-room, zero-platform-dependency offline verifier for the TruthLayer ledger and EvidenceVault (TruthCert) certificate trust chain. Reimplements every trust-critical primitive (RFC 8785 JCS, RFC 6962 Merkle, Ed25519, ML-DSA-65, SLH-DSA, OpenTimestamps)
Maintainers
Readme
provenance-verify
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 the audited @noble crypto libraries.
Why "independent" matters. The platforms ship their own verifiers, but those import the platform's own crypto library and run identical logic to the code that produced the artifacts — so 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 against a byte-identical cross-implementation conformance corpus, not assumed. A CI guard fails the build if a single platform import ever creeps in.
MIT licensed. Node ≥ 22.
Install
Status: not yet published to npm. Until the first release lands, install from source:
# from the repo root pnpm install && pnpm --filter provenance-verify build npm link ./tools/independent-verify # exposes the `provenance-verify` CLI
Once published (via the gated publish.yml → npm-provenance-verify):
npm i -g provenance-verifyUse
# Verify a TruthLayer sealed agent-day (event chain → hourly sub-seals →
# RFC 6962 daily root → Ed25519 subkey chain → ML-DSA/SLH-DSA hybrid →
# OpenTimestamps → Bitcoin), from a local bundle or a public mirror:
provenance-verify ledger --tenant-id <t> --agent-id <a> --date <YYYY-MM-DD> --dir <bundle>
provenance-verify ledger --tenant-id <t> --agent-id <a> --date <YYYY-MM-DD> --base-url <url>
# Verify an EvidenceVault certificate (canonical payload hash → Ed25519 +
# ML-DSA-65 + SLH-DSA triple signature → reliance window → Merkle inclusion →
# predicates → Lamport anchor → OTS):
provenance-verify cert --cert-id <c> --tenant-id <t> --dir <bundle>
# Verify the full provenance-to-certificate chain, including the Merkle-root
# join (a certificate's source_evidence_merkle_root binds to the seal's root):
provenance-verify chain --tenant-id <t> --agent-id <a> --date <d> \
--cert-id <c> --cert-tenant <t> --dir <bundle>
# Run the cross-implementation conformance corpus (JCS + Merkle, pinned):
provenance-verify conformanceExit codes: 0 verified · 1 a check failed · 2 usage error. The full check
object is printed as JSON.
What it verifies
TruthLayer ledger (verifyDay, verifyEvent, verifyEventInclusion, verifyLogInclusion)
- the tenant registry is the single trust root; every signature resolves to the tenant root key through the rotation-safe, time-bounded root→subkey chain;
- the daily seal's signature over its canonical preimage (formats 1–4);
- the two-level daily Merkle root recomputes from the 24 hourly leaves (v1 Bitcoin-dup for formats 2/3, RFC 6962 for format 4);
- every non-empty hourly sub-seal is published, signed, and matches;
- ML-DSA-65 hybrid co-signatures (hybrid = AND; required after the tenant's PQC activation date) and SLH-DSA root certifications;
- a single event's chain hash, signature, payload hash, and inclusion path (event → hour → day → anchor);
- checkpoint transparency-log inclusion under a self-signed STH, witness quorum, and consistency (no-rewrite);
- the OpenTimestamps proof, executed offline to a Bitcoin block-header attestation (optionally cross-checked against supplied block headers).
EvidenceVault certificate (verifyCertificateFromArtifacts)
- the canonical payload SHA-256 matches the signature block;
- the Ed25519 + ML-DSA-65 + SLH-DSA-SHA2-128f triple signature verifies through the certificate registry's subkey/PQC trust chain;
- the reliance window (reported as a distinct axis from the crypto verdict);
- optional evidence Merkle inclusion, predicate dependencies, and the Lamport one-time-signature anchor (the SHA-256-only floor).
Bridge (sealRootMatchesCertificate, verifyChain)
- a certificate's
source_evidence_merkle_rootbinds to the TruthLayer seal's Merkle root — proving the certificate attests that sealed day.
Trust model
- Trust roots are the public tenant registries (
public/tenants/{id}.json) and, for certificates, the published existence records. Everything chains to a tenant root key using public artifacts only. - Fail closed / verify forever. An unknown
format/suite/hash_version/domainis a hard refusal; an absent version field verifies under the frozen v1 rule, so already-published evidence verifies forever. - Offline by default. The only networked path is
--base-url(a plain object-store read of a public mirror) — never a platform control-plane call. - The digest floor. OpenTimestamps and Lamport anchoring reduce the residual trust to SHA-256 pre-image resistance and Bitcoin's proof-of-work.
Correctness
test/vectors/canon-vectors.json is a byte-identical copy of the corpus the
TruthLayer and EvidenceVault platforms and the reference Python verifier all run;
its SHA-256 is pinned. The test suite verifies real, committed production
artifacts end-to-end (a Bitcoin-anchored format-4 seal with hybrid PQC
co-signatures and a triple-signed certificate) and proves the verifier fails
closed on every tamper, plus RFC 8032 / RFC 6962 known-answer vectors and the
independence guard.
npm testScope notes
This first release covers the load-bearing verification surface above. The following platform sub-modes are on the roadmap and not yet implemented: selective-disclosure, cross-agent causality, residency, bilateral, and completeness proofs; RFC 3161 TSA-time and drand-beacon existence bounds; DNSSEC-STH corroboration; the adversarial co-attestation structural check; and bonded attestation. Their absence never causes a false pass — an artifact that depends on an unimplemented mode is simply not asserted valid on that axis.
License
MIT.
