Skip to main content

Verification kernel for the ar.io verification stack: RFC 8785 canonicalization, SHA-256, Ed25519 envelope sign/verify, RFC 9162 Merkle inclusion proofs.

Project description

ar-io-proof

The polyglot verification home of the ar.io verification stack: RFC 8785 (JCS) canonicalization, SHA-256 hashing, Ed25519 envelope sign/verify, and RFC 9162 binary Merkle inclusion proofs — as standalone, dependency-light kernels in two languages, plus the family specs and the one authoritative conformance corpus. An app never owns a kernel; producers and verifiers import these.

Both reproduce the same test-vectors-v1.0 corpus byte-for-byte; that mutual conformance gate is the point — anyone can verify ar.io provenance with no ar.io code in the trust path.

pip install ar-io-proof        # Python
npm install @ar.io/proof       # TypeScript

Quickstart

Verify a signed envelope fetched from any Arweave gateway:

import json
import urllib.request

from ario_proof import verify_envelope

raw = urllib.request.urlopen("https://arweave.net/raw/<tx_id>").read()
result = verify_envelope(json.loads(raw))

assert result.ok            # spec_version + payload binding + Ed25519 signature
print(result.to_dict())

Bind an artifact you hold to the provenance an envelope commits to (reverse lookup):

import hashlib

artifact_hash = hashlib.sha256(open("model.pkl", "rb").read()).hexdigest()
result = verify_envelope(envelope, expected_content_hash=artifact_hash)
print(result.content_hash_ok, result.content_role)   # True, "asset"

Verify an external-commitment (ario.mlflow/v1) envelope against the committed bytes:

result = verify_envelope(envelope, payload_bytes=canonical_bytes)

Verify an inclusion-proof bundle (ariod proof output — proves a leaf was in a signed daily checkpoint):

from ario_proof import verify_proof_bundle

bundle = json.load(open("proof-bundle.json"))
result = verify_proof_bundle(bundle)
assert result.ok and result.inclusion_ok

Sign an envelope (producers):

from ario_proof import sign_envelope, signing_key_from_seed_hex

key = signing_key_from_seed_hex("<32-byte seed hex>")
envelope = sign_envelope(
    {
        "spec_version": "ario.mlflow/v1",
        "event_id": "...",
        "event_type": "training_complete",
        "subject": {"type": "mlflow_run", "run_id": "..."},
        "payload_hash": "<sha256 of the committed canonical bytes>",
        "previous_hash": "GENESIS",
        "signed_at": "2026-06-10T00:00:00.000Z",
    },
    key,
)

TypeScript (@ar.io/proof)

The same algorithm, conformance-gated against the same corpus (ts/test/conformance.test.ts reads the authoritative test-vectors/ directly). Browser + Node ≥ 20, ESM, two small deps (@noble/ed25519, canonicalize):

import { verifyEnvelope, sha256Hex, contentHashes } from "@ar.io/proof";

const env = await (await fetch("https://arweave.net/raw/<tx_id>")).json();
const result = await verifyEnvelope(env);
result.ok; // spec_version + payload_hash + Ed25519 all passed

// Reverse lookup: bind an artifact you hold to what an envelope commits to.
const bound = await verifyEnvelope(env, await sha256Hex(fileBytes));
bound.contentHashOk; // true ⇔ the envelope commits to exactly these bytes

It also ships the RFC 9162 Merkle primitives (leafHash / merkleRoot / auditPath / verifyInclusion) for full parity with the Python kernel. See ts/README.md.

What these kernels implement

  • The Verifiable Event Envelope family contract, envelope-spec.md v1.1 (ratified v1.0 2026-06-10, amended 2026-06-11 — additive, same conformance corpus), for two profiles:
    • ario.agent/v1 — inline-payload envelopes minted by ar-io-agent (byte-level format: docs/artifact.md).
    • ario.mlflow/v1 — external-commitment envelopes minted by ar-io-mlflow.
  • The RFC 9162 binary Merkle tree (leaf/node domain separation, audit paths, pinned empty-tree root) and the ario.agent.proof/v1 inclusion-proof bundle behind agent verification checkpoints.
  • The accepted-version registry: {ario.agent/v1, ario.mlflow/v1}, matched on the v<major> token boundary per envelope-spec §2 — additive minors (ario.agent/v1.3) are accepted within a major; different majors (ario.agent/v10) and malformed minors fail closed. Envelopes that predate spec_version verify only with an explicit allow_legacy=True.
  • The signed scope per the ratified contract: the envelope minus signature, minus the reserved co_signatures field (envelope-spec §7.1), and — for ario.mlflow/v1 and legacy envelopes only — minus underscore-prefixed annotation keys. The ario.agent/v1 signed scope is minus signature/co_signatures only, matching the Go reference byte-for-byte.

The kernel is exactly the five primitives in the stack architecture's kernel scope — no I/O, no networking, no key lifecycle. Gateway fetching, attestation polling, and key storage belong to the products that import this.

Conformance

This package is conformance-gated against the ario.agent/v1 corpus at tag test-vectors-v1.0, vendored under test-vectors/ byte-for-byte (see test-vectors/VENDORING.md for provenance). CI asserts, for every vector: JCS-canonical bytes, payload hashes, envelope-for-signature bytes, deterministic signatures, Merkle roots, and audit paths — exact to the byte. If this package disagrees with a vector, the package is wrong — never the vector.

mlflow-profile-specific behaviors (external commitment, underscore stripping, legacy acceptance) are covered by unit tests; the bidirectional cross-product gate against ar-io-mlflow's production verifier lands when mlflow migrates to import this package.

Trust model

result.ok proves: the holder of the private key matching the envelope's public_key signed exactly these bytes, and the payload binding holds. It does not prove whose key that is, or that the envelope is on Arweave — trust in the key comes from out of band (e.g. the agent's registration chain), and on-chain presence comes from fetching the TX yourself and re-verifying, which is exactly what the quickstart does. signed_at is the signer's claim, not a trusted timestamp; witnessed time comes from the Arweave block.

Development

python3 -m venv .venv && .venv/bin/pip install -e .[dev]
.venv/bin/pytest -q          # the conformance gate is the contract
.venv/bin/black src tests

Dependencies are deliberately two: PyNaCl (Ed25519, strict RFC 8032 — matches Go crypto/ed25519 and the JS sibling verifier) and jcs (reference RFC 8785).

License

MIT — verifier-relevant code is deliberately MIT-licensed so third-party auditors can verify independently of ar.io.

Standards home

As of 2026-06-11 this repo is the authoritative home of the verification stack's standards layer (moved from ar-io-agent so the contract is public alongside the reference verifiers) — and, with the TypeScript kernel's move from the proof-checker app, the single home of every conformant kernel the stack ships (the Go reference stays in ar-io-agent/pkg/proof, MIT-carved):

  • specs/envelope-spec.md — the producer-neutral Verifiable Event Envelope family contract (ratified v1.0, amended v1.1)
  • specs/evidence-bundle.mdario.evidence/v1 report wrapper (ratified v1.0, not yet implemented)
  • specs/architecture.md — kernel / producer / connector / transport factoring standard (ratified v1.0)
  • specs/governance.md — who decides, how (BDFL, async docs-PR, corpus-tag governance, amendment log)
  • test-vectors/ — the conformance corpus, locked at test-vectors-v1.0 (per-file SHA-256 in CORPUS-v1.md), generated by tools/gen-vectors/ — generated, never hand-edited
  • ts/ — the TypeScript kernel (@ar.io/proof on npm), conformance-gated against the same test-vectors/ corpus; moved here 2026-06-11 from the proof-checker app (an app never owns a kernel — the same principle that extracted the Python kernel from mlflow). The proof-checker now consumes it as an ordinary npm dependency.
  • Producer profiles stay with their producers: ario.agent/v1 is artifact.md in ar-io-agent; ario.mlflow/v1 lives in ar-io-mlflow.

Tag namespaces (no overlap): v* = Python release · ts-v* = TypeScript release · test-vectors-v* = corpus. Python publishes to PyPI via release.yml; TypeScript publishes to npm via release-ts.yml (OIDC trusted publishing, provenance on).

Contract conflicts: open an issue here titled contract conflict: <spec> §<section> with the smallest reproduction (see specs/governance.md §6).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ar_io_proof-0.2.0.tar.gz (192.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ar_io_proof-0.2.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file ar_io_proof-0.2.0.tar.gz.

File metadata

  • Download URL: ar_io_proof-0.2.0.tar.gz
  • Upload date:
  • Size: 192.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ar_io_proof-0.2.0.tar.gz
Algorithm Hash digest
SHA256 34b4fcab20147c8bc911f33afd661ec8db63fc47ebc69be365f104decfe648e1
MD5 f6bbaaf29cfd2dd645d6b3e51c0eadd8
BLAKE2b-256 d41f3fa2590a9fa2697a78becf988a45f41976d2df3b841dc82dcbf6b62a5a71

See more details on using hashes here.

Provenance

The following attestation bundles were made for ar_io_proof-0.2.0.tar.gz:

Publisher: release.yml on ar-io/ar-io-proof

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ar_io_proof-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: ar_io_proof-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for ar_io_proof-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 df78607eb7f7f3f0655f8ec7b27ce1ecd770e3b609bd10c4d1b65d638e617d62
MD5 9048ac6b3b5e81deea678921612634e0
BLAKE2b-256 c38a67061e9937f66feef48380fb2bb4fd66a099e74751f45fc9472e94a04882

See more details on using hashes here.

Provenance

The following attestation bundles were made for ar_io_proof-0.2.0-py3-none-any.whl:

Publisher: release.yml on ar-io/ar-io-proof

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page