aere-research/aips/AIP-23.md

15 KiB

AIP-23: AERE Proof Protocol (a portable, verifiable statement + on-chain finality envelope)

Preamble

Field Value
AIP 23
Title AERE Proof Protocol (portable verifiable-statement envelope with optional post-quantum on-chain finality)
Author Aere Network Foundation
Type Standards Track
Category Interface
Status Draft (describes the envelope AERE tools already emit; the reference verifier is published with this AIP)
Created 2026-09-26
Requires AIP-15 (anchor certificate under the block hash), AIP-21 (per-block PQ seal record)
Supersedes None
Superseded-By None
Ratification Not ratified; open standard, reference verifier aere-node/tools/verify-proof.mjs, conformance vectors in aere-node/tools/proof-vectors/

Abstract

AERE already emits proofs from several surfaces (Proof of Software attestations, Cloud audit-log notarization, the anchor certificate) and they share one shape without ever having been named: a structured statement, a statementHash (the SHA-256 of the statement's canonical text), an optional producer signature, and an optional on-chain notarization whose finality becomes post-quantum once an AERE anchor with a post-quantum validator certificate (AIP-15) covers the state that records it. This AIP names that shape the AERE Proof Protocol, fixes it so anyone can produce and verify it without trusting the producer, and publishes a reference verifier and conformance vectors. The claim it makes checkable is narrow and concrete: a stranger can verify what a system stated, and when the chain first saw it, against a chain state certified post-quantum, without trusting the producer or the RPC endpoint they read through.

Motivation

Today the same envelope is re-described in each tool (Proof of Software's attestation.json, the gateway's /v1/proof, the audit export). A third party who wants to verify an AERE proof has to read the source each time. Fixing one envelope and one open verifier turns "AERE can verify post-quantum" into "anyone can verify against AERE", which is the only version of the claim that survives a hostile reading.

Non-goals: this AIP does not define new cryptography, a new chain rule, or a new contract. It fixes the interface of proofs that already exist. Signature schemes are referenced (hybrid ECDSA + ML-DSA via @aere/pq-sign), not redefined.

Specification

1. The envelope

A proof is a JSON object:

{
  "v": 1,
  "kind": "aere-proof-of-<type>-attestation",
  "statement": { "v": 1, "kind": "aere-proof-of-<type>", ...type-specific fields..., "createdAt": "<RFC3339>" },
  "statementHash": "0x<64 hex>",
  "signature": { "scheme": "ml-dsa-65", "publicKey": "<spki der base64 | pem>", "signature": "<base64|hex>" } | null,
  "notarization": { "txHash": "0x..", "block": <n>, "firstSeenAt": <unix seconds>, "contract": "0x..", "chainId": 2800 } | null
}
  • statement is the payload: what happened. Its kind names the proof type (aere-proof-of-software, aere-proof-of-data, aere-proof-of-ai, aere-proof-of-execution, aere-proof-of-identity, aere-proof-of-compliance, ...). The type-specific fields are that type's business; the protocol constrains only the envelope. The kinds AERE produces, with their fields and one conformance envelope each, are listed in aere-research/aips/aip23-kinds/ (added 2026-09-29).
  • statementHash binds the statement.
  • signature (optional) is the producer's signature over the canonical statement text.
  • notarization (optional) records that statementHash was written to the on-chain notary. It is a claim of the producer; a verifier does not take it on trust (section 4).

2. Canonical text and statementHash

The canonical text of a statement is JSON.stringify(statement) with keys in insertion order, exactly as written into the envelope (this is what Proof of Software already does; do not re-sort keys, do not reformat). statementHash is

statementHash = "0x" + hex( SHA-256( utf8( JSON.stringify(statement) ) ) )

A verifier recomputes the SHA-256 over the exact statement sub-object as serialized and requires equality. (SHA-256 rather than keccak: it is the digest Proof of Software has emitted since 1.0.0 and the one software-attestation tooling speaks; the on-chain notary stores whatever 32-byte value it is handed.)

3. Signature (optional)

If present, the signature is over the canonical statement text (section 2), not over the envelope. The reference verifier checks an ml-dsa-{44,65,87} signature with node:crypto (OpenSSL 3.5) when the public key is present; the full hybrid ECDSA + ML-DSA form is verified by @aere/pq-sign. A signature the reference verifier cannot check is reported UNMEASURED, never silently passed.

4. On-chain finality (optional)

statementHash is notarized by calling notarize(bytes32) on the AERE notary contract (chain 2800, 0x4aB392c4Aca7D9D4C16c0b60a9514c5025bd58c7; permissionless, no owner). The contract records, once, the time of the block in which the hash was first seen: firstSeen[h] = block.timestamp (unix seconds, proofOf(bytes32) -> uint64). It does not record a block number; the block that holds the first sighting is found from the contract's Notarized event.

A verifier establishes finality from a certified state, not from what an endpoint says:

  1. the chain's most recent anchor is verified: every post-quantum seal of its certificate is checked against the published key manifests, and the certificate is bound under the anchor's hash (AIP-15; this is what aere-node/tools/verify-anchor.mjs does);
  2. the header of the anchor's parent is re-encoded in its on-chain form and must hash to the parent hash those seals signed;
  3. that header's state root anchors a Merkle-Patricia proof (eth_getProof) of the notary's account, whose code hash must be the notary's runtime code hash (0x8eaa924081e9718fcee05ae64fadaa1815437ebbbcef5b87317c5879050452ce), and of the storage slot firstSeen[statementHash] (slot keccak256(statementHash || uint256(0)));
  4. the slot's value is the first-seen time. An empty slot, proven absent, means not notarized as of that certified state.

The endpoint only carries data: a header, a proof node or a value it altered would not match the hash the certificate signed. The first-seen block, located through the endpoint's logs, is reported as such and is not part of what is certified. Levels:

level meaning
not-notarized the certified state holds no entry for the hash (proven absent)
pending the endpoint reports a notarization after the certified state; the next anchor will cover it
post-quantum the certified state records the hash with its first-seen time; changing that record would require forging the certificate of an anchor at or above it

The most recent anchor is used, not the anchor right after the first sighting, because the record never changes once written (a second notarize of the same hash leaves it as it is) and the endpoint's state window may not reach an old block.

5. Verification levels and verdict

A verifier reports each level that is present in the envelope, and a verdict:

  1. form: the envelope has statement (object) and statementHash (0x + 64 hex).
  2. integrity: section 2 holds.
  3. signature: present ? verified or UNMEASURED : absent.
  4. finality: (the envelope claims a notarization, or an endpoint is given) ? the section-4 levels : absent. A claimed notarization that the certified state does not hold is a failure.

VALID iff every present level passed; PARTIAL if a present level is UNMEASURED or pending; INVALID if any present level failed. A verifier that cannot go INVALID cannot be trusted: the conformance suite plants failures and requires each to be caught.

Rationale

  • One envelope, many kinds. The protocol constrains only what every proof needs (a statement, its hash, an optional signature, an optional notarization); each kind keeps its own fields. A verifier that knows no kind can still check levels 1, 2 and 4.
  • SHA-256 over the canonical text. It is what Proof of Software already emits, and it keeps the envelope checkable with the standard library of any language; the notary is agnostic to the digest.
  • Finality from a certified state, not from an endpoint. Reading proofOf through an RPC endpoint and calling the result post-quantum because the covering anchor carries a certificate would make the endpoint the trust anchor. Binding a storage proof to a header whose hash the verified certificate signed moves the trust to the certificate, which is what the anchor is for.
  • The most recent anchor. The notary's record is write-once, so the most recent certified state is as good as the one right after the first sighting, and it is the one an endpoint can still prove (state windows are finite).

Backwards Compatibility

Envelopes that Proof of Software and the Cloud gateway already emit are valid envelopes under this AIP; nothing they produce changes. A draft of the reference verifier (2026-09-26, not published) read the notary's value as a block number and reported the covering anchor post-quantum from the presence of a certificate; it is replaced by the verifier described here.

Security Considerations

  • What is certified. That the statementHash was recorded by the notary, with its first-seen time, in a state covered by a post-quantum validator certificate. Not certified: the truth of the statement (that is the producer's word, or its signature's); the first-seen block number (located through logs); anything about the producer's identity unless the signature level passed.
  • Notarization is permissionless. Anyone can notarize any hash; a first-seen time proves that the statement existed at that time, not who wrote it. Authorship is the signature level's job.
  • The certificate's trust is the validator set's and the published key manifests': a verifier that trusts the manifests it downloads trusts their publisher, and aere-node/tools/verify-anchor.mjs checks the manifests' self-consistency and the validators' own bindings to their keys.
  • An endpoint can refuse to answer or answer late (reported UNMEASURED), but it cannot make an altered header, proof node or value pass: each is bound by hash to what the certificate signed.
  • Signatures a verifier cannot check are UNMEASURED, never PASSED.

Reference Implementation and On-Chain Deployment

  • AERE notary: chain 2800 0x4aB392c4Aca7D9D4C16c0b60a9514c5025bd58c7; public testnet 28001 0x70099E62735500AA2F85B60C518551a57B202d54 (the same runtime code, code hash in section 4).

  • aere-node/tools/verify-proof.mjs: the verifier (Node, node:crypto and @noble/hashes); for the finality level it runs aere-node/tools/verify-anchor.mjs, published beside it, and reads the anchor it verified from its ANCHOR_REPORT output, so the certificate check exists in one place. node verify-proof.mjs <envelope.json> [--rpc <url>] [--chain 2800|28001] [--json].

  • aere-node/tools/proof-vectors/: envelopes with their expected verdicts, a real Proof-of-Software attestation among them, and one notarized on the public testnet 28001.

  • aere-research/aips/aip23-kinds/ (added 2026-09-29): the proof kinds AERE produces, fifteen on that date (data, execution, identity, compliance, runtime, location, device, payment, ownership, time, block, authorization, settlement, provenance, AI; the last three before AI were added on 2026-09-28), each with its required fields in KINDS.json and one envelope. A settlement carries its transaction and block as 32-byte hashes as they are, never re-hashed; a provenance names a non-empty list of parents.

  • Later on 2026-09-29, a sixteenth kind in the same folder: agent-decision (aere-proof-of-agent-decision), an AI agent's action judged against a policy named by its hash, allowed or refused and why. Its actionHash is the SHA-256 of the canonical JSON of the action (keys sorted at every level), so anyone can recompute it from the action. It is produced by the agents component published the same day in aere-quantum/agents/.

Measured status (2026-09-27)

  • Levels 1 to 3: the verifier reproduces the statementHash of a real attestation; a changed statement, a changed statementHash and a missing statementHash each give INVALID.
  • Finality, end to end on the public testnet 28001, where a notary with the same runtime code was deployed for this purpose (0x70099E62735500AA2F85B60C518551a57B202d54): a statement about the published AIP-22 conformance corpus was notarized at block 3,618,722, and the verifier reports it post-quantum from the state of the parent of the most recent anchor, with its first-seen time. Through an endpoint that alters the parent header's state root, a node of the storage proof, or the value proofOf returns, and with a certificate altered on the way to the anchor check, the verdict is INVALID in the first, second and fourth cases and unaffected by the third (the value is read from the proof, not from the call); an address that holds another contract is refused by its code hash. With a check removed in a copy of the verifier (the header binding, the code hash, the node hash, the anchor verdict), the corresponding case no longer gives the expected verdict, four of four.
  • On chain 2800 nothing is notarized yet; there the verifier proves the absence of a hash from the certified state. Corrected 2026-09-29: the sentence above was wrong when written. The notary on chain 2800 does hold digests (measured: one first seen at 2026-09-17T21:08:06Z); what holds is that none of the published conformance vectors is notarized there, so for them the verifier proves the absence of their hash from the certified state.

Measured status (2026-09-29)

  • Each of the fifteen envelopes in aere-research/aips/aip23-kinds/ is VALID with the reference verifier offline (form and integrity pass; signature and finality are ABSENT). The folder is written from one source, and a copy altered, a foreign file, a kind without its description or a vector whose statement no longer hashes to its statementHash stops the publication.
  • With agent-decision added later that day, the folder holds sixteen envelopes, each VALID with the reference verifier offline (measured with verify-proof.mjs on each of the sixteen files, 16 of 16).

Adoption path

The value is in external implementations: once other tools emit this envelope and other verifiers check it, AERE becomes a common verification layer rather than one more product. Concretely: the verifier and vectors are published with this AIP, the SDKs gain a verify command that wraps the verifier, and the conformance vectors are the compatibility contract.

Errata

  1. 2026-09-29, Measured status (2026-09-27), last item. It said that nothing was notarized on chain 2800. The notary there held digests from 2026-09-17; the statement was true only of the published conformance vectors. Corrected in place, with its date.

Post-Acceptance Outcome Record

Not accepted; nothing to record.

Copyright and related rights waived via CC0.