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}, 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.

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.1.tar.gz (92.3 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.1-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: ar_io_proof-0.1.1.tar.gz
  • Upload date:
  • Size: 92.3 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.1.tar.gz
Algorithm Hash digest
SHA256 d5078a61a690a06de6f8ae2fd424dee86b24dded73670abd2abf79945de8ac0f
MD5 0cac5f6c5a462b796e25e1177d65c611
BLAKE2b-256 7300cb42a8a5afe043b95effc7872744ef3d94cbe627b99dd813068715303084

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: ar_io_proof-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 16.1 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e3daf2951d5f9d91d92bec694a1eefdd576f4a1eb93ffd171d55bca6ddcf4317
MD5 199bed90a9bcb9aa6cb32de958ca7814
BLAKE2b-256 e5e2f0abee12c76e3541b4e1f3bdf3637fe522950f1355aea2d5d1195582c5e6

See more details on using hashes here.

Provenance

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