AIP-23 AERE Proof Protocol (Draft) published with its reference verifier and conformance vectors (aere-node/tools/); index: AIP-22 status brought to date, AIP-23 added

This commit is contained in:
Aere Network 2026-09-27 06:44:07 +03:00
parent 6d907fa2e9
commit f86746a376
2 changed files with 202 additions and 1 deletions

200
aips/AIP-23.md Normal file
View File

@ -0,0 +1,200 @@
# 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.
- `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.
### 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.
### 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
None.
## Post-Acceptance Outcome Record
Not accepted; nothing to record.
## Copyright
Copyright and related rights waived via CC0.

View File

@ -46,7 +46,8 @@ document is current.
| [19](./AIP-19.md) | AIP Process Hardening | Meta | **Review, not ratified** | | | [19](./AIP-19.md) | AIP Process Hardening | Meta | **Review, not ratified** | |
| [20](./AIP-20.md) | Native Post-Quantum Transactions (Type 0x50, ML-DSA Authorization) | Standards Track / Core | **Draft, not ratified; implemented in both clients and proven conformant on shared vectors (2026-09-17); live on testnet 28001 from block 2,212,000 (first type-0x50 transaction at 2,212,032, both clients); on chain 2800 the implementation runs on every node since 2026-09-22 and is armed, uniformly, for block 19,900,000 (per-node property, not a genesis change); no type-0x50 transaction on chain 2800 before that height** | | | [20](./AIP-20.md) | Native Post-Quantum Transactions (Type 0x50, ML-DSA Authorization) | Standards Track / Core | **Draft, not ratified; implemented in both clients and proven conformant on shared vectors (2026-09-17); live on testnet 28001 from block 2,212,000 (first type-0x50 transaction at 2,212,032, both clients); on chain 2800 the implementation runs on every node since 2026-09-22 and is armed, uniformly, for block 19,900,000 (per-node property, not a genesis change); no type-0x50 transaction on chain 2800 before that height** | |
| [21](./AIP-21.md) | Verifiable Post-Quantum Finality per Block (Side Store, Proof RPC, Anchor as Permanent Record) | Standards Track / Interface (non-consensus) | **Draft, not ratified; first half (retention window + `aere_getPqFinality`) implemented in the Besu-derived client with 7 tests and deployed on testnet 28001 (5 nodes, public door `testnet-rpc.aere.network/finality`) on 2026-09-18; Nethermind port the same day (10 tests) and deployed on the testnet Nethermind validator with its own public door; two-client conformance proven live (`aip21-conformitate/DOVEDESTE.sh`, CONFORM on block 2,250,809); second half (the window on disk, same journal format in both clients) deployed on all six testnet nodes the same day: the window survives a restart in both (1,284 and 1,255 seals re-verified, 0 failed), and a round-1 block is `post-quantum` in both on the same hash (CONFORM 08:49Z, block 2,285,481 and round-1 block 2,285,333); on chain 2800 since 2026-09-22 on all ten validators and both clients (`aere_getPqFinality` answers `post-quantum` with 10 of 10 seals re-verified; dated record at the end of AIP-21)** | | | [21](./AIP-21.md) | Verifiable Post-Quantum Finality per Block (Side Store, Proof RPC, Anchor as Permanent Record) | Standards Track / Interface (non-consensus) | **Draft, not ratified; first half (retention window + `aere_getPqFinality`) implemented in the Besu-derived client with 7 tests and deployed on testnet 28001 (5 nodes, public door `testnet-rpc.aere.network/finality`) on 2026-09-18; Nethermind port the same day (10 tests) and deployed on the testnet Nethermind validator with its own public door; two-client conformance proven live (`aip21-conformitate/DOVEDESTE.sh`, CONFORM on block 2,250,809); second half (the window on disk, same journal format in both clients) deployed on all six testnet nodes the same day: the window survives a restart in both (1,284 and 1,255 seals re-verified, 0 failed), and a round-1 block is `post-quantum` in both on the same hash (CONFORM 08:49Z, block 2,285,481 and round-1 block 2,285,333); on chain 2800 since 2026-09-22 on all ten validators and both clients (`aere_getPqFinality` answers `post-quantum` with 10 of 10 seals re-verified; dated record at the end of AIP-21)** | |
| [22](./AIP-22.md) | Post-Quantum-Only Finality (Chained Quorum Certificates, PQ Validator Identity, ECDSA Demoted to Compatibility) | Standards Track / Core | **Draft, design only (2026-09-23): nothing implemented or deployed; every quantity carries its provenance or is marked not measured** | | | [22](./AIP-22.md) | Post-Quantum-Only Finality (Chained Quorum Certificates, PQ Validator Identity, ECDSA Demoted to Compatibility) | Standards Track / Core | **Draft, not ratified; a design only on 2026-09-23; stages 1 to 6 then proven on testnet 28001 in both clients (2026-09-23 to 2026-09-25, stage records in the AIP); conformance corpus of all nine kinds published 2026-09-27 (`aip22-conformance/`); not armed on chain 2800 (activation heights are the founder's)** | |
| [23](./AIP-23.md) | AERE Proof Protocol (Portable Verifiable-Statement Envelope with Optional Post-Quantum On-Chain Finality) | Standards Track / Interface | **Draft, not ratified (2026-09-26); reference verifier and conformance vectors published 2026-09-27; finality proven end to end on testnet 28001** | |
Numbers are permanent and are never reused, including for withdrawn proposals Numbers are permanent and are never reused, including for withdrawn proposals
(AIP-1 section 2). Numbering is contiguous from 1 to 22 with no gaps. No AIP (AIP-1 section 2). Numbering is contiguous from 1 to 22 with no gaps. No AIP