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

Verification kernel for the ar.io verification stack: RFC 8785 (JCS) canonicalization, SHA-256 hashing, Ed25519 envelope sign/verify, and RFC 9162 binary Merkle inclusion proofs — as a standalone, dependency-light Python package.

pip install ar-io-proof

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,
)

What this package implements

  • 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}, fail-closed on anything else. 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.

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.1.0.tar.gz (91.5 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.1.0-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for ar_io_proof-0.1.0.tar.gz
Algorithm Hash digest
SHA256 434ea4866ec120d8176c38dad4ed2b392c1fffda754963753b0d5fdc2b9a2b27
MD5 56e3239b22eed3cfe701ab7a8f59962c
BLAKE2b-256 fd9b1d2bc3681e08943e8e9fbe626b790357ad464dbd293c12f6eca633d61fe1

See more details on using hashes here.

Provenance

The following attestation bundles were made for ar_io_proof-0.1.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.1.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for ar_io_proof-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 be321ca392595fb3f1f3f7c5cdb6bddff86bc3bd1fee9f1f8d131339bd436371
MD5 08c5849fe67b65be7c85a268d4a5f875
BLAKE2b-256 e92802f1ed96f0c88940ddd66f20d9aa149fd73951a350fef648e0d81d6f1076

See more details on using hashes here.

Provenance

The following attestation bundles were made for ar_io_proof-0.1.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