The unpublished line of work joins the sanitized public line
The published line and the local line of this repository had no common ancestor: the public one carried the hygiene pass (no host names, no internal paths), the local one carried a month of corrections that never shipped. This commit ports the local work onto the public line, keeping the public hygiene wording wherever the two touched the same sentence, and keeping the public version of AERE-CROSS-CLIENT-DETERMINISM.md entirely. Carried: LICENSE/LICENSING corrections, VERIFY-POLICY.md, CITATIONS-UNRESOLVED.md remeasured 2026-08-11, the 'audited' adjective removed from next to Bouncy Castle, citation paths rewritten to published form, AIP-8, the QA consolidation report, the second EIP validation pass, fork-height corrections, the AereSink / threshold-factory correction, the forge test floor, and the architecture-map updates.
This commit is contained in:
parent
19b13db640
commit
dd1410c266
42
.gitignore
vendored
Normal file
42
.gitignore
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
# aere-docs .gitignore
|
||||
#
|
||||
# This repository is PUBLIC and contains documentation only. It holds no keys,
|
||||
# no node data and no infrastructure detail by design. These rules exist so that
|
||||
# an accidental `git add -A` cannot quietly change that.
|
||||
#
|
||||
# Added 2026-07-20, after a review found this repository had no .gitignore at
|
||||
# all. Nothing was leaking here; this is preventive.
|
||||
|
||||
# ---- Secret-bearing file types. Never commit any of these. ----
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
*.pem
|
||||
*.key
|
||||
*.p12
|
||||
*.pfx
|
||||
*.keystore
|
||||
id_rsa*
|
||||
id_ed25519*
|
||||
*.mnemonic
|
||||
secrets.json
|
||||
nodekey
|
||||
nodekey.pub
|
||||
|
||||
# ---- Compiled Python (a .pyc in a sibling repository leaked a build path) ----
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
# ---- Doc tooling build output ----
|
||||
node_modules/
|
||||
_site/
|
||||
.cache/
|
||||
*.pdf.tmp
|
||||
|
||||
# ---- Editor / OS noise ----
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.idea/
|
||||
.vscode/
|
||||
@ -1,374 +1,271 @@
|
||||
# spec-25: The Aere Improvement Proposal (AIP) Process, Index, and Design-Decision Records
|
||||
# spec-25: The Aere Improvement Proposal (AIP) Process and Index
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Spec | 25 |
|
||||
| Title | The Aere Improvement Proposal (AIP) Process, Index, and Design-Decision Records |
|
||||
| Title | The Aere Improvement Proposal (AIP) Process and Index |
|
||||
| Author | Aere Network Foundation |
|
||||
| Status | For publication |
|
||||
| Created | 2026-07-19 |
|
||||
| Last revised | 2026-07-20 |
|
||||
| Chain | Aere Network, chain ID 2800 |
|
||||
|
||||
## 0. Purpose of this document
|
||||
|
||||
This document does three things.
|
||||
This is the published narrative view of the AIP process and its index. The
|
||||
**canonical** artifacts are in `aerenew/aips/`:
|
||||
|
||||
1. It formalizes the **AIP process**: what an Aere Improvement Proposal is, the lifecycle it moves through, who may propose one, where proposals live, and how they are ratified today.
|
||||
2. It publishes a **canonical index** of every AIP that currently exists in the Aere repositories, with its real number, title, status, and path. It records the real state, including the fact that the process is young and the numbering is short.
|
||||
3. It drafts the **key design-decision records** for load-bearing architecture choices that are not yet captured under a numbered AIP, continuing the real existing numbering.
|
||||
|
||||
The goal is a transparent, numbered, dated record of Aere's reasoning that any auditor, integrator, or automated agent can read and, if they disagree, fork. This is the same intent behind Ethereum's EIP/ERC process and Rust's RFCs. Because it is published, everything in it must be honest.
|
||||
|
||||
### 0.1 Honesty note on community review (read this first)
|
||||
|
||||
An AIP process is worth running from day one, even before an external technical community exists, because its first job is transparent decision documentation: a stable, plain-text home for the motivation, mechanism, on-chain proof, and honest limitations of each change. That value does not depend on anyone commenting.
|
||||
|
||||
The comment and review mechanism defined below is **open**: anyone may author an AIP, raise an issue on one, or fork the record. But it must be stated plainly that Aere has essentially **no external technical community commenting yet**. The network's decentralization is thin (an effective Nakamoto coefficient of about 1, since all validators are Foundation-operated on a single client), and real external usage is thin. Public comment on AIPs becomes meaningful only as an external developer and validator community forms.
|
||||
|
||||
Therefore this document, and the AIPs it indexes, contain **no fabricated community discussion**: no invented "the community debated," no fake review threads, no imagined external participants, and no comment counts. Where an AIP records a decision, it records who actually decided (today, the Foundation) and on what evidence. The review mechanism exists now; organic external comment is expected later, and will be recorded honestly when it happens, not simulated in advance.
|
||||
|
||||
---
|
||||
|
||||
## 1. The process
|
||||
|
||||
### 1.1 What an AIP is
|
||||
|
||||
An AIP (Aere Improvement Proposal) is a design document describing a change to the Aere Network (chain ID 2800), its contracts, its consensus parameters, or its processes. An AIP records the motivation for a change, the exact mechanism, the rationale for the design, and, when the change is already live, the on-chain addresses and transactions that prove it exists. AIPs are Aere's equivalent of Ethereum's EIP/ERC process. They exist so that a reader, human or machine, can reconstruct why the chain works the way it does from a single canonical plain-text source instead of from marketing pages.
|
||||
|
||||
**What belongs in an AIP:** a protocol or consensus change (block time, fee routing, precompiles); a new contract standard or interface other builders integrate against; a token-standard or account-standard convention (ARC); a process or governance change (Meta).
|
||||
|
||||
**What does not belong in an AIP:** bug-fix redeploys that preserve an existing interface (tracked in the SDK address registry's deprecation notes), routine parameter tuning inside an already-ratified bound, and pure documentation.
|
||||
|
||||
### 1.2 Lifecycle
|
||||
|
||||
The normative lifecycle is `Draft -> Review -> Last Call -> Final`. `Living` replaces `Final` for standards that keep evolving (an index, a registry). `Withdrawn` and `Stagnant` are the off-ramps.
|
||||
|
||||
| Status | Meaning |
|
||||
| Artifact | Path |
|
||||
| --- | --- |
|
||||
| Draft | Well-formed, has an author, may still change substantially. |
|
||||
| Review | Author has requested wider scrutiny; open questions are tracked in the AIP. |
|
||||
| Last Call | A stated final-review window (default 14 days). If no blocking issue is raised, it advances. |
|
||||
| Final | Accepted. For shipped work, live on chain 2800. Breaking changes after Final require a new AIP that supersedes it. |
|
||||
| Living | Accepted and expected to keep being updated. |
|
||||
| Withdrawn | Abandoned. Terminal; the number is retired, not reused. |
|
||||
| Stagnant | Inactive in Draft or Review beyond 6 months. Revivable by any author. |
|
||||
| The process, normatively | `aere-research/aips/AIP-1.md` |
|
||||
| The index | `aere-research/aips/README.md` |
|
||||
| The outsider contribution path | `aerenew/aips/CONTRIBUTING.md` |
|
||||
| The required template | `aere-research/aips/aip-template.md` |
|
||||
| Every proposal | `aerenew/aips/AIP-N.md` |
|
||||
|
||||
Retro-filed AIPs (documents written after the change already shipped) enter directly at `Final` or `Living` and state in their Abstract that they backfill history.
|
||||
Where this document and AIP-1 disagree, **AIP-1 wins**. This one exists to
|
||||
explain the process to a reader who is not going to read nineteen files.
|
||||
|
||||
### 1.3 Categories and types
|
||||
### 0.1 What changed on 2026-07-20, and why it mattered
|
||||
|
||||
Types are **Standards Track**, **Meta**, and **Informational**. Informational AIPs give guidance and do not mandate anything. A Standards Track AIP names exactly one category:
|
||||
The revision of 2026-07-19 of this document described a process and published an
|
||||
index. An honest review on 2026-07-20 found that what existed was **a document
|
||||
describing a process rather than a process**, on five specific counts:
|
||||
|
||||
- **Core:** consensus, block production, fee and burn accounting, precompiles, genesis and client configuration.
|
||||
- **Networking:** peer-to-peer protocol and sync.
|
||||
- **Interface:** contract interfaces, ABIs, RPC conventions, verification surfaces.
|
||||
- **ARC** (Aere Request for Comment): application and token standards (ERC-20, ERC-4626, ERC-4337, ERC-6551 conventions as adopted on Aere).
|
||||
1. Nothing had ever moved through the lifecycle. All eight proposals entered
|
||||
directly at Final, Living or Draft; none had occupied Review or Last Call.
|
||||
2. AIP-9 through AIP-16 were published in the index while existing only as
|
||||
sections inside this document. A number that does not resolve to a document is
|
||||
not a record.
|
||||
3. AIP-8 lived outside the AIP directory under a non-conforming filename.
|
||||
4. Two mechanisms the process depends on did not exist: supersession headers, and
|
||||
a rule against editing accepted documents.
|
||||
5. Real, consequential decisions had no number at all: the 1 Gwei base-fee floor
|
||||
live since block 10,141,734, and the EIP-2935 activation deviation.
|
||||
|
||||
Meta and Informational carry no category.
|
||||
All five are now addressed. The process change is recorded as **AIP-19**, which
|
||||
is itself in **Review** and not ratified. AIP-1 revision 2 carries the normative
|
||||
text.
|
||||
|
||||
### 1.4 Roles
|
||||
### 0.2 Honesty note on community review (read this first)
|
||||
|
||||
- **Author.** Anyone may author an AIP. The author writes the document, drives it through the statuses, and answers review questions.
|
||||
- **Editor.** Checks that an AIP is well-formed, correctly numbered and categorized, and technically coherent, and that every cited address, transaction, and number is real. The editor does not judge whether a proposal is a good idea; that is the ratifier's job. Until decentralization, the editor is the Foundation.
|
||||
- **Ratifier.** The party whose approval moves an AIP to Final. Until decentralization this is the Foundation account `0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3`, a single-key, Foundation-controlled account (not a deployed multisig).
|
||||
An AIP process is worth running from day one, even before an external technical
|
||||
community exists, because its first job is transparent decision documentation: a
|
||||
stable, plain-text home for the motivation, mechanism, on-chain proof, and honest
|
||||
limitations of each change. That value does not depend on anyone commenting.
|
||||
|
||||
### 1.5 How to file an AIP
|
||||
The comment and review mechanism is **open**: anyone may author an AIP, raise an
|
||||
issue on one, or fork the record. But Aere has essentially **no external
|
||||
technical community commenting yet**. Decentralization is thin (an effective
|
||||
Nakamoto coefficient of about 1, since all validators are Foundation-operated on
|
||||
a single live client) and real external usage is thin.
|
||||
|
||||
1. Copy the template to `AIP-N.md`, where N is the next free integer.
|
||||
2. Fill in every required section (Preamble, Abstract, Motivation, Specification, Rationale, Backwards Compatibility, Security Considerations, Reference Implementation and On-Chain Deployment, Copyright). A section that does not apply keeps its header with the body "None".
|
||||
3. Cite on-chain addresses verbatim from the canonical SDK registry (`sdk-js/src/addresses.ts`). Never invent an address, transaction hash, or gas number. If a number has not been measured, write "to be measured".
|
||||
4. Add a row to the index.
|
||||
5. Open it for editorial review. Anyone may raise an issue against it. Until decentralization, the editor and ratifier is the Foundation.
|
||||
|
||||
### 1.6 Where AIPs live
|
||||
|
||||
- **Canonical scaffold:** `aerenew/aips/` holds `README.md`, `aip-template.md`, and the retro-filed records AIP-1 through AIP-7. This is the seed of a public AIP repository.
|
||||
- **AIP-8** currently lives as a standalone Draft at `aerenew/docs/AIP-PQ-TX-2026-07-18.md` and has not yet been moved into the `aerenew/aips/` index. This document records that real state; consolidating it into the scaffold index is a housekeeping step.
|
||||
- **Earlier publish-staging copy:** `aere-research-repo/aips/` holds AIP-1 through AIP-6 with an older governance note (it says "three validators" and describes the Foundation account as a "multisig"). It is stale relative to `aerenew/aips/`, which reflects the current reality of seven validators and a single-key Foundation account. The `aerenew/aips/` copy is authoritative where the two differ.
|
||||
|
||||
### 1.7 Sourcing rules (binding on every AIP)
|
||||
|
||||
- Every on-chain address is copied verbatim from the canonical SDK registry. No address is guessed. If unsure, omit it.
|
||||
- Every gas figure, transaction hash, and block number is reproducible from the chain or a repo fixture. Unmeasured quantities are written as "to be measured", never invented.
|
||||
- Design ceilings (for example a theoretical maximum throughput) are never presented as measured throughput.
|
||||
|
||||
### 1.8 Honest governance note and the decentralization path
|
||||
|
||||
Aere is not yet trustlessly governed. Today the network runs seven QBFT validators (f=2, commit quorum 5-of-7) under a single operator, on one client (Hyperledger Besu), with no external security audit and thin real usage. In that reality an AIP is not ratified by an on-chain vote of independent stakeholders. It is **Foundation-ratified**: the Foundation account is the final editor and approver. Every AIP that predates validator and client decentralization carries the label **"Foundation-ratified (pre-decentralization)"** so no reader mistakes editorial ratification for trustless governance.
|
||||
|
||||
The intended migration, each step of which will be its own Meta AIP: (1) open the validator set beyond the current seven Foundation-operated validators and run a second client as a live producer; (2) introduce a public review period the Foundation cannot unilaterally shorten; (3) move ratification to stake-weighted or validator-weighted approval once an independent staker and validator base exists. Until step 3, all Standards Track AIPs carry the pre-decentralization label. The chief risk of a pre-decentralization process, that a single party can both author and ratify, is mitigated only partially today by the editor's sourcing rules and by keeping the honesty label on every proposal; it is fully mitigated only when independent ratifiers exist. This weakness is stated rather than hidden.
|
||||
Therefore this document and the AIPs it indexes contain **no fabricated community
|
||||
discussion**: no invented debate, no fake review threads, no imagined
|
||||
participants, no comment counts. Where an AIP records a decision, it records who
|
||||
actually decided (today, the founder) and on what evidence.
|
||||
|
||||
---
|
||||
|
||||
## 2. Index of existing AIPs (real state)
|
||||
## 1. The process in brief
|
||||
|
||||
The numbering is contiguous from 1 to 8, with no gaps. AIP-1 through AIP-7 are ratified and live in `aerenew/aips/`. AIP-8 is a Draft in `aerenew/docs/`. No AIP numbered 9 or higher exists in any Aere repository as of this writing; the records in Section 3 below are the first drafts of AIP-9 onward.
|
||||
Full normative text: `aere-research/aips/AIP-1.md`. Summary:
|
||||
|
||||
| AIP | Title | Type / Category | Status | Path |
|
||||
**What an AIP is.** A design document describing a change to chain 2800, its
|
||||
contracts, its consensus parameters, or its processes, recording motivation,
|
||||
mechanism, rationale, and, when live, the addresses and transactions that prove
|
||||
it exists.
|
||||
|
||||
**Lifecycle.** `Draft -> Review -> Last Call -> Final`, with `Living` replacing
|
||||
`Final` for documents that keep evolving, and `Withdrawn` and `Stagnant` as
|
||||
off-ramps. AIP-1 section 3 publishes the full table of permitted transitions.
|
||||
There is **no transition out of Final**: a Final AIP changes only by being
|
||||
superseded.
|
||||
|
||||
**Retro-filing.** A document written after the change shipped enters directly at
|
||||
Final or Living and must say so in its Abstract. This is the one sanctioned
|
||||
bypass, and it exists because pretending a shipped change went through review
|
||||
would be a lie.
|
||||
|
||||
**Numbering.** Sequential from 1, assigned at Draft entry, **never reused**,
|
||||
retained through Withdrawn.
|
||||
|
||||
**Supersession.** Paired `Supersedes` and `Superseded-By` headers, so a reader
|
||||
who lands on any AIP can follow `Superseded-By` to the current text. A superseded
|
||||
AIP is never deleted or rewritten: its historical claim stays true.
|
||||
|
||||
**Immutability.** A Final AIP's normative sections are frozen. Corrections are
|
||||
dated **Errata** appended below the original text; results are dated
|
||||
**Post-Acceptance Outcome Records**. Nothing above those headings is edited.
|
||||
|
||||
**Precedent for each mechanism.** Numbering permanence from IETF RFC 2026;
|
||||
transition table from PEP 1's state diagram; supersession from the IETF
|
||||
`Obsoletes` / `Obsoleted by` pair; mandatory sections from EIP-1 and RFC 3552;
|
||||
immutability plus separate errata from the RFC Editor model and from Nygard's
|
||||
Architecture Decision Records. None of it is invented here.
|
||||
|
||||
**Types.** Standards Track (categories Core, Networking, Interface, ARC), Meta,
|
||||
Informational.
|
||||
|
||||
**Roles.** Author (anyone), Editor (checks well-formedness and that every cited
|
||||
number is real; does not judge merit), Ratifier (the founder, today).
|
||||
|
||||
**Sourcing rules.** Addresses verbatim from `sdk-js/src/addresses.ts`; every
|
||||
number labeled **measured**, **spec** or **estimate**; "to be measured" rather
|
||||
than a guess; design ceilings never presented as measured results; and no
|
||||
document claims post-quantum consensus.
|
||||
|
||||
---
|
||||
|
||||
## 2. Index
|
||||
|
||||
The canonical index with status and supersession columns is
|
||||
`aere-research/aips/README.md`. Numbering is contiguous from 1 to 19 with no gaps; no
|
||||
AIP numbered 20 or higher exists in any Aere repository.
|
||||
|
||||
| AIP | Title | Type / Category | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | AIP Purpose and Process | Meta | Living (rev 2) |
|
||||
| 2 | Coinbase Fee-Burn Routing (37.5%) | Standards Track / Core | Final |
|
||||
| 3 | Sub-Second Block Period (500 ms QBFT) | Standards Track / Core | Final |
|
||||
| 4 | On-Chain Post-Quantum Signature Verification Suite | Standards Track / Interface | Final |
|
||||
| 5 | sAERE Receipt Token and AereSink Immutable Flywheel | Standards Track / ARC | Final |
|
||||
| 6 | ERC-4337 Passkey and Gasless Onboarding Stack | Standards Track / ARC | Final |
|
||||
| 7 | AerePQC Hard-Fork Activation | Standards Track / Core | Final |
|
||||
| 8 | Post-Quantum-Authorized Transaction Envelope (Type 0x2A) | Standards Track / Core | Draft, not live |
|
||||
| 9 | Consensus Mechanism: QBFT, not HotStuff | Informational | Final |
|
||||
| 10 | Execution Client: Forked Besu, Nethermind second, not Reth | Informational | Final |
|
||||
| 11 | Interoperability: Hyperlane-compatible plus zk light clients, not IBC | Informational | Final |
|
||||
| 12 | The Virtual Machine: Extend the EVM, not a New VM | Informational | Final |
|
||||
| 13 | Post-Quantum Signatures: Falcon and ML-DSA Together | Informational | Final |
|
||||
| 14 | Account Abstraction: ERC-4337 with EIP-7702 Bridge | Informational | Final |
|
||||
| 15 | In-Place Hybrid PQC Consensus Activation, not Re-Genesis | Standards Track / Core | Draft, testnet R&D |
|
||||
| 16 | PQ STARK-Verify Precompile (0x0AE8) | Standards Track / Core | Draft, skeleton |
|
||||
| 17 | One-Gwei EIP-1559 Base-Fee Floor | Standards Track / Core | Final |
|
||||
| 18 | EIP-2935 on Chain 2800: Deviation from the Written Activation Schedule | Standards Track / Core | Final |
|
||||
| 19 | AIP Process Hardening | Meta | Review, not ratified |
|
||||
|
||||
Every one of these is a file at `aerenew/aips/AIP-N.md`.
|
||||
|
||||
### 2.1 What is actually live on chain 2800
|
||||
|
||||
**Live:** AIP-2, AIP-3, AIP-4, AIP-5, AIP-6, AIP-7, AIP-17, AIP-18. AIP-9 through
|
||||
AIP-14 record the decisions behind the live system.
|
||||
|
||||
**Not live:** AIP-8 (requires a coordinated hard fork), AIP-15 (isolated testnet
|
||||
only, chain ID 440855), AIP-16 (a fail-closed skeleton that verifies nothing),
|
||||
AIP-19 (a process change in Review).
|
||||
|
||||
**Boundaries that must not be blurred in any Aere document:**
|
||||
|
||||
- Consensus on chain 2800 is **classical secp256k1 ECDSA QBFT** at N = 7. Aere
|
||||
never claims post-quantum consensus. Post-quantum applies to signatures,
|
||||
accounts and applications.
|
||||
- Mainnet has **exactly five** PQC precompiles, `0x0AE1` to `0x0AE5`, from block
|
||||
9,189,161. `0x0AE6` and `0x0AE7` are **testnet-only** (confirmed 2026-07-20 by a
|
||||
gas-differential probe against a no-code control). `0x0AE8` is not activated
|
||||
anywhere.
|
||||
- The Aere burn is a cut of the **validator coinbase reward**, not a base-fee
|
||||
burn. Coinbase revenue is zero and lifetime burn is 0.1374 AERE, so **AERE is
|
||||
not deflationary today** (AIP-2 outcome record). The separate 1 Gwei base-fee
|
||||
**floor** (AIP-17) sets a minimum price and removes no supply.
|
||||
- The block period is a 500 ms **target**; the **measured** mean interval is
|
||||
516.4 ms (AIP-3 outcome record).
|
||||
|
||||
### 2.2 Coverage of the engineering-spec design decisions
|
||||
|
||||
`aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md` Section 4 enumerates the
|
||||
load-bearing design decisions. All now have a numbered record.
|
||||
|
||||
| Section 4 decision | Record |
|
||||
| --- | --- |
|
||||
| 4.1 Consensus: QBFT, not HotStuff | AIP-9 |
|
||||
| 4.2 Execution client: forked Besu with Nethermind second, not Reth | AIP-10 |
|
||||
| 4.3 Interoperability: Hyperlane-compatible plus zk light clients, not IBC | AIP-11 |
|
||||
| 4.4 Post-quantum signatures: Falcon and ML-DSA together | AIP-13 (mechanism in AIP-4, AIP-7) |
|
||||
| 4.5 Account abstraction: ERC-4337 with EIP-7702 bridge | AIP-14 (stack in AIP-6) |
|
||||
| 4.6 Virtual machine: extend the EVM, not a new VM | AIP-12 |
|
||||
| 4.7 The burn: validator-reward cut, not a base-fee burn | AIP-2 |
|
||||
| PQC precompile activation | AIP-7 |
|
||||
| Base-fee floor | AIP-17 |
|
||||
| EIP-2935 activation deviation | AIP-18 |
|
||||
| In-place hybrid PQC consensus activation (R&D, not live) | AIP-15 |
|
||||
| PQ STARK-verify precompile 0x0AE8 (skeleton, not live) | AIP-16 |
|
||||
|
||||
### 2.3 Open EIP/ERC drafts (external standards, not AIPs)
|
||||
|
||||
Separately from the internal AIP numbering, Aere maintains drafts of **open,
|
||||
externally-submittable Ethereum standards** for the primitives judged genuinely
|
||||
novel and worth standardizing beyond Aere. The strategy is to conform to existing
|
||||
open standards wherever they exist and to propose only the genuinely new
|
||||
primitives, as open (CC0) standards, never as a closed Aere-only standard. These
|
||||
live in `aerenew/eips/` (index: `aerenew/eips/README.md`) and target the upstream
|
||||
`ethereum/EIPs`, `ethereum/ERCs`, or the RIP (RollCall) process. Each is
|
||||
**Status: Draft**: formatted as submittable, but not yet submitted to or accepted
|
||||
by the upstream editors, and carrying no assigned EIP number.
|
||||
|
||||
They are distinct from AIPs: an AIP records why chain 2800 works the way it does
|
||||
with its live addresses; an open EIP draft is the chain-agnostic version a third
|
||||
party could implement.
|
||||
|
||||
| Open draft | File | Type / Category | Status | Maps to AIP |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 1 | AIP Purpose and Process | Meta | Living | `aerenew/aips/AIP-1.md` |
|
||||
| 2 | Coinbase Fee-Burn Routing (37.5%) | Standards Track / Core | Final | `aerenew/aips/AIP-2.md` |
|
||||
| 3 | Sub-Second Block Period (500 ms QBFT) | Standards Track / Core | Final | `aerenew/aips/AIP-3.md` |
|
||||
| 4 | On-Chain Post-Quantum Signature Verification Suite | Standards Track / Interface | Final | `aerenew/aips/AIP-4.md` |
|
||||
| 5 | sAERE Receipt Token and AereSink Immutable Flywheel | Standards Track / ARC | Final | `aerenew/aips/AIP-5.md` |
|
||||
| 6 | ERC-4337 Passkey and Gasless Onboarding Stack | Standards Track / ARC | Final | `aerenew/aips/AIP-6.md` |
|
||||
| 7 | AerePQC Hard-Fork Activation (Native PQC Precompiles and Extended EIP-2935 Lookback) | Standards Track / Core | Final | `aerenew/aips/AIP-7.md` |
|
||||
| 8 | Post-Quantum-Authorized Transaction Envelope (EIP-2718 Type 0x2A) | Standards Track / Core | Draft (not live) | `aerenew/docs/AIP-PQ-TX-2026-07-18.md` |
|
||||
| Native NIST PQC signature-verification precompiles | `aerenew/eips/eip-draft-pqc-signature-precompiles.md` | Standards Track / Core (filable as RIP) | Draft | AIP-4, AIP-7 |
|
||||
| SHAKE256 extendable-output-function precompile | `aerenew/eips/eip-draft-shake256-precompile.md` | Standards Track / Core (filable as RIP) | Draft | AIP-7 |
|
||||
| Post-quantum account and mandate authorization | `aerenew/eips/eip-draft-pqc-account-authorization.md` | Standards Track / ERC | Draft | AIP-4, AIP-14 |
|
||||
|
||||
Notes on real state:
|
||||
|
||||
- AIP-1 through AIP-7 are Foundation-ratified (pre-decentralization). AIP-2 through AIP-7 are retro-filed records of changes already live on chain 2800; AIP-1 is the process document itself.
|
||||
- AIP-8 is a genuine Draft: it specifies a base-layer post-quantum transaction type that requires a coordinated Besu hard fork and is **not deployed**. It ships with a deploy-today ERC-4337 reference path (`AerePQCTxAccount.sol`) that needs no fork.
|
||||
- The mechanism specification behind AIP-7 also exists as `aerenew/research/aip-draft-pqc-precompiles.md` (frontmatter `aip: TBD`, marked SHIPPED); it is the design/gas spec, canonically recorded as AIP-7. It is not a separate AIP number.
|
||||
- A duplicate AIP-1 through AIP-6 set exists under `aere-research-repo/aips/`; it is an older copy and is superseded by `aerenew/aips/` where the two disagree (see 1.6).
|
||||
|
||||
### 2.1 Coverage map: which section-4 decisions already have a record
|
||||
|
||||
The engineering rationale in `aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md` Section 4 enumerates the load-bearing design decisions. Several already have a numbered AIP; the rest are drafted in Section 3.
|
||||
|
||||
| Section 4 decision | Captured by | New record needed |
|
||||
| --- | --- | --- |
|
||||
| 4.1 Consensus: QBFT, not HotStuff | (none) | Yes -> AIP-9 |
|
||||
| 4.2 Execution client: forked Besu with Nethermind second, not Reth | (none) | Yes -> AIP-10 |
|
||||
| 4.3 Interoperability: Hyperlane-compatible plus zk light clients, not IBC | (none) | Yes -> AIP-11 |
|
||||
| 4.6 Virtual machine: extend the EVM, not a new VM | (none) | Yes -> AIP-12 |
|
||||
| 4.4 Post-quantum signatures: Falcon and ML-DSA together, not one lattice family | AIP-4, AIP-7 (mechanism) | Yes, as a distinct decision record -> AIP-13 |
|
||||
| 4.5 Account abstraction: ERC-4337 with EIP-7702 bridge, not native AA | AIP-6 (stack) | Yes, as a distinct decision record -> AIP-14 |
|
||||
| 4.7 The burn: validator-reward cut, not a base-fee burn | AIP-2 (mechanism and rationale) | No; already recorded in AIP-2 |
|
||||
| PQC precompile activation | AIP-7 | No; already recorded in AIP-7 |
|
||||
| In-place hybrid PQC consensus activation (R&D, not live) | (none) | Yes -> AIP-15 |
|
||||
| PQ STARK-verify precompile 0x0AE8 (skeleton, not live) | (none) | Yes -> AIP-16 |
|
||||
The precompile drafts generalize the primitive shipped on chain 2800 at `0x0AE1`
|
||||
to `0x0AE5` (block 9,189,161, recorded as AIP-7); the account and mandate ERC
|
||||
draft generalizes the account primitives recorded in AIP-4. Gas figures in all
|
||||
three are cited from `aerenew/docs/AERE-BENCHMARK-REPORT.md`. None of these
|
||||
drafts touches consensus.
|
||||
|
||||
---
|
||||
|
||||
## 3. Design-decision records drafted here (AIP-9 to AIP-16)
|
||||
## 3. Governance, stated plainly
|
||||
|
||||
These are the first drafts of the records that continue the real numbering after AIP-8. AIP-9 through AIP-14 document architecture decisions that are already live and settled, so they enter at Final as Informational records (they explain rationale for a shipped choice rather than mandate a new normative change). AIP-15 and AIP-16 document research and blocked work that is **not live on chain 2800**, so they enter at Draft. Each record is deliberately concise: context, decision, rationale, alternatives rejected, and status. The normative mechanism for a decision that also has a Standards Track AIP (AIP-13 references AIP-4/AIP-7; AIP-14 references AIP-6) stays in that AIP; the record here captures the decision framing.
|
||||
Aere is not yet trustlessly governed. Seven QBFT validators (f = 2, commit quorum
|
||||
5-of-7) under a single operator, one live client (Hyperledger Besu), no external
|
||||
security audit, thin real usage. In that reality an AIP is not ratified by an
|
||||
on-chain vote of independent stakeholders. **The founder decides**, acting through
|
||||
the Foundation account `0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3`, which is a
|
||||
**single-key account and not a deployed multisig**.
|
||||
|
||||
The post-quantum scope boundary holds throughout: **Aere consensus is classical secp256k1 ECDSA QBFT.** Post-quantum applies to signatures, accounts, and applications only. No record here claims post-quantum consensus.
|
||||
A Governor, Timelock and governance token are deployed on chain 2800 and
|
||||
**control nothing**: no production contract is owned by a timelock. They are inert
|
||||
infrastructure for a future in which they hold authority. Their existence is not
|
||||
a claim that Aere has on-chain governance.
|
||||
|
||||
Every AIP that predates validator and client decentralization carries the label
|
||||
**"Foundation-ratified (pre-decentralization)"** so no reader mistakes editorial
|
||||
ratification for trustless governance.
|
||||
|
||||
The intended migration, each step its own Meta AIP: (1) open the validator set
|
||||
beyond the current seven Foundation-operated validators and run a second client
|
||||
as a live producer; (2) introduce a public review period the Foundation cannot
|
||||
unilaterally shorten; (3) move ratification to stake-weighted or
|
||||
validator-weighted approval once an independent staker and validator base exists.
|
||||
|
||||
The chief risk of a pre-decentralization process, that a single party can both
|
||||
author and ratify, is mitigated only partially today, by the editor's sourcing
|
||||
rules and by the immutability rule that makes a false claim dated, attributed and
|
||||
hard to erase quietly. It is fully mitigated only when independent ratifiers
|
||||
exist. This weakness is stated rather than hidden.
|
||||
|
||||
For what this means to an outside contributor, see
|
||||
`aerenew/aips/CONTRIBUTING.md`.
|
||||
|
||||
---
|
||||
|
||||
### AIP-9: Consensus Mechanism: QBFT, not HotStuff
|
||||
## 4. Relationship to the whitepaper
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 9 |
|
||||
| Title | Consensus Mechanism: QBFT, not HotStuff |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Informational |
|
||||
| Status | Final |
|
||||
| Created | 2026-07-19 |
|
||||
| Ratification | Foundation-ratified (pre-decentralization) |
|
||||
|
||||
**Context.** Aere is a settlement layer whose core promise is deterministic, single-slot finality at a sub-second cadence. It runs a small, permissioned validator set: seven validators today, with a roadmap target in the 9 to 21 range.
|
||||
|
||||
**Decision.** Use QBFT, the Byzantine-fault-tolerant IBFT-family protocol as implemented in Hyperledger Besu, producing deterministic single-block finality at a target block time of about 0.5 s. At N=7, QBFT tolerates f=2 Byzantine or crashed validators with a commit quorum of 2f+1 = 5-of-7.
|
||||
|
||||
**Rationale.** At Aere's validator-set size, QBFT's O(N^2) message complexity is negligible in absolute terms (a 5-of-7 quorum verify costs on the order of a few milliseconds per block, a small fraction of the 500 ms slot). Against that non-cost, QBFT gives three concrete advantages: deterministic instant single-block finality (the exact settlement guarantee the network sells), maturity and existing integration in Besu (no new-protocol implementation risk), and the fact that Aere's post-quantum consensus research, second-client work, and zk finality proofs are all built against QBFT.
|
||||
|
||||
**Alternatives rejected.** HotStuff and its pipelined variants, whose linear per-round communication complexity is engineered to scale BFT to hundreds of validators. That scaling regime is one Aere does not operate in and does not plan to enter under this design, so HotStuff's headline benefit is unavailable, while adopting it would add the risk and integration cost of a protocol less battle-tested in the chosen client.
|
||||
|
||||
**Honest limitation.** At N=7 the fault tolerance against node outages is real, but all validators are Foundation-operated. Decentralization, not the consensus mechanism, is the binding trust assumption. The block-period choice (500 ms) is documented separately in AIP-3.
|
||||
|
||||
**Status.** Final. Live on chain 2800.
|
||||
Every substantive change to the whitepaper should cite the AIP that authorized
|
||||
it, so the version history explains itself rather than recording only that
|
||||
something moved. The rule and its mechanics are specified in
|
||||
`aerenew/docs/AERE-WHITEPAPER-AIP-LINKAGE.md`.
|
||||
|
||||
---
|
||||
|
||||
### AIP-10: Execution Client: Forked Besu with Nethermind as the Second Client, not Reth
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 10 |
|
||||
| Title | Execution Client: Forked Besu with Nethermind as the Second Client, not Reth |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Informational |
|
||||
| Status | Final |
|
||||
| Created | 2026-07-19 |
|
||||
| Ratification | Foundation-ratified (pre-decentralization) |
|
||||
|
||||
**Context.** A production chain needs a producing client and, to retire single-implementation risk, a second independent client. Aere already ships QBFT, which is Besu-specific: no off-the-shelf Geth, Reth, Erigon, or stock Nethermind produces QBFT-compatible blocks.
|
||||
|
||||
**Decision.** A fork of Hyperledger Besu v26.4.0 (Java, base commit d2032017, JDK 21 toolchain) is the sole live mainnet producer. The fork adds the native post-quantum precompiles and extended EIP-2935 lookback (live since block 9,189,161, AIP-7) and the 1-Gwei base-fee floor (live since block 10,141,734). A patched Nethermind 1.39.0 (.NET) is the second, independent client.
|
||||
|
||||
**Rationale.** Besu already carries QBFT and already carries the codebase into which the PQC precompile fork and base-fee changes were integrated. Nethermind was chosen as the second client specifically for implementation diversity: a different codebase in a different language (.NET versus Java), so a consensus-relevant bug in one is unlikely to exist in the other. The patched Nethermind validates the live chain, runs the five PQC precompiles byte-for-byte identically (27 of 27 NIST KAT vectors), and, on an isolated test network, produces byte-identical QBFT blocks that stock Besu accepts through full BFT validation (with a one-byte-tampered seal rejected).
|
||||
|
||||
**Alternatives rejected.** Reth (Rust) as the base client: it has no notion of QBFT, so it would require building QBFT production into a client that lacks it before producing a single block; and the September 2025 Reth halt is the reference case for why depending on one producing implementation is a systemic risk. A second Besu instance instead of Nethermind: that is not client diversity, since it shares every bug with the first.
|
||||
|
||||
**Honest limitation.** Cross-client production is proven on an isolated testnet (offline import and, later, live devp2p between test nodes), and a listen-only Nethermind follower has run against the live network. Nethermind is **not yet a live gossiping producer on chain 2800**. Besu remains the sole live producer; the second client is a client-diversity cross-check and fail-safe today, not a second live validator. Making Nethermind a live producer is a founder-supervised change, because a producer bug on a live chain can halt or fork it.
|
||||
|
||||
**Status.** Final (as the decision and the current live topology). Live producer: Besu only.
|
||||
|
||||
---
|
||||
|
||||
### AIP-11: Interoperability: Hyperlane-Compatible Messaging plus zk Light Clients, not IBC
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 11 |
|
||||
| Title | Interoperability: Hyperlane-Compatible Messaging plus zk Light Clients, not IBC |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Informational |
|
||||
| Status | Final |
|
||||
| Created | 2026-07-19 |
|
||||
| Ratification | Foundation-ratified (pre-decentralization) |
|
||||
|
||||
**Context.** Aere's value proposition is that it is an ordinary EVM chain. Cross-chain interop must serve permissionless, EVM-familiar builders while also offering trust-minimized verification of a counterparty's finality.
|
||||
|
||||
**Decision.** An EVM-native, Hyperlane-compatible messaging layer (a Mailbox-compatible `AereMessenger`, an interchain gas paymaster `AereIGP`), an ERC-7683 intent layer, and an Across-v3-compatible spoke pool. Alongside it, a zero-knowledge interop path: on-chain zk light clients that verify a counterparty's consensus finality (inbound Ethereum sync-committee finality, outbound Aere QBFT finality) from inside a contract, via SP1 Groth16 proofs.
|
||||
|
||||
**Rationale.** IBC's design philosophy, verifying the counterparty's consensus rather than trusting a bridge committee, is the right one, and Aere adopts it directly. Aere splits the problem: for permissionless developer-familiar interop it uses the Hyperlane-compatible interfaces the EVM tooling ecosystem already speaks; for the trust-minimization that is IBC's real contribution it built the zk light clients, which capture "verify the counterparty's consensus, do not trust a relayer" without leaving the EVM world.
|
||||
|
||||
**Alternatives rejected.** IBC as a protocol: it is built around Tendermint-style light clients and a non-EVM connection, channel, and packet model. Adopting it natively would import a substantial non-EVM stack and its tooling into a chain whose entire premise is that it is an ordinary EVM.
|
||||
|
||||
**Honest limitation.** The Hyperlane-compatible endpoints are interface-faithful and deployed, but a live decentralized relayer and interchain-security-module network is not yet stood up (the current bridge path runs through a single Foundation signer with a relayer pending). The zk light clients are trust-minimized, not trustless, and not quantum-safe: their committed seals are classical secp256k1 and the proof wrap is Groth16 over BN254 (Shor-breakable).
|
||||
|
||||
**Status.** Final (as the decision). Deployed interfaces; decentralized relayer pending.
|
||||
|
||||
---
|
||||
|
||||
### AIP-12: The Virtual Machine: Extend the EVM, not a New VM
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 12 |
|
||||
| Title | The Virtual Machine: Extend the EVM, not a New VM |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Informational |
|
||||
| Status | Final |
|
||||
| Created | 2026-07-19 |
|
||||
| Ratification | Foundation-ratified (pre-decentralization) |
|
||||
|
||||
**Context.** Aere differentiates on post-quantum verification, parallel execution, and extended block-hash lookback. It must add these without taxing the developer surface it depends on.
|
||||
|
||||
**Decision.** Keep the EVM. Solidity, EVM bytecode, JSON-RPC, and the developer tooling are unchanged. Differentiation is added as precompiles and client-fork rules at otherwise-empty reserved addresses, not as a new instruction set or a new language, and activated by client-only forks in the same manner Ethereum activates its own hard forks.
|
||||
|
||||
**Rationale.** A mature VM has years of implementation hardening, a known cost model, and an operational history; a new VM starts that clock at zero, maximizing technical and adoption risk. The EVM is the single largest smart-contract developer surface in existence, and every deviation (a nonstandard opcode, account model, or RPC) is a tax on every developer and tool. Aere's thesis is settlement, not a novel programming model, so the design keeps the tested execution environment intact and adds differentiation only at the EVM's standard extension points (precompiles at reserved addresses). Nothing about Aere's account, passkey, or post-quantum surface depends on a nonstandard EVM.
|
||||
|
||||
**Alternatives rejected.** Designing a new, purpose-built VM (a new bytecode, language, or non-EVM environment) optimized around Aere's differentiators.
|
||||
|
||||
**Honest limitation.** Some ambitions (base-layer parallel execution, an EVM-in-a-zkVM) must be reached inside the existing model rather than designed in from scratch. Those remain roadmap and are labeled as such.
|
||||
|
||||
**Status.** Final. Live on chain 2800.
|
||||
|
||||
---
|
||||
|
||||
### AIP-13: Post-Quantum Signatures: Falcon and ML-DSA Together, not a Single Lattice Family
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 13 |
|
||||
| Title | Post-Quantum Signatures: Falcon and ML-DSA Together, not a Single Lattice Family |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Informational |
|
||||
| Status | Final |
|
||||
| Created | 2026-07-19 |
|
||||
| Requires | 4, 7 |
|
||||
| Ratification | Foundation-ratified (pre-decentralization) |
|
||||
|
||||
**Context.** Aere verifies post-quantum signatures on-chain at both the contract layer (AIP-4) and, since block 9,189,161, the native precompile layer (AIP-7). A choice of scheme family is a bet on a mathematical assumption.
|
||||
|
||||
**Decision.** Support multiple post-quantum signature schemes across two distinct lattice families, Falcon (Falcon-512 and Falcon-1024) and ML-DSA (Dilithium2 / ML-DSA-44), alongside hash-based schemes (SLH-DSA, XMSS, WOTS+). The live precompiles for SHAKE256, Falcon-512, Falcon-1024, ML-DSA-44, and SLH-DSA-SHA2-128s occupy the 0x0AE1 to 0x0AE5 band.
|
||||
|
||||
**Rationale.** Cryptographic-risk diversification. Falcon rests on NTRU lattices; ML-DSA rests on module lattices with Fiat-Shamir-with-aborts. Supporting both means a cryptanalytic break or a standardization flaw in one lattice family does not, by itself, remove Aere's ability to verify post-quantum signatures: accounts and settlement authorization can migrate to the surviving family. This mirrors the hybrid `AereHybridAuth` account, which requires both a classical ECDSA and a Falcon-512 signature so that neither a broken curve nor a broken lattice alone suffices to forge.
|
||||
|
||||
**Alternatives rejected.** Standardizing on a single lattice scheme (ML-DSA alone as the NIST primary, or Falcon alone for its compact signatures). The cost of supporting several schemes is more verifier surface to implement, validate, and eventually audit; that cost is accepted deliberately rather than betting the network's post-quantum future on a single assumption.
|
||||
|
||||
**Scope boundary (binding).** This is post-quantum at the signature, account, and application layer only. Consensus remains classical (validators sign secp256k1 QBFT), and the zk verification is classical (BN254 Groth16, Shor-breakable). Aere never claims post-quantum consensus.
|
||||
|
||||
**Honest limitation.** The verifiers and precompiles carry an internal self-audit only; an external audit is pending before they should secure material value. Their assurance today rests on bit-for-bit agreement with official NIST KAT and ACVP vectors and cross-checks against independent reimplementations.
|
||||
|
||||
**Status.** Final. Precompiles live on chain 2800; the normative mechanism is in AIP-4 (contract suite) and AIP-7 (precompile activation).
|
||||
|
||||
---
|
||||
|
||||
### AIP-14: Account Abstraction: ERC-4337 with EIP-7702 Bridge, not Native AA
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 14 |
|
||||
| Title | Account Abstraction: ERC-4337 with EIP-7702 Bridge, not Native AA |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Informational |
|
||||
| Status | Final |
|
||||
| Created | 2026-07-19 |
|
||||
| Requires | 6 |
|
||||
| Ratification | Foundation-ratified (pre-decentralization) |
|
||||
|
||||
**Context.** Aere wants programmable accounts (recovery, passkey ownership, post-quantum ownership, gas sponsorship) without breaking EVM and EOA compatibility.
|
||||
|
||||
**Decision.** ERC-4337 (v0.7) smart accounts as the account-abstraction path, with EIP-7702 (live under the Pectra ruleset) as the migration bridge that lets existing externally-owned accounts (EOAs) delegate to smart-account code.
|
||||
|
||||
**Rationale.** ERC-4337 needs no consensus change, is an established standard with an existing bundler and tooling ecosystem, and delivers programmable accounts (including the Falcon-owned post-quantum smart account `AerePQCAccountFactory`) without touching the protocol, preserving exact EVM and Ethereum compatibility. EIP-7702 is the chosen bridge precisely because it upgrades existing EOAs in place without forcing a disruptive "everything is a contract" change.
|
||||
|
||||
**Alternatives rejected.** Native, protocol-level account abstraction up to an "all accounts are smart accounts by default" end-state: it changes what an account fundamentally is, breaking existing tooling, contracts, and user keys. EIP-3074, an earlier EOA-empowerment proposal: it was superseded by EIP-7702, which is the mechanism Aere carries; Aere does not implement EIP-3074.
|
||||
|
||||
**Honest limitation.** The EntryPoints are Aere's own ERC-4337-compatible implementations, compatible in shape and interface but not byte-identical to Ethereum's canonical audited singleton; integrators should treat them as Aere-specific. Gasless onboarding is subsidized (Foundation-funded, rate-limited), not free. These contracts have not had an external audit.
|
||||
|
||||
**Status.** Final. Live on chain 2800; the normative stack (accounts, factories, paymasters, EntryPoints) is in AIP-6.
|
||||
|
||||
---
|
||||
|
||||
### AIP-15: In-Place Hybrid PQC Consensus Activation via On-Chain Anchor Contract, not Re-Genesis
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 15 |
|
||||
| Title | In-Place Hybrid PQC Consensus Activation via On-Chain Anchor Contract, not Re-Genesis |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Standards Track |
|
||||
| Category | Core |
|
||||
| Status | Draft (isolated-testnet R&D; not live on chain 2800) |
|
||||
| Created | 2026-07-19 |
|
||||
| Ratification | Not ratified; external-audit and founder gated |
|
||||
|
||||
**Context.** Aere's hybrid consensus research (Stage 1 and Stage 2) proved a gossiped, blocking Falcon-512 quorum certificate that runs alongside the ECDSA committed-seal quorum, empirically at N=4 (2 s) and N=7 (0.5 s). Its Falcon registry, however, was bound to chain identity at genesis (folding `keccak256(manifest)` into the genesis state root). Chain 2800 launched long before any Falcon manifest existed, so blocking activation was previously recorded as "requires a re-genesis," a non-starter for a live chain because re-genesis destroys history and chain identity.
|
||||
|
||||
**Decision.** Bind the Falcon manifest to on-chain state **post-genesis**, via a minimal, immutable, ownerless anchor contract deployed by one ordinary transaction at an activation height. The contract commits `keccak256(manifest)` to storage slot 0 (its runtime code is a single STOP byte; it is never callable and has no admin). On every block import the validation rule resolves the manifest from the **parent block's world state** at the anchor address and activates the pending registry only if the observed hash matches, failing closed on any mismatch. The re-genesis requirement is removed.
|
||||
|
||||
**Rationale.** The late anchor folds `keccak256(manifest)` into every block hash from the deployment block onward, so two nodes that agree on the chain past that block necessarily agree on the anchored hash: the same integrity guarantee the genesis ceremony gave, minus the re-genesis. The deploy address is deterministic (`keccak256(rlp[deployer, nonce])[12:]`), so validators can be pre-configured before deployment, and activation is idempotent and retried each block, so deploy-then-configure and configure-then-deploy both converge.
|
||||
|
||||
**Alternatives rejected.** Re-genesis carrying a Falcon anchor in genesis alloc (destroys history and chain identity). A shared per-node manifest file with no on-chain root (a node with a tampered manifest could join silently; the on-chain anchor makes it fail closed instead).
|
||||
|
||||
**Evidence and honest scope.** Proven end-to-end on an **isolated N=4 @ 0.5 s testnet** (chainId 440855) whose genesis is byte-shape-identical to a classical ECDSA-only chain: classical start, deploy anchor at block 16, activate from the contract at block 17, flip to blocking at fork block 150, with 0 forks, 0.5 s cadence maintained, pre-activation blocks still valid, a post-activation sub-quorum block rejected (chain halts), and recovery in place with no re-genesis. **Nothing here is live on chain 2800.** Chain 2800 consensus remains classical secp256k1 ECDSA QBFT at N=7, with no Falcon layer of any kind in its headers. The hybrid can only shrink the committable set, so it is never worse than the ECDSA-only chain; ECDSA committed seals remain the decisive safety and liveness seal.
|
||||
|
||||
**Remaining gates to a live flip.** No longer a gate: re-genesis. Still required: an external audit of the Falcon consensus patch (quorum, gossip, assembly, late-anchor Java) and of BouncyCastle Falcon-512 on the consensus path; finalizing the full target validator set (N >= 9 recommended, since N=7 blocking has a zero two-fault margin) with an address-bound manifest re-anchored for the full set; a live isolated N=7 (ideally N=9) soak of the combined activation; and an explicit founder GO. No agent activates blocking consensus on chain 2800.
|
||||
|
||||
**Status.** Draft. Reference patch: `aerenew/consensus-pqc/besu-consensus-pqc-fork-activation.patch` with evidence under `aerenew/consensus-pqc/inplace-activation-evidence/`.
|
||||
|
||||
---
|
||||
|
||||
### AIP-16: PQ STARK-Verify Precompile (0x0AE8)
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| AIP | 16 |
|
||||
| Title | PQ STARK-Verify Precompile (0x0AE8) |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Standards Track |
|
||||
| Category | Core |
|
||||
| Status | Draft (reference skeleton; verifies nothing; not live on any Aere network) |
|
||||
| Created | 2026-07-19 |
|
||||
| Ratification | Not ratified; prerequisite-gated, external-audit gated, founder gated |
|
||||
|
||||
**Context.** Aere's zk interop and validity paths currently wrap proofs as Groth16 over BN254, which is classical and Shor-breakable. A post-quantum-sound proof system (a FRI-based STARK, hash-commitment only, no pairing) would remove that assumption. A native precompile is the natural home for STARK verification, matching the same reasoning used for the PQC signature precompiles in AIP-7.
|
||||
|
||||
**Decision.** Reserve precompile address 0x0AE8 for a PQ STARK-verify precompile that verifies a hash-based STARK directly on-chain (removing a BN254 pairing check). It is specified to activate under a new, forward-dated milestone (PQ-3), never folded into an already-crossed milestone, so that pre-activation history is byte-identical on old and new binaries and the upgrade itself carries no fork risk.
|
||||
|
||||
**Scope caveat (2026-07-19 research finding).** An earlier draft described this as verifying "an SP1 inner-STARK (FRI over a Poseidon2 commitment)". That is corrected: the verifier skeleton built so far is a BabyBear + FRI STARK verifier, conformance-confirmed against Plonky3 `0.4.3-succinct`, which targets Aere's OWN Plonky3 circuits, NOT SP1 6.1.0. The pinned SP1 6.1.0 is a Hypercube release (KoalaBear multilinear: BaseFold plus sumcheck-zerocheck plus LogUp-GKR), so FRI does not apply to it and this skeleton does not verify SP1 6.1.0 proofs; retargeting 0x0AE8 to the SP1 Hypercube stack is a separate ~22 to 32 person-week effort. See `AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md`.
|
||||
|
||||
**Rationale.** A forward-dated, non-retroactive milestone plus a rolling binary upgrade (the same zero-liveness-risk posture proven for the base-fee floor and the in-place activation) means the address stays an empty account, and every consumer adapter fails closed, until the announced activation time. A migrated consumer can keep both the new 0x0AE8 path and the existing BN254 gateway required during a defense-in-depth window before dropping the classical path.
|
||||
|
||||
**Alternatives rejected.** Folding 0x0AE8 into the crossed `futureEipsTime` milestone (block 9,189,161): every historical block that called the currently-empty address would re-execute with different return data on the upgraded binary, a state divergence and a consensus split. Presenting the current artifact as a working verifier: it is not one.
|
||||
|
||||
**Honest scope (critical).** This is the record's load-bearing honesty statement. **0x0AE8 is not activated on any Aere network. As of this date it is a reference skeleton that fail-closes (returns EMPTY for every input): it is not a working verifier and must not be presented as one.** Mainnet 2800 has exactly five PQC precompiles (0x0AE1 to 0x0AE5, block 9,189,161). The sibling ML-KEM-768 (0x0AE6) and Falcon HashToPoint (0x0AE7) precompiles are testnet-only. `AerePQStarkVerifier.sol` is a fail-closed adapter that denies every proof (safe by construction). Consensus is untouched by all of this; it remains classical ECDSA QBFT.
|
||||
|
||||
**Prerequisite and gates.** Activation cannot begin until the crypto core is ported from maintained references (Plonky3 FRI/Poseidon2/uni-stark, SP1 stark) or a pinned native wrap is built and reproducible; a real SP1 v6.1.0 inner-STARK vector corpus exists and the precompile accepts every valid vector and rejects every tampered or wrong-public-values vector, including cross-agreement with the live BN254 gateway; a soundcalc receipt for the exact pinned FriConfig is recorded (no 128-bit claim without the receipt); and a benchmark confirms a real verify fits under the EIP-7825 2^24 per-transaction gas cap. Beyond the prerequisite: a specialist external STARK/FRI audit of the consensus-critical crypto, a conformance gate green on the frozen artifact, an isolated N=7 soak across a simulated milestone crossing, and an explicit founder GO. Until all hold, 0x0AE8 stays a skeleton.
|
||||
|
||||
**Status.** Draft (blocked on the prerequisite crypto-core port). References: `aerenew/docs/PQ-STARK-VERIFIER-PRECOMPILE-2026-07-18.md` (design), `aerenew/docs/PQ-STARK-VERIFIER-ACTIVATION-2026-07-18.md` (gated activation plan), `aerenew/contracts/contracts/zkverify/AerePQStarkVerifier.sol` (fail-closed adapter).
|
||||
|
||||
---
|
||||
|
||||
## 4. Copyright
|
||||
## 5. Copyright
|
||||
|
||||
Released to the public domain (CC0). No rights reserved.
|
||||
|
||||
@ -78,13 +78,15 @@ flowchart TB
|
||||
Aere Network runs QBFT (Istanbul BFT family) with a Hyperledger Besu block producer, signing blocks with classical ECDSA over secp256k1. The live validator set is N=7 (f=2, commit quorum 5 of 7), all Foundation-operated, at a 500 ms target block period with sub-second deterministic finality. A second execution client, a patched Nethermind 1.39.0, is LIVE as a client-diversity cross-check: it peers with the Besu validators over devp2p and independently validates and follows the live chain (verification-layer diversity). Nethermind producing live QBFT blocks is roadmap: block production and adversarial recovery are proven on isolated testnets and via offline import (Besu imports Nethermind-sealed blocks byte-for-byte), but it is not yet a live producing validator on mainnet. Consensus is classical today, not post-quantum.
|
||||
|
||||
### Execution (LIVE base, frontier roadmap)
|
||||
The EVM is at Pectra plus Fusaka parity with Ethereum mainnet (Prague/Cancun activated at block 2,075,363; Osaka at block 2,106,606), including EIP-7702, EIP-2537 BLS12-381, EIP-2935 historical block hashes, transient storage, and the RIP-7951 P-256 precompile at 0x100. Five native post-quantum precompiles are LIVE on mainnet since block 9,189,161 (Falcon-512, Falcon-1024, ML-DSA-44, SLH-DSA-128s, SHAKE256 at 0x0AE1 through 0x0AE5), NIST KAT-validated on-chain. Roadmap execution items, all built and tested but not activated on mainnet: two further precompiles (ML-KEM-768 at 0x0AE6 and Falcon HashToPoint at 0x0AE7, KAT-verified on isolated testnet); parallel execution via a Block-STM engine (correctness proven bit-identical to sequential, near-linear execution-phase scaling, but no end-to-end throughput win claimed and not enabled on L1); and a full-EVM zk validity rollup (revm in the SP1 zkVM), which is verified on-chain as a proof-of-approach on small real blocks, not yet a production-throughput rollup.
|
||||
The EVM is at Pectra plus Fusaka parity with Ethereum mainnet (Prague/Cancun activated at block 2,075,341; Osaka at block 2,106,597), including EIP-7702, EIP-2537 BLS12-381, EIP-2935 historical block hashes, transient storage, and the RIP-7951 P-256 precompile at 0x100. Five native post-quantum precompiles are LIVE on mainnet since block 9,189,161 (Falcon-512, Falcon-1024, ML-DSA-44, SLH-DSA-128s, SHAKE256 at 0x0AE1 through 0x0AE5), NIST KAT-validated on-chain. Roadmap execution items, all built and tested but not activated on mainnet: two further precompiles (ML-KEM-768 at 0x0AE6 and Falcon HashToPoint at 0x0AE7, KAT-verified on isolated testnet); parallel execution via a Block-STM engine (correctness proven bit-identical to sequential, near-linear execution-phase scaling, but no end-to-end throughput win claimed and not enabled on L1); and a full-EVM zk validity rollup (revm in the SP1 zkVM), which is verified on-chain as a proof-of-approach on small real blocks, not yet a production-throughput rollup.
|
||||
|
||||
### Accounts (LIVE, some V2 redeploys founder-gated)
|
||||
Aere supports the full modern account spectrum: plain EOAs; WebAuthn / P-256 passkey accounts (backed by the native 0x100 precompile); ERC-4337 v0.7 smart accounts (AereEntryPointV2 live); EIP-7702 EOA delegation; a Falcon-512 post-quantum account whose sole owner is a Falcon public key; hybrid ECDSA plus Falcon authorization; and non-custodial t-of-n post-quantum threshold accounts (AereThresholdAccountFactory V2 live on mainnet, each committee leg verified by the live PQC precompiles). Honest caveat: several first-generation account contracts had audited defects and were superseded by fixed V2 redeploys that hold zero value; some corrected factories are deployed inert and the live migration of any funds-bearing path is founder-gated.
|
||||
Aere supports the full modern account spectrum: plain EOAs; WebAuthn / P-256 passkey accounts (backed by the native 0x100 precompile); ERC-4337 v0.7 smart accounts (AereEntryPointV2 live); EIP-7702 EOA delegation; a Falcon-512 post-quantum account whose sole owner is a Falcon public key; hybrid ECDSA plus Falcon authorization; and non-custodial t-of-n post-quantum threshold accounts (AereThresholdAccountFactory V2 at `0x69734E4044B1C5943B9256A73De41B101BFA2633`, each committee leg verified by the live PQC precompiles).
|
||||
|
||||
**Correction of 2026-08-01, because this line and `AERE-POST-QUANTUM-GOVERNANCE.md` in this same publication bundle contradicted each other.** This map said the V2 factory was "live on mainnet"; the governance document said of the same address "not on mainnet, treated here as not deployed". Two public documents in one bundle cannot say opposite things about one address. Measured at head block 11,810,041: the address carries **6,835 bytes** of code, against 6,717 at V1, so this map was closer to the truth and the governance document has been corrected. But neither was fully honest, and the accurate status is narrower than either: **deployed, code present, build identity NOT MEASURED**. The repository artifact is 7,407 bytes and reproduces neither version, so we cannot yet assert from bytecode that the deployed runtime is the duplicate-key-guard build. Do not cite it as the fixed factory until that is reproduced. Honest caveat: several first-generation account contracts had audited defects and were superseded by fixed V2 redeploys that hold zero value; some corrected factories are deployed inert and the live migration of any funds-bearing path is founder-gated.
|
||||
|
||||
### Applications (mixed LIVE and roadmap)
|
||||
- DeFi (LIVE): an isolated-market lending engine (AereLendingMarket, proven end-to-end with real supply/borrow/repay), the sAERE staking-receipt vault, and the immutable AereSink burn-and-buyback router. Note that sAERE has a corrected V2 whose migration is founder-gated.
|
||||
- DeFi (LIVE): an isolated-market lending engine (AereLendingMarket, proven end-to-end with real supply/borrow/repay), the sAERE staking-receipt vault, and the immutable AereSink burn-and-buyback router. **On AereSink, one word of that is not currently earned: the buyback.** Measured at head, `AereSink.DEX_ROUTER()` is `0x0000000000000000000000000000000000000001` and `ORACLE()` is the zero address, both immutable, so the 40% buyback bucket cannot execute for a non-AERE token and the documented oracle-derived minimum-output floor is not active. The burn path and the AERE/WAERE flow work as described. Read it as a burn router that is wired, plus a buyback leg that is not. Note that sAERE has a corrected V2 whose migration is founder-gated.
|
||||
- Settlement (LIVE): AereSettlementHub, AereStateChannels (24h challenge window), and AERE402 machine-to-machine payments (AereAgentV2 plus AERE402FacilitatorV2). The settlement hub is deployed in a bootstrap state holding no value pending a founder-supervised migration.
|
||||
- Bridge and interop: Hyperlane-compatible message bus (AereMessenger) is LIVE, as are the inbound zk Ethereum light client and the outbound zk QBFT-finality light client (both proven live end-to-end, trust-minimized, classical BN254). ERC-7683 intent settlement (SpokePool path) is roadmap: the corrected contracts exist but are deployed inert, so no live intent route is enrolled.
|
||||
- Identity and compliance: ZKScreen v3 sanctions screening is LIVE, as is a compliant, sanctions-gated privacy pool (deposit/withdraw circuit proofs are still being generated) and the AereProof proof-anchoring registry. zk-KYC and the over-18 attribute proof are roadmap (proofs generated, pending a Foundation registration signature).
|
||||
|
||||
@ -62,18 +62,32 @@ conditions" that "has never been a measured result."
|
||||
ceiling but does not publish the explicit factors. The two facts that are
|
||||
sourceable:
|
||||
|
||||
- Block period 0.5 s. `[CITED: aerenew/docs/wp2-sections/02-architecture.md:19; genesis-subsecond.json (blockperiodmilliseconds: 500)]`
|
||||
- Block period 0.5 s. `[CITED: aerenew/docs/wp2-sections/02-architecture.md:19; genesis-subsecond.json `config.transitions.qbft[0]` = `{ "block": 2137652, "xblockperiodmilliseconds": 500 }`]`
|
||||
<!-- QBFT-TRANSITION-CANONICAL path=config.transitions.qbft key=xblockperiodmilliseconds block=2137652 value=500 -->
|
||||
The earlier form of this citation read `blockperiodmilliseconds: 500`, without the mandatory
|
||||
`x` prefix. Besu never reads that key, so the citation described a setting that would have had
|
||||
no effect. Corrected 2026-07-31 against the file on disk. See
|
||||
`aerenew/docs/TRANZITIA-QBFT-SETTLED-2026-07-20.md`.
|
||||
- Genesis block gas limit is ambiguous across genesis artifacts: `0x2625a00`
|
||||
(40,000,000) in `aerenew/genesis.json`, versus `0x1fffffffffffff`
|
||||
(9,007,199,254,740,991, effectively unbounded) in `aere-genesis-current.json`
|
||||
and `genesis-subsecond.json`. `[VERIFY: which gas limit is live on 2800]`
|
||||
and `genesis-subsecond.json`. **RESOLVED by measurement 2026-08-01: the
|
||||
effectively-unbounded value is the live one.** `eth_getBlockByNumber("latest")`
|
||||
on `https://rpc.aere.network` at head block 11,810,041 returns header
|
||||
`gasLimit` = `0x1fffffffffffff` = 9,007,199,254,740,991. The 40,000,000
|
||||
artifact is not what chain 2800 runs. Anyone can re-check this in one RPC call.
|
||||
|
||||
Implied arithmetic (transparent, not a new claim): 273,000 TPS at a 0.5 s block
|
||||
is 136,500 tx per block, and at the 21,000-gas simple-transfer floor that is
|
||||
about 2.87 billion gas per block. That is far above the 40M limit and far below
|
||||
the effectively-unbounded limit, so the ceiling presumes an effectively-
|
||||
unbounded block gas limit AND the cheapest possible transaction, not the
|
||||
EIP-7825-capped realistic workload the chain actually runs. `[VERIFY: publish the
|
||||
the effectively-unbounded limit. Since the live header limit is measured at
|
||||
9,007,199,254,740,991 (see above), the block-space side of the ceiling is not
|
||||
what bounds it. The ceiling still presumes the cheapest possible transaction
|
||||
rather than a realistic workload, and that remains the honest caveat on the
|
||||
figure. The per-transaction EIP-7825 cap referenced here is **NOT MEASURED**:
|
||||
an `eth_call` above the stated 2^24 cap succeeded, `eth_estimateGas` does not
|
||||
discriminate, and the only conclusive probe is a transaction above the cap,
|
||||
which we do not send. `[VERIFY: publish the
|
||||
explicit block-space arithmetic behind 273,000 so the ceiling is reproducible]`
|
||||
|
||||
### A.1 Testnet-measured and live-observed throughput (the honest gap)
|
||||
@ -83,7 +97,7 @@ closest measured throughput number in the repo is a rollup-executor
|
||||
microbenchmark, and the artifact that produces it says plainly it neither
|
||||
reaches nor implies the ceiling.
|
||||
|
||||
`[CITED: aerenew/parallel-executor/BLOCKSTM-ENDTOEND-THROUGHPUT-2026-07-13.md section 7]`
|
||||
`[CITED: aere-research/parallel-executor/BLOCKSTM-ENDTOEND-THROUGHPUT-2026-07-13.md section 7]`
|
||||
The Block-STM end-to-end harness measured about 247,000 to 270,000 TPS at
|
||||
`gas=80` on a 16-vCPU box, but this is (a) the rollup executor with a light
|
||||
commit proxy, not L1, not a real Merkle Patricia Trie, and (b) entirely a
|
||||
@ -108,8 +122,13 @@ irreversible in well under a second from inclusion, with no confirmation count
|
||||
and no reorg. `[CITED: aerenew/docs/wp2-sections/02-architecture.md:19]`
|
||||
|
||||
The 0.5 s period was reached by a mid-chain QBFT parameter change at block
|
||||
2,138,451, halved from the launch value of one second, with no re-genesis.
|
||||
`[CITED: aerenew/docs/wp2-sections/01-overview.md:59; aerenew/docs/WHITEPAPER-V2.md:73; genesis-subsecond.json (blockperiodseconds: 0, blockperiodmilliseconds: 500)]`
|
||||
2,137,652, halved from the launch value of one second, with no re-genesis.
|
||||
`[CITED: aerenew/docs/wp2-sections/01-overview.md:59; aerenew/docs/WHITEPAPER-V2.md:73; genesis-subsecond.json `config.qbft.blockperiodseconds` = 1 at genesis, `config.transitions.qbft[0]` = `{ "block": 2137652, "xblockperiodmilliseconds": 500 }`]`
|
||||
<!-- QBFT-TRANSITION-CANONICAL path=config.transitions.qbft key=xblockperiodmilliseconds block=2137652 value=500 -->
|
||||
The earlier form of this citation read `blockperiodseconds: 0, blockperiodmilliseconds: 500`.
|
||||
Neither appears in the file. `blockperiodseconds: 0` is rejected outright by Besu's
|
||||
`JsonUtil.getPositiveInt`, and the non-x key is silently ignored. Corrected 2026-07-31 by
|
||||
reading `genesis-subsecond.json` rather than by trusting the citation.
|
||||
|
||||
Finality is a latency-to-irreversibility claim and is separate from throughput.
|
||||
The 0.5 s finality claim follows mechanically from QBFT plus the block period; it
|
||||
@ -135,7 +154,7 @@ PATHOLOGICAL parallel==sequential check: PASS
|
||||
|
||||
This corroborates the cited larger runs: a 6,000-comparison correctness harness
|
||||
with 0 mismatches, and a re-import plus validation of 253 real exported blocks
|
||||
with zero state-root mismatch. `[CITED: aerenew/parallel-executor/BLOCKSTM-ENDTOEND-THROUGHPUT-2026-07-13.md section 3 and section 8]`
|
||||
with zero state-root mismatch. `[CITED: aere-research/parallel-executor/BLOCKSTM-ENDTOEND-THROUGHPUT-2026-07-13.md section 3 and section 8]`
|
||||
|
||||
**(2) Near-linear execution-phase scaling on parallelizable workloads.**
|
||||
`[MEASURED-FRESH]` on this machine (fewer physical cores than the reference
|
||||
@ -189,6 +208,27 @@ Notes on the two recursion facts worth keeping, both `[CITED: proof-aggregator-s
|
||||
- The proving side of that same 10-fold cost 526.1 s for the aggregation Groth16
|
||||
plus 988 s of inner proving (measured, off-chain, single run).
|
||||
|
||||
### B.1.1 Every receipt-type figure in B.1 was fetched from chain 2800 and matches
|
||||
|
||||
`[MEASURED-FRESH 2026-07-19]` The gas figures in B.1 that claim to be on-chain
|
||||
records are receipt-type claims, so each cited transaction was fetched from
|
||||
`https://rpc.aere.network` by `eth_getTransactionReceipt` and its `gasUsed`
|
||||
compared against the figure printed in this report. All five resolve, all five are
|
||||
status `0x1`, and all five match **exactly**, no roundings, no near-misses:
|
||||
|
||||
| Figure in B.1 | Tx hash | Block | Receipt gasUsed | Report says | Result |
|
||||
|---|---|--:|--:|--:|---|
|
||||
| Halo2 cubic verify | `0x2be2449c...451c6c` | 8,926,951 | 449,517 | 449,517 | exact |
|
||||
| KZG point-eval (0x0A) | `0x28d4395c...8987b8` | 8,926,917 | 255,719 | 255,719 | exact |
|
||||
| SP1 aggregation n=10 | `0xd1fd4d60...44d978` | 8,930,005 | 393,844 | 393,844 | exact |
|
||||
| Storage-proof coprocessor | `0xe541c52b...936c54` | 8,921,209 | 348,345 | 348,345 | exact |
|
||||
| zkML MNIST verify | `0x4cb256ed...0b497a` | 8,741,874 | 326,492 | 326,492 | exact |
|
||||
|
||||
This is the standard the Part C verify-and-record figures do not currently meet:
|
||||
these five name a transaction, the transaction exists on mainnet 2800, and its
|
||||
receipt says what the report says it says. A reader can re-run this check in five
|
||||
RPC calls.
|
||||
|
||||
### B.2 Routing logic (which prover for which job, and why)
|
||||
|
||||
`[CITED: aerenew/research/specs/spec-zk-stack.md sections 1-3, 7-11]` Routing is
|
||||
@ -253,34 +293,185 @@ exactly the five PQC precompiles `0x0AE1..0x0AE5`; `0x0AE8` is not live anywhere
|
||||
|
||||
## PART C: CRYPTO-OP GAS (PQC vs ECDSA)
|
||||
|
||||
### C.1 Table (measured marginal precompile verify-op gas, with sources)
|
||||
### C.1 Three different kinds of number, kept in three different columns
|
||||
|
||||
| Operation | Address | Marginal gas | Full verify-and-record tx gasUsed | Source |
|
||||
The single most dangerous thing this table could do is print a schedule constant,
|
||||
an empirical cost, and a transaction receipt in one column as if they were the
|
||||
same kind of fact. They are not, so they are separated here:
|
||||
|
||||
- **PRICE**, a fixed constant in the client's gas schedule. It is not an
|
||||
empirical result; it is a chosen number. What *can* be measured about a price
|
||||
is whether the live chain actually charges it.
|
||||
- **MEASURED-LIVE**, the price the live canonical client charged, isolated by a
|
||||
calibrated `eth_call` probe on mainnet 2800 (method in C.1.1). This is the only
|
||||
column that constitutes evidence about the running chain.
|
||||
- **RECEIPT**, a `gasUsed` from a real mined transaction, only meaningful when
|
||||
the tx hash and the chain it was mined on are both given.
|
||||
|
||||
| Operation | Address | Schedule PRICE | MEASURED-LIVE on 2800 | Verdict |
|
||||
|---|---|--:|--:|---|
|
||||
| ECDSA (ecrecover) | 0x01 | ~3,000 | n/a | protocol constant `[VERIFY: G_ecrecover = 3000 is a fixed EVM constant, not Aere-specific]` |
|
||||
| P-256 / passkey (RIP-7951, aka RIP-7212) | 0x100 | ~3,450 | n/a | `[CITED: aerenew/docs/wp2-sections/02-architecture.md:36; aerenew/research/aip-draft-pqc-precompiles.md section 4, "repo-sourced from the Fusaka notes"]` |
|
||||
| SHAKE256 (FIPS 202) | 0x0AE5 | 60 base + 12/word | 21,470 | `[CITED: aerenew/pqc-fork/precompiles/HashToPointPrecompiledContract.java lines 51-52 (BASE_GAS=60, GAS_PER_WORD=12); aip-draft section 3 table]` |
|
||||
| Falcon-512 (NIST round-3) | 0x0AE1 | 40,000 | 86,336 | `[CITED: aip-draft section 4 and Reference table]` |
|
||||
| ML-DSA-44 (FIPS 204) | 0x0AE3 | 55,000 | 351,050 | `[CITED: aip-draft section 6 and Reference table]` |
|
||||
| ML-KEM-768 (FIPS 203, encapsulation) | 0x0AE6 | 60,000 (fixed) | n/a (KEM, testnet-only) | `[CITED: aerenew/pqc-fork/precompiles/MLKEM768PrecompiledContract.java line 73 (GAS = 60_000)]` |
|
||||
| Falcon-1024 (NIST round-3) | 0x0AE2 | 75,000 | 145,496 | `[CITED: aip-draft section 5 and Reference table]` |
|
||||
| SLH-DSA-SHA2-128s (FIPS 205) | 0x0AE4 | 350,000 | 558,276 | `[CITED: aip-draft section 7 and Reference table]` |
|
||||
| ECDSA (ecrecover) | 0x01 | 3,000 | **3,000** | price confirmed charged |
|
||||
| P-256 / passkey (**RIP-7951 / EIP-7951**) | 0x100 | **6,900** | **6,900** | price confirmed charged; see C.1.2 |
|
||||
| SHAKE256 (FIPS 202) | 0x0AE5 | 60 + 12/word, words counted **separately** (C.1.3) | **60 + 12/word, separate** (56/56 shapes exact) | price and word model confirmed |
|
||||
| Falcon-512 (NIST round-3) | 0x0AE1 | 40,000 | **40,000** | price confirmed charged |
|
||||
| Falcon-1024 (NIST round-3) | 0x0AE2 | 75,000 | **75,000** | price confirmed charged |
|
||||
| ML-DSA-44 (FIPS 204) | 0x0AE3 | 55,000 | **55,000** | price confirmed charged |
|
||||
| SLH-DSA-SHA2-128s (FIPS 205) | 0x0AE4 | 350,000 | **350,000** | price confirmed charged |
|
||||
| ML-KEM-768 (FIPS 203, encap) | 0x0AE6 | 60,000 `[CITED: MLKEM768PrecompiledContract.java line 73]` | **not live** (probe returns 0) | testnet-only, as documented |
|
||||
| Falcon HashToPoint | 0x0AE7 | 60 + 12/word `[CITED: HashToPointPrecompiledContract.java lines 51-52]` | **not live** (probe returns 0) | testnet-only, as documented |
|
||||
|
||||
All marginal-gas values are the scratch-fork (chain 28099) measured constants;
|
||||
the verify-and-record tx gasUsed values are on-chain receipts. `[CITED: aerenew/research/aip-draft-pqc-precompiles.md Reference Implementation table]`
|
||||
The five signature and hash precompiles (`0x0AE1..0x0AE5`) are live on mainnet
|
||||
2800, activated at block 9,189,161. ML-KEM-768 (`0x0AE6`) and Falcon HashToPoint
|
||||
(`0x0AE7`) are KAT-validated on an isolated testnet and remain founder-gated for
|
||||
mainnet. `[CITED: aerenew/pqc-fork/README chain, pqc-fork memory]`
|
||||
`[MEASURED-FRESH 2026-07-19, mainnet 2800, head block 10,487,300]` Every
|
||||
MEASURED-LIVE cell above was produced this session by the calibrated probe, not
|
||||
carried over from the scratch fork. The five signature and hash precompiles
|
||||
(`0x0AE1..0x0AE5`) are confirmed live and charging; `0x0AE6`, `0x0AE7` and
|
||||
`0x0AE8` are confirmed **absent** on mainnet (the probe measures exactly 0 marginal
|
||||
gas, i.e. a call to a codeless address), which independently corroborates the
|
||||
"KAT-validated on isolated testnet, founder-gated for mainnet" status.
|
||||
|
||||
Activation of `0x0AE1..0x0AE5` is stated as block 9,189,161. `[VERIFY: this
|
||||
activation block could NOT be confirmed by measurement. The check that would prove
|
||||
it is a historical `eth_call` probe at blocks 9,189,160 and 9,189,161, showing the
|
||||
precompile charging 0 before and 40,000 after. The public endpoint retains state
|
||||
for only about the last 256 to 1,024 blocks (probes succeed at head-256 and return
|
||||
"Internal error" at head-1024), so state at block 9.19M is long pruned. Confirming
|
||||
this requires an archive node. The Nethermind second client cannot serve it either:
|
||||
it is mid-sync well below 9.19M. The activation block therefore remains a cited
|
||||
claim, not a measured one.]`
|
||||
|
||||
**Verify-and-record transaction gasUsed, moved out of the table above, because
|
||||
these are NOT mainnet receipts.**
|
||||
|
||||
| Operation | verify-and-record gasUsed | Chain it was mined on | Tx hash |
|
||||
|---|--:|---|---|
|
||||
| SHAKE256 | 21,470 | scratch fork **28099** | not recorded |
|
||||
| Falcon-512 | 86,336 | scratch fork **28099** | not recorded |
|
||||
| Falcon-1024 | 145,496 | scratch fork **28099** | not recorded |
|
||||
| ML-DSA-44 | 351,050 | scratch fork **28099** | not recorded |
|
||||
| SLH-DSA-SHA2-128s | 558,276 | scratch fork **28099** | not recorded |
|
||||
|
||||
`[CITED: aere-research-repo/docs/PROVEN-RESULTS-2026-07-11.md line 93, which states
|
||||
plainly "Measured on the isolated scratch fork (chain 28099), full verify-and-record
|
||||
transactions"; aerenew/research/aip-draft-pqc-precompiles.md sections 3-7]`
|
||||
|
||||
`[VERIFY: no transaction hash is recorded for any of these five, so none of them
|
||||
can be fetched and re-verified by a reader. They are single-run receipts from a
|
||||
disposable chain. Either publish the tx hashes and the chain-28099 export, or
|
||||
re-run all five as real transactions on mainnet 2800 (the precompiles are live,
|
||||
so this is now possible and would replace fork receipts with citable mainnet
|
||||
ones). Until then these five numbers are the weakest-provenance figures in this
|
||||
report and MUST NOT be cited as mainnet results.]`
|
||||
|
||||
An independent data point showing how environment-dependent these end-to-end
|
||||
receipts are: the keyless statefork rehearsal on a *different* isolated network
|
||||
measured Falcon-1024 verify-and-record at **172,720** gas and ML-DSA-44 at
|
||||
**351,970** gas `[CITED: PROVEN-RESULTS-2026-07-11.md line 95]`, versus 145,496 and
|
||||
351,050 on chain 28099. The marginal precompile price is a hard constant; the
|
||||
verify-and-record total is not, because it includes contract storage writes and
|
||||
calldata that vary with the harness.
|
||||
|
||||
Scope reminder attached to this table: these precompiles are an application and
|
||||
account layer capability. They do not make Aere consensus post-quantum.
|
||||
|
||||
### C.2 Two fresh cross-checks run this session
|
||||
#### C.1.1 How the MEASURED-LIVE column was produced, and how the instrument was calibrated
|
||||
|
||||
`[MEASURED-FRESH]` The SHAKE256 gas schedule (60 base plus 12 per word) is
|
||||
confirmed present in source, and the HashToPoint precompile's own gas was freshly
|
||||
computed from that exact source formula (`gasRequirement`, lines 78-93):
|
||||
`eth_estimateGas` is insufficient for this job: the EIP-7623 calldata floor can
|
||||
mask precompile price differences entirely. Instead a probe contract was installed
|
||||
at a scratch address via `eth_call` state override (read-only, nothing was sent to
|
||||
the chain). The probe does `CALLDATACOPY`, a **pre-warming** `STATICCALL` to the
|
||||
target, then `GAS / STATICCALL / GAS / SWAP1 / SUB` around the measured call, and
|
||||
returns the delta. The pre-warming call absorbs both the EIP-2929 cold-access
|
||||
charge and the memory expansion, so the second call's delta is the precompile's
|
||||
own `gasRequirement` plus a fixed probe overhead. That overhead is removed by
|
||||
subtracting the identical measurement against a codeless address.
|
||||
|
||||
The instrument was calibrated **before** being trusted, against two operations
|
||||
whose price no scheduled EIP can move:
|
||||
|
||||
- IDENTITY `0x04`, expected `15 + 3*ceil(len/32)`: **exact on all 12 input lengths
|
||||
tested** (0, 1, 31, 32, 33, 64, 96, 100, 128, 200, 256, 1000 bytes).
|
||||
- SHA-256 `0x02`, expected `60 + 12*ceil(len/32)`: **exact on all 4 lengths tested**.
|
||||
|
||||
16/16 exact, zero residual, including the `len=0` case returning exactly the bare
|
||||
base cost, which demonstrates the control subtraction leaves no residue. Only
|
||||
after that was any PQC or P-256 number recorded.
|
||||
|
||||
#### C.1.2 The P-256 figure: a corrected 2x error, and exactly where it came from
|
||||
|
||||
**A previous revision of this report stated P-256 at `~3,450` gas and attributed
|
||||
that to "RIP-7951, aka RIP-7212". Both halves of that were wrong.** The measured
|
||||
price on mainnet 2800 is **6,900 gas**, flat and independent of input length
|
||||
(measured at input lengths 0, 160 and 161 bytes; all 6,900).
|
||||
|
||||
The resolution is not "spec price versus measured cost including overhead". The
|
||||
probe subtracts its own overhead, the raw probe delta was 7,029 and the codeless
|
||||
control was 129, leaving 6,900 as the precompile's own charge with zero call
|
||||
overhead included. So 6,900 is *both* the spec price and the measured price, and
|
||||
3,450 is neither.
|
||||
|
||||
3,450 is the price in **RIP-7212**, the original Layer-2 rollup spec. **RIP-7951 /
|
||||
EIP-7951**, the mainnet successor scheduled in Fusaka, keeps RIP-7212's address
|
||||
(`0x100`), its 160-byte input and its output format, full bytecode compatibility ,
|
||||
but **doubles the gas to 6,900**, having addressed security issues found in
|
||||
RIP-7212. Aere tracks Ethereum's ruleset (Pectra plus Fusaka), so Aere ships the
|
||||
RIP-7951 price of 6,900, correctly. The "aka RIP-7212" phrasing was the source of
|
||||
the error: the two specs are interface-compatible but are *not* price-compatible,
|
||||
and the older number was carried in under the newer name.
|
||||
|
||||
`[VERIFY: this correction propagates. aerenew/research/aip-draft-pqc-precompiles.md
|
||||
section 4 anchors its Falcon-512 pricing rationale on "RIP-7951 prices a native
|
||||
P-256 verification at a fixed roughly 3,450 gas". That anchor is wrong. The
|
||||
argument's direction survives but its magnitude does not: Falcon-512 is 40,000/6,900
|
||||
= 5.8x a P-256 verify, not 40,000/3,450 = 11.6x.]`
|
||||
|
||||
#### C.1.3 SHAKE256 word counting: independently re-measured, separate not combined
|
||||
|
||||
The SHAKE256 gas word count is `ceil(len(data)/32) + ceil(outLen/32)`, the two
|
||||
lengths rounded up **separately**, not `ceil((len(data)+outLen)/32)` combined. This
|
||||
was re-measured this session against live mainnet 2800 with well-formed input
|
||||
(32-byte `outLen` word followed by data) across **56 shapes** (8 output lengths x 7
|
||||
data lengths), fitting both candidate models with no hypothesis assumed:
|
||||
|
||||
```
|
||||
SEPARATE model 60 + 12*(ceil(d/32) + ceil(o/32)) : 56/56 exact, SSE = 0
|
||||
COMBINED model 60 + 12*ceil((d+o)/32) : 47/56 exact, SSE = 1296
|
||||
```
|
||||
|
||||
The models diverge exactly when `len(data) mod 32` and `outLen mod 32` are both
|
||||
nonzero. Behaviour was confirmed alongside price: `eth_call` to `0x0AE5` with
|
||||
`outLen=32` and data `abc` returns
|
||||
`0x483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739`, which is
|
||||
`shake_256(b'abc').hexdigest(32)` per FIPS 202.
|
||||
|
||||
`[VERIFY: aerenew/research/aip-draft-pqc-precompiles.md section 3 still specifies
|
||||
the combined form `words = ceil((len(data) + outLen) / 32)` normatively. That is the
|
||||
same defect already corrected in aerenew/eips/eip-draft-shake256-precompile.md and
|
||||
it contradicts the running chain. It is corrected in the AIP draft as of this
|
||||
report; flagged here because this report cited that document as its source.]`
|
||||
|
||||
`[VERIFY: a previous revision of this report cited
|
||||
aerenew/pqc-fork/precompiles/HashToPointPrecompiledContract.java lines 51-52 as the
|
||||
source for the SHAKE256 (0x0AE5) gas constants. That file is the HashToPoint
|
||||
precompile, address 0x0AE7, which this session's probe confirms is NOT live on
|
||||
mainnet. Its BASE_GAS=60 / GAS_PER_WORD=12 happen to equal SHAKE256's constants but
|
||||
it is not their source. The 0x0AE5 constants are now sourced from live measurement
|
||||
above.]`
|
||||
|
||||
Scope reminder attached to this table: these precompiles are an application and
|
||||
account layer capability. They do not make Aere consensus post-quantum.
|
||||
|
||||
### C.2 Two further cross-checks
|
||||
|
||||
Note the register difference between these two and the C.1 measurements: the first
|
||||
is **arithmetic evaluated from source code**, not a measurement of a running chain,
|
||||
and the second is a **scratch-fork benchmark artifact**. Neither is a mainnet
|
||||
result, and neither is presented as one.
|
||||
|
||||
`[COMPUTED-FROM-SOURCE, not measured]` The SHAKE256 gas schedule (60 base plus 12
|
||||
per word) is confirmed present in source, and the HashToPoint precompile's own gas
|
||||
was computed from that exact source formula (`gasRequirement`, lines 78-93). This
|
||||
is evaluating a formula in a file, and HashToPoint (`0x0AE7`) is not live on
|
||||
mainnet 2800, so this figure could not have been measured on-chain even in
|
||||
principle:
|
||||
|
||||
```
|
||||
Falcon-512 (n=512) 32-byte message, 73-byte input: words=38 -> gasRequirement = 516
|
||||
@ -293,28 +484,36 @@ is the precompile's own intrinsic gas; it is distinct from the end-to-end verify
|
||||
gas below, and the two must not be conflated.
|
||||
|
||||
`[CITED: aerenew/pqc-fork/results/bench-results.json]` The HashToPoint-precompile
|
||||
optimization measured on the scratch fork (chain 28777), full Falcon-512 verify:
|
||||
9,140,858 gas in pure EVM dropping to 7,186,367 gas with the precompile, a 21.4
|
||||
percent reduction across 8 test vectors, all accept and tamper-reject checks
|
||||
passing.
|
||||
optimization measured on the scratch fork (chain 28777, NOT mainnet), full
|
||||
Falcon-512 verify: 9,140,858 gas in pure EVM dropping to 7,186,367 gas with the
|
||||
precompile, a 21.4 percent reduction across 8 test vectors, all accept and
|
||||
tamper-reject checks passing. Re-checked against the artifact this session: the
|
||||
JSON records `avg_verify_gas_in_evm` 9140858, `avg_verify_gas_precompile` 7186367,
|
||||
`avg_verify_pct_drop` 21.4, `chainId` 28777, `vectors` 8,
|
||||
`integration_all_pass` true. The report's figures match the artifact exactly.
|
||||
|
||||
### C.3 The honest story the numbers tell
|
||||
|
||||
Post-quantum verification is materially more expensive than ECDSA. Ratios below
|
||||
are fresh arithmetic from the cited marginal-gas constants divided by the
|
||||
3,000-gas ecrecover:
|
||||
are fresh arithmetic over the **live-measured** prices of C.1, divided by the
|
||||
live-measured 3,000-gas ecrecover and by the live-measured 6,900-gas P-256. Both
|
||||
baselines are given because they answer different questions: ecrecover is what a
|
||||
plain EOA signature costs, P-256 is what a *passkey* signature costs, and a passkey
|
||||
is the realistic thing a post-quantum account would be replacing.
|
||||
|
||||
| Scheme | Marginal gas | Cost vs ECDSA (3,000) |
|
||||
|---|--:|--:|
|
||||
| Falcon-512 | 40,000 | ~13.3x |
|
||||
| ML-DSA-44 | 55,000 | ~18.3x |
|
||||
| ML-KEM-768 | 60,000 | ~20.0x |
|
||||
| Falcon-1024 | 75,000 | ~25.0x |
|
||||
| SLH-DSA-SHA2-128s | 350,000 | ~116.7x |
|
||||
| Scheme | Live-measured gas | vs ECDSA (3,000) | vs P-256 passkey (6,900) |
|
||||
|---|--:|--:|--:|
|
||||
| Falcon-512 | 40,000 | ~13.3x | ~5.8x |
|
||||
| ML-DSA-44 | 55,000 | ~18.3x | ~8.0x |
|
||||
| Falcon-1024 | 75,000 | ~25.0x | ~10.9x |
|
||||
| SLH-DSA-SHA2-128s | 350,000 | ~116.7x | ~50.7x |
|
||||
| ML-KEM-768 (not live on 2800) | 60,000 (price only) | ~20.0x | ~8.7x |
|
||||
|
||||
So PQC verification runs roughly 13x (Falcon-512) to about 117x
|
||||
(SLH-DSA-SHA2-128s) the cost of an ECDSA recover. That premium is exactly what
|
||||
motivates two roadmap directions:
|
||||
(SLH-DSA-SHA2-128s) the cost of an ECDSA recover, or about 6x to 51x the cost of a
|
||||
P-256 passkey verify. The ML-KEM-768 row is a schedule price only: that precompile
|
||||
is not live on mainnet 2800, so unlike the rows above it it has no live-measured
|
||||
value. That premium is exactly what motivates two roadmap directions:
|
||||
|
||||
- **Aggregation.** Amortize one expensive PQC verify across many authentications
|
||||
rather than paying per signature. `[VERIFY: the specific "AerePQAggregate"
|
||||
@ -360,8 +559,8 @@ recommendation is to consolidate them, but each is real and runnable now:
|
||||
|
||||
| Domain | Where to run it | File |
|
||||
|---|---|---|
|
||||
| Block-STM correctness + scaling (Part A.3, freshly run here) | `cd aerenew/parallel-executor && cargo test --release && cargo run --release -- bench` and `-- endtoend` | `aerenew/parallel-executor/BLOCKSTM-ENDTOEND-THROUGHPUT-2026-07-13.md` section 10 |
|
||||
| PQC precompile KATs + gas (Part C) | `aerenew/pqc-fork/run-kats.sh`, `aerenew/pqc-fork/bench/bench.py` | `aerenew/pqc-fork/` (results in `results/bench-results.json`, `results/kat-results-*.json`) |
|
||||
| Block-STM correctness + scaling (Part A.3, freshly run here) | `cd aerenew/parallel-executor && cargo test --release && cargo run --release -- bench` and `-- endtoend` | `aere-research/parallel-executor/BLOCKSTM-ENDTOEND-THROUGHPUT-2026-07-13.md` section 10 |
|
||||
| PQC precompile KATs + gas (Part C) | `aerenew/pqc-fork/run-kats.sh`, `aere-research/bench/bench.py` | `aerenew/pqc-fork/` (results in `aere-research/results/bench-results.json`, `results/kat-results-*.json`) |
|
||||
| Reproducible Besu client build | `docker build ... -f aerenew/node/Dockerfile.reproducible` then `aerenew/scripts/verify-besu-image.sh` | `aerenew/node/REPRODUCIBLE.md` (note: public digest manifest publication is still roadmap, so the third-party comparison step is not yet live) |
|
||||
| PQ-consensus reproduction | committed harness | `aerenew/research-stage/formal-consensus/REPRODUCE.md`, `aerenew/audit-package-pq-consensus/REPRODUCE.md` |
|
||||
|
||||
@ -375,20 +574,47 @@ domains above with pinned commands, so a third party has one entry point]`
|
||||
**Freshly measured this session `[MEASURED-FRESH]`:**
|
||||
- Block-STM `parallel==sequential` gate: PASS on all 4 conflict profiles (this Windows box).
|
||||
- Block-STM 16-thread execution-phase speedup this box: low 4.36x, medium 4.96x, high 1.92x, pathological 0.43x.
|
||||
- HashToPoint precompile intrinsic gas from source formula: 516 gas (Falcon-512, 32-byte message), 936 gas (Falcon-1024).
|
||||
|
||||
**Freshly measured against live mainnet 2800 (2026-07-19, head block 10,487,300),
|
||||
calibrated probe, read-only `eth_call` only `[MEASURED-LIVE]`:**
|
||||
- Probe calibration: IDENTITY `0x04` exact on 12 lengths, SHA-256 `0x02` exact on 4 lengths, 16/16, zero residual.
|
||||
- ecrecover `0x01` = **3,000** (flat). Closes the prior `[VERIFY]` on this constant.
|
||||
- P-256 `0x100` = **6,900** (flat across 0/160/161-byte input). **Corrects the prior "~3,450".**
|
||||
- Falcon-512 `0x0AE1` = **40,000**; Falcon-1024 `0x0AE2` = **75,000**; ML-DSA-44 `0x0AE3` = **55,000**; SLH-DSA `0x0AE4` = **350,000**. All flat, all matching the published schedule prices.
|
||||
- SHAKE256 `0x0AE5` = **60 + 12 per word, words counted separately**: 56/56 shapes exact, SSE 0; combined-word model 47/56, SSE 1296.
|
||||
- SHAKE256 behaviour: `shake256("abc", 32)` returns the correct FIPS 202 bytes.
|
||||
- `0x0AE6`, `0x0AE7`, `0x0AE8` measure **0 marginal gas** = not live on mainnet, corroborating their documented testnet-only status.
|
||||
- **Re-measured and re-derived 2026-07-20** by `aerenew/pqc-fork/probe-precompile-liveness.js` at block 10,611,947, with a second, independent probe design (an in-EVM `STATICCALL` gas prober injected by `eth_call` state override, rather than transaction-level `eth_estimateGas`). Identity calibration exact at 6 lengths. Charges: `0x0AE1` 40,000, `0x0AE2` 75,000, `0x0AE3` 55,000, `0x0AE4` 350,000, `0x0AE5` 24,648, `0x0AE6` **0**, `0x0AE7` **0**. Both probe designs agree.
|
||||
- **Caveat on the `eth_estimateGas` form of this probe, discovered 2026-07-20.** Under EIP-7623 a transaction pays `max(21000 + standard calldata cost + execution, calldata floor cost)`, and the floor term dominates. At a 64-byte input the measured headroom is **1,873 gas of execution that is free inside the floor and therefore invisible**. Measured consequence: the estimateGas probe reports the **live** identity precompile at `0x04` as charging **0 gas**, at all six lengths tried. So "estimateGas equals the codeless control" is sound evidence of absence only for a precompile that would bill *more* than the floor headroom on that input. It is sound for `0x0AE6` (flat 60,000 for every input). It is **not** sound on its own for `0x0AE7`, which bills only about 84 gas on a malformed 64-byte input. `0x0AE7`'s absence rests on the in-EVM probe, which has no such blind spot. Raw numbers at that input for the record: codeless control 23,897; `0x0AE1` 62,853; `0x0AE2` 97,992; `0x0AE3` 77,913; `0x0AE4` 376,144; `0x0AE5` 47,055; `0x0AE6` 23,897; `0x0AE7` 23,897.
|
||||
- Part B receipts re-fetched: Halo2 449,517 / KZG 255,719 / SP1-agg 393,844 / storage-proof 348,345 / zkML 326,492, all five resolve on 2800, all status 1, all exact.
|
||||
|
||||
**Computed from source this session, NOT measured on a chain `[COMPUTED-FROM-SOURCE]`:**
|
||||
- HashToPoint precompile intrinsic gas from source formula: 516 gas (Falcon-512, 32-byte message), 936 gas (Falcon-1024). HashToPoint is not live on mainnet, so this is formula evaluation, not measurement.
|
||||
|
||||
**Cited from committed repo artifacts `[CITED]`:**
|
||||
- 273,000 TPS is a design ceiling, never measured (WHITEPAPER-V2, wp2-sections).
|
||||
- 0.5 s block period, halved at block 2,138,451, single-slot QBFT finality (wp2-sections, genesis-subsecond.json).
|
||||
- 0.5 s block period, halved at block 2,137,652 by `config.transitions.qbft[0].xblockperiodmilliseconds = 500`, single-slot QBFT finality (wp2-sections, genesis-subsecond.json).
|
||||
- Rollup end-to-end harness ~247k to 270k TPS at gas=80, swinging 115k to 500k, not the L1 ceiling (BLOCKSTM-ENDTOEND section 7).
|
||||
- Reference 16-core Block-STM ~8.3x to 9.4x exec, ~8.3x to 9.1x end-to-end (same artifact).
|
||||
- SP1 Groth16 ~300k gas, ~260 to 356 byte proofs; measured records storage-proof 348,345, zkML 326,492, aggregation ~390k (spec-zk-stack; deployment artifacts).
|
||||
- SP1 proving times: zkscreen ~72 to 75 s, over18 ~71 to 73 s, zkml-mnist ~200 to 205 s, aggregation Groth16 526.1 s (proof-aggregator-scale.json).
|
||||
- RISC Zero Groth16 seal 260 bytes, 5.0.0-rc.1 (risc0-verifier-fix.json).
|
||||
- Halo2 ~449,517 gas, 1,152-byte proof; KZG point-eval ~255,719 gas (deployment artifacts, spec-zk-stack).
|
||||
- PQC marginal gas: Falcon-512 40,000, Falcon-1024 75,000, ML-DSA-44 55,000, SLH-DSA-128s 350,000, ML-KEM-768 60,000, SHAKE256 60+12/word; verify-and-record tx: 86,336 / 145,496 / 351,050 / 558,276 / 21,470 (aip-draft, precompile source, bench-results.json).
|
||||
- P-256 ~3,450 gas (wp2-sections, aip-draft).
|
||||
- HashToPoint optimization 9,140,858 to 7,186,367 gas, -21.4% (bench-results.json).
|
||||
- PQC verify-and-record tx gasUsed: 86,336 / 145,496 / 351,050 / 558,276 / 21,470, **scratch fork chain 28099, no tx hashes recorded, NOT mainnet** (see C.1).
|
||||
- HashToPoint optimization 9,140,858 to 7,186,367 gas, -21.4%, **scratch fork chain 28777** (bench-results.json).
|
||||
|
||||
**Superseded by live measurement this session (previously `[CITED]`, now
|
||||
`[MEASURED-LIVE]`):** the PQC marginal-gas constants and the ecrecover constant are
|
||||
no longer cited from the scratch fork or from memory; they were re-measured on
|
||||
mainnet 2800 and all matched. The P-256 figure did **not** match and was corrected.
|
||||
|
||||
**Corrections applied to this report on 2026-07-19:**
|
||||
1. **P-256 `0x100`: `~3,450` -> `6,900`.** The old value was RIP-7212's L2 price carried in under RIP-7951's name; RIP-7951/EIP-7951 doubles it to 6,900, and 6,900 is what chain 2800 measurably charges. A 2x understatement. See C.1.2.
|
||||
2. **Verify-and-record gasUsed figures re-labelled.** They were presented as "on-chain receipts" in a report headed "Chain: mainnet 2800"; they are chain-28099 scratch-fork receipts with no recorded tx hashes. Moved to their own table with the chain named and the gap flagged. See C.1.
|
||||
3. **SHAKE256 source citation corrected.** The report cited `HashToPointPrecompiledContract.java` (which is `0x0AE7`, not live on mainnet) as the source for `0x0AE5`'s constants. Now sourced from live measurement.
|
||||
4. **SHAKE256 word model made explicit and verified separate, not combined** (56/56, SSE 0), and the surviving combined-form error in the cited AIP draft was flagged and fixed. See C.1.3.
|
||||
5. **Register separation introduced in C.1**: schedule PRICE, MEASURED-LIVE, and RECEIPT are now three distinct columns rather than one "Marginal gas" column.
|
||||
6. **C.3 ratio table** rebased on live-measured values and given a P-256 baseline alongside ecrecover.
|
||||
|
||||
**To measure `[MEASURE]` or verify `[VERIFY]` (open items):**
|
||||
- `[MEASURE]` Observed live mainnet sustained TPS over a real block window.
|
||||
@ -397,7 +623,8 @@ domains above with pinned commands, so a third party has one entry point]`
|
||||
- `[MEASURE]` Halo2 proving time.
|
||||
- `[MEASURE]` Wall-clock verification latency per prover.
|
||||
- `[MEASURE]` Consolidated top-level aerenew/REPRODUCE.md.
|
||||
- `[MEASURE]` **Re-run the five PQC verify-and-record transactions on mainnet 2800 and publish their tx hashes**, replacing the chain-28099 fork receipts. The precompiles are live, so this is now possible and is the single highest-value provenance fix left in this report.
|
||||
- `[VERIFY]` The explicit block-space arithmetic behind 273,000 TPS.
|
||||
- `[VERIFY]` Which genesis gas limit is live on 2800 (40M vs effectively unbounded).
|
||||
- `[VERIFY]` ECDSA ecrecover 3,000 is a fixed protocol constant (not Aere-specific).
|
||||
- ~~`[VERIFY]` Which genesis gas limit is live on 2800 (40M vs effectively unbounded).~~ **CLOSED, measured 2026-08-01:** header `gasLimit` at head block 11,810,041 is `0x1fffffffffffff` = 9,007,199,254,740,991, the effectively-unbounded value, identical to genesis. **Opened in its place:** the EIP-7825 per-transaction cap of 2^24 is **NOT MEASURED** and cannot be inferred from the block limit.
|
||||
- ~~`[VERIFY]` ECDSA ecrecover 3,000~~, **CLOSED**, measured 3,000 on live 2800.
|
||||
- `[VERIFY]` The "AerePQAggregate" contract name (not found in repo; aggregation is a documented roadmap direction).
|
||||
|
||||
@ -81,7 +81,7 @@ contract (for example the ERC-20 asset) so its storage is observable inside a ru
|
||||
|
||||
#### 2.a.1 `AereSink` (immutable 3-bucket router)
|
||||
|
||||
Source: `aerenew/contracts/contracts/sink/AereSink.sol`. Read confirms:
|
||||
Source: `aere-contracts/contracts/sink/AereSink.sol`. Read confirms:
|
||||
|
||||
- `is ReentrancyGuard` only. **No `Ownable`, no admin role, no setters** (`grep` for `onlyOwner`,
|
||||
`setBucket`, `setRecipient` returns nothing; the NatSpec asserts this and the source matches).
|
||||
@ -165,7 +165,7 @@ summary for `IAereV2Router.swapExactTokensForTokens` that forwards only to `reci
|
||||
|
||||
#### 2.a.2 `AereCoinbaseSplitterV2`
|
||||
|
||||
Source: `aerenew/contracts/contracts/AereCoinbaseSplitterV2.sol`. Read confirms:
|
||||
Source: `aere-contracts/contracts/AereCoinbaseSplitterV2.sol`. Read confirms:
|
||||
|
||||
- `is Ownable, ReentrancyGuard`. Mutable `uint256 burnBps` (default 3750), `uint256 sinkBps` (default 1500).
|
||||
- Constants: `BPS = 10000`, `MAX_BURN_BPS = 5000`, `MAX_SINK_BPS = 3000`, `SINK_CHANGE_TIMELOCK = 7 days`.
|
||||
@ -214,7 +214,7 @@ rule onlyOwnerChangesBpsWithinCaps(method f, env e, calldataarg args) {
|
||||
|
||||
#### 2.a.3 `AereFeeBurnVault`
|
||||
|
||||
Source: `aerenew/contracts/contracts/AereFeeBurnVault.sol`. Read confirms:
|
||||
Source: `aere-contracts/contracts/AereFeeBurnVault.sol`. Read confirms:
|
||||
|
||||
- No `Ownable`, no admin. Functions: `receive()`, `burn()` (payable), `burnToken(address,uint256)`,
|
||||
`sweepToZero()`, `currentAEREBalance()` view. **There is no `withdraw`, no `rescue`, no admin escape.**
|
||||
@ -269,7 +269,7 @@ rule sweepGoesOnlyToBurnSink(env e, address r) {
|
||||
|
||||
### 2.b Tokenomics: `sAERE` (ERC-4626 staking receipt)
|
||||
|
||||
Target the corrected `sAEREv2`. Source: `aerenew/contracts/contracts/staking/sAEREv2.sol` (the R7-fixed
|
||||
Target the corrected `sAEREv2`. Source: `aere-contracts/contracts/staking/sAEREv2.sol` (the R7-fixed
|
||||
redeploy; the live `sAERE` at `0xA212...50b0` shares the same interface but not the R7 fix, see the note
|
||||
on SR-RULE-3). Read confirms:
|
||||
|
||||
@ -353,7 +353,7 @@ counterexample) on the un-fixed `sAERE.sol`, matching the R7 finding in
|
||||
|
||||
#### 2.c.1 `AereCryptoRegistry`
|
||||
|
||||
Source: `aerenew/contracts/contracts/pqc/AereCryptoRegistry.sol`. Read confirms:
|
||||
Source: `aere-contracts/contracts/pqc/AereCryptoRegistry.sol`. Read confirms:
|
||||
|
||||
- `is Ownable`. Storage: `mapping(uint256 => Algorithm) _algorithms`, `uint256 _count`, `bool _seeded`.
|
||||
Ids are 1-based and monotonic (`_count += 1` in `_addAlgorithm`, never decremented).
|
||||
@ -446,7 +446,7 @@ rule resolveActiveReturnsActive(env e, uint256 startId) {
|
||||
|
||||
#### 2.c.2 `AerePQCKeyRegistry` (the PQC key registry)
|
||||
|
||||
Source: `aerenew/contracts/contracts/pqc/AerePQCKeyRegistry.sol`. Read confirms:
|
||||
Source: `aere-contracts/contracts/pqc/AerePQCKeyRegistry.sol`. Read confirms:
|
||||
|
||||
- Permissionless (no `Ownable`). Storage: `KeyRecord[] _keys` (append-only; keyId is the array index,
|
||||
pushed in `_registerWithPoP`, never removed), `mapping(address => uint64) identityNonce` (monotonic),
|
||||
@ -528,8 +528,8 @@ AerePQCKeyRegistry rule report]`
|
||||
|
||||
### 2.d Threshold / precompile callers: the duplicate-committee-key fix
|
||||
|
||||
Source: `aerenew/contracts/contracts/mpc/AereThresholdAccount.sol` (ERC-4337 t-of-n PQC account) and the
|
||||
shared library `aerenew/contracts/contracts/mpc/AerePQCThreshold.sol`. The sibling
|
||||
Source: `aere-contracts/contracts/mpc/AereThresholdAccount.sol` (ERC-4337 t-of-n PQC account) and the
|
||||
shared library `aere-contracts/contracts/mpc/AerePQCThreshold.sol`. The sibling
|
||||
`AereThresholdPQCRegistry.registerCommittee(uint8,uint8,bytes[])` carries the identical fix. Read confirms:
|
||||
|
||||
- `initialize(address _entryPoint, uint8 _scheme, uint8 _threshold, bytes[] pubKeys)` is factory-only and
|
||||
@ -540,7 +540,7 @@ shared library `aerenew/contracts/contracts/mpc/AerePQCThreshold.sol`. The sibli
|
||||
`seen` bitmask in `_countMem`, and returns success only when `valid >= threshold`.
|
||||
- `scheme`, `threshold`, `size`, `membersHash`, `_pubKeys` are immutable after `initialize`.
|
||||
|
||||
This is the exact target of `aerenew/formal-consensus/threshold_account_smt.py` (P1: with distinct keys,
|
||||
This is the exact target of `aere-research/formal-consensus/threshold_account_smt.py` (P1: with distinct keys,
|
||||
no single keyholder can reach threshold `t >= 2`). The CVL splits it into the part provable at bytecode
|
||||
level and the combinatorial part that stays in z3, keeping the same boundary the z3 file itself declares.
|
||||
|
||||
@ -681,9 +681,9 @@ Example run config (Certora conf files are JSON):
|
||||
// certora/conf/burnstack.conf
|
||||
{
|
||||
"files": [
|
||||
"contracts/sink/AereSink.sol",
|
||||
"contracts/AereCoinbaseSplitterV2.sol",
|
||||
"contracts/AereFeeBurnVault.sol",
|
||||
"aere-contracts/contracts/sink/AereSink.sol",
|
||||
"aere-contracts/contracts/AereCoinbaseSplitterV2.sol",
|
||||
"aere-contracts/contracts/AereFeeBurnVault.sol",
|
||||
"certora/harness/DummyERC20A.sol"
|
||||
],
|
||||
"verify": "AereSink:certora/specs/AereSink.spec",
|
||||
@ -700,7 +700,7 @@ Example run config (Certora conf files are JSON):
|
||||
// certora/conf/sAEREv2.conf
|
||||
{
|
||||
"files": [
|
||||
"contracts/staking/sAEREv2.sol",
|
||||
"aere-contracts/contracts/staking/sAEREv2.sol",
|
||||
"certora/harness/DummyERC20A.sol"
|
||||
],
|
||||
"verify": "sAEREv2:certora/specs/sAEREv2.spec",
|
||||
@ -716,8 +716,8 @@ Example run config (Certora conf files are JSON):
|
||||
// certora/conf/registries.conf
|
||||
{
|
||||
"files": [
|
||||
"contracts/pqc/AereCryptoRegistry.sol",
|
||||
"contracts/pqc/AerePQCKeyRegistry.sol"
|
||||
"aere-contracts/contracts/pqc/AereCryptoRegistry.sol",
|
||||
"aere-contracts/contracts/pqc/AerePQCKeyRegistry.sol"
|
||||
],
|
||||
"verify": "AereCryptoRegistry:certora/specs/AereCryptoRegistry.spec",
|
||||
"solc": "solc0.8.23",
|
||||
@ -731,7 +731,7 @@ Example run config (Certora conf files are JSON):
|
||||
// certora/conf/threshold.conf
|
||||
{
|
||||
"files": [
|
||||
"contracts/mpc/AereThresholdAccount.sol",
|
||||
"aere-contracts/contracts/mpc/AereThresholdAccount.sol",
|
||||
"contracts/mpc/AerePQCThreshold.sol"
|
||||
],
|
||||
"verify": "AereThresholdAccount:certora/specs/AereThresholdAccount.spec",
|
||||
@ -785,14 +785,14 @@ and we do not have one.
|
||||
|
||||
| Target | Source file read | CVL status |
|
||||
|---|---|---|
|
||||
| `AereSink` | `contracts/sink/AereSink.sol` | Real CVL against real getters (`BURN_BPS`, `BURN_VAULT`, `flush`, `sweepDust`). AERE-branch rules exact; router branch is a marked `[MEASURE]` extension. |
|
||||
| `AereCoinbaseSplitterV2` | `contracts/AereCoinbaseSplitterV2.sol` | Real CVL (`burnBps`, `sinkBps`, `MAX_BURN_BPS`, `setBps`, `owner`). |
|
||||
| `AereFeeBurnVault` | `contracts/AereFeeBurnVault.sol` | Real CVL (`totalBurnedAERE`, `sweepToZero`, `nativeBalances`). |
|
||||
| `sAEREv2` | `contracts/staking/sAEREv2.sol` | Real CVL (`totalAssets`, `undistributedRewards`, `sync`, `convertToAssets`). SR-RULE-4 designed to distinguish v2 from the un-fixed v1. |
|
||||
| `AereCryptoRegistry` | `contracts/pqc/AereCryptoRegistry.sol` | Real CVL (`getAlgorithm`, `statusOf`, `verify`, `resolveActive`, `Status` enum). |
|
||||
| `AerePQCKeyRegistry` | `contracts/pqc/AerePQCKeyRegistry.sol` | Real CVL (`keyCount`, `ownerOf`, `statusOf`, `verifyWithKey`, `identityNonce`). K1/K2 keccak domain-separation flagged `[MEASURE]` extension. |
|
||||
| `AereThresholdAccount` + `AerePQCThreshold` | `contracts/mpc/AereThresholdAccount.sol`, `AerePQCThreshold.sol` | Real CVL for init bounds / set-once / distinct-key (TH-1/2/3). The P1 keyholder-counting theorem is an abstract-ghost model, same boundary as `threshold_account_smt.py`. |
|
||||
| `AereThresholdPQCRegistry` | `contracts/mpc/AereThresholdPQCRegistry.sol` | Not separately specced here; its `registerCommittee` dup-key guard is byte-identical to `AereThresholdAccount.initialize`, so TH-RULE-3 transfers. Adding a dedicated spec is a `[MEASURE]` follow-up. |
|
||||
| `AereSink` | `aere-contracts/contracts/sink/AereSink.sol` | Real CVL against real getters (`BURN_BPS`, `BURN_VAULT`, `flush`, `sweepDust`). AERE-branch rules exact; router branch is a marked `[MEASURE]` extension. |
|
||||
| `AereCoinbaseSplitterV2` | `aere-contracts/contracts/AereCoinbaseSplitterV2.sol` | Real CVL (`burnBps`, `sinkBps`, `MAX_BURN_BPS`, `setBps`, `owner`). |
|
||||
| `AereFeeBurnVault` | `aere-contracts/contracts/AereFeeBurnVault.sol` | Real CVL (`totalBurnedAERE`, `sweepToZero`, `nativeBalances`). |
|
||||
| `sAEREv2` | `aere-contracts/contracts/staking/sAEREv2.sol` | Real CVL (`totalAssets`, `undistributedRewards`, `sync`, `convertToAssets`). SR-RULE-4 designed to distinguish v2 from the un-fixed v1. |
|
||||
| `AereCryptoRegistry` | `aere-contracts/contracts/pqc/AereCryptoRegistry.sol` | Real CVL (`getAlgorithm`, `statusOf`, `verify`, `resolveActive`, `Status` enum). |
|
||||
| `AerePQCKeyRegistry` | `aere-contracts/contracts/pqc/AerePQCKeyRegistry.sol` | Real CVL (`keyCount`, `ownerOf`, `statusOf`, `verifyWithKey`, `identityNonce`). K1/K2 keccak domain-separation flagged `[MEASURE]` extension. |
|
||||
| `AereThresholdAccount` + `AerePQCThreshold` | `aere-contracts/contracts/mpc/AereThresholdAccount.sol`, `AerePQCThreshold.sol` | Real CVL for init bounds / set-once / distinct-key (TH-1/2/3). The P1 keyholder-counting theorem is an abstract-ghost model, same boundary as `threshold_account_smt.py`. |
|
||||
| `AereThresholdPQCRegistry` | `aere-contracts/contracts/mpc/AereThresholdPQCRegistry.sol` | Not separately specced here; its `registerCommittee` dup-key guard is byte-identical to `AereThresholdAccount.initialize`, so TH-RULE-3 transfers. Adding a dedicated spec is a `[MEASURE]` follow-up. |
|
||||
|
||||
No target required a `[VERIFY: locate <contract>.sol]` flag: every contract named in the task was located
|
||||
and read. The only interface caveat is the sAERE target selection, which points at `sAEREv2.sol` (the
|
||||
|
||||
@ -1,60 +1,108 @@
|
||||
# Spec 10: Aere Compute Market V3 (proof-carrying DePIN)
|
||||
|
||||
Revised 2026-07-20. The prior revision of this file described V3 before the liveness review; the
|
||||
sections below supersede it.
|
||||
|
||||
## Delivered
|
||||
|
||||
1. `aerenew/contracts/contracts/depin/AereComputeMarketV3.sol` (new; deployed V1/V2 untouched)
|
||||
2. `aerenew/contracts/test/AereComputeMarketV3.test.js` (13 tests, all passing)
|
||||
3. `aerenew/docs/AERE-COMPUTE-MARKET-V3.md`
|
||||
1. `aere-contracts/contracts/depin/AereComputeMarketV3.sol` (new; deployed V1/V2 untouched)
|
||||
2. `aere-contracts/test/AereComputeMarketV3.test.js` (14 tests: safety)
|
||||
3. `aerenew/contracts/test/AereComputeMarketV3.liveness.test.js` (14 tests: liveness and griefing, NEW)
|
||||
4. `aere-research/formal-consensus/computemarket_smt.py` (z3 solvency model, extended for the new exits)
|
||||
5. `aerenew/docs/AERE-COMPUTE-MARKET-V3.md`
|
||||
|
||||
## What it does
|
||||
|
||||
Proof-carrying compute marketplace. Requester posts a job (specHash, reward escrow, deadline,
|
||||
verification mode); provider claims + runs off-chain; result acceptance depends on the mode:
|
||||
Requester posts a job (specHash, reward escrow, deadline, verification mode); provider claims and runs
|
||||
off-chain; result acceptance depends on the mode:
|
||||
|
||||
- REPLAY (0): deterministic recompute. Result bytes emitted; challenge window; dispute records the
|
||||
challenger's recomputed hash; arbiter resolves.
|
||||
- ZK_VERIFIED (1): SP1 proof verified on-chain via the deployed SP1 gateway (ISP1Verifier). publicValues
|
||||
bound to the job (abi.encode(specHash, resultHash), specHash must match). Paid in the SAME tx, only on
|
||||
a valid proof. No other pay path exists for a ZK job.
|
||||
- OPTIMISTIC (2): challenge window + provider bond. Successful dispute slashes provider bond to the
|
||||
challenger, refunds requester.
|
||||
- REPLAY (0): deterministic recompute. Result bytes emitted; challenge window; a dispute records the
|
||||
challenger's recomputed hash; arbiter resolves. Cheap, and only sound for deterministic work.
|
||||
- ZK_VERIFIED (1): SP1 proof verified on-chain via the deployed SP1 gateway (ISP1Verifier).
|
||||
publicValues bound to the job (abi.encode(specHash, resultHash), specHash must match). Paid in the
|
||||
SAME tx, only on a valid proof. No other pay path exists for a ZK job. Strongest, and expensive.
|
||||
- OPTIMISTIC (2): challenge window + provider bond. A successful dispute slashes the provider bond to
|
||||
the challenger and refunds the requester. Cheap, but needs a watcher and a bond.
|
||||
|
||||
PQC settlement path: any job can set pqcSettlement + an 897-byte Falcon-512 key. Final payout then
|
||||
requires a Falcon-512 signature (verified via live precompile 0x0AE1) over a digest binding
|
||||
(chainId, contract, jobId, provider, token, amount, resultHash). Fail-closed. This is payout
|
||||
authorization only; it does NOT make consensus post-quantum (documented).
|
||||
## What changed in the 2026-07-20 review
|
||||
|
||||
Settlement asset: native AERE (address(0)) or an allowlisted ERC-20 (governance-gated allowlist).
|
||||
Bonds always native AERE. No new token.
|
||||
The prior V3 was sound on SAFETY (nobody is paid without evidence) and had three holes in LIVENESS
|
||||
(funds that could never leave the contract). All three are now closed and tested.
|
||||
|
||||
## Fail-closed / invariants (all tested)
|
||||
1. FALCON KEY MOVED FROM REQUESTER TO PROVIDER. Previously the requester supplied the settlement key
|
||||
at postJob, which handed the requester a permanent veto over paying for correct work: never sign,
|
||||
never pay. The key is now the PROVIDER's, registered at claimJob. This also makes the security
|
||||
claim coherent, since it is the provider's payout authorization being hardened.
|
||||
2. `resolveByTimeout` (NEW). An arbiter that never resolves previously froze the reward and both bonds
|
||||
forever. After ARBITRATION_TIMEOUT (14 days) anyone can unwind a stale dispute NEUTRALLY: reward to
|
||||
the requester, both bonds home, nothing slashed.
|
||||
3. `reclaimUnsettled` (NEW). A pqc job whose provider never signs previously locked the escrow forever.
|
||||
After the challenge window plus PQC_SETTLEMENT_GRACE (7 days) the requester reclaims the reward and
|
||||
the provider bond is RETURNED, not slashed. Guarded so it cannot be used on a non-pqc job.
|
||||
4. `submitResultRef` (NEW). Outputs too large for calldata commit as (keccak256 hash, URI). Data
|
||||
availability is explicitly NOT solved; see the design doc.
|
||||
|
||||
## PQC: where it is used and where it is deliberately not
|
||||
|
||||
Used: the final payout release, optionally per job, via Falcon-512 at the live precompile 0x0AE1 over
|
||||
a digest binding (chainId, contract, jobId, provider, token, amount, resultHash). Fail-closed.
|
||||
|
||||
NOT used: posting, claiming, submitting, disputing, arbitration. None of those move value to a new
|
||||
owner, so ECDSA is sufficient and Falcon there would be decorative.
|
||||
|
||||
Two boundaries stated plainly in the doc:
|
||||
- Consensus is classical secp256k1 ECDSA QBFT. Nothing here changes that.
|
||||
- The ZK proofs are classical BN254 and Shor-breakable. pqcSettlement on a ZK job hardens WHO RECEIVES
|
||||
the payout; it does NOT make the proof quantum-safe.
|
||||
|
||||
## Fail-closed / invariants
|
||||
|
||||
- Escrow solvency: totalLiabilities[token] = sum(open rewards + posted bonds); contract balance always
|
||||
>= liabilities per asset. isSolvent() view. Asserted after every mutating step in every test.
|
||||
- No double-pay: terminal statuses (Paid/Refunded/Slashed) reached once; nonReentrant; CEI ordering.
|
||||
>= liabilities per asset. isSolvent() view; asserted after every mutating step in every test.
|
||||
- No double-pay: terminal statuses reached once; nonReentrant; CEI ordering.
|
||||
- No pay-without-proof (ZK): settle inside submitResultZK after verifyProof (reverts on invalid).
|
||||
- No admin drain: no owner, no sweep. Arbiter only routes a DISPUTED job's escrow; governance only
|
||||
flips a token-allowlist bool.
|
||||
- Fee-on-transfer/rebasing reward tokens rejected at escrow (received must equal stated reward).
|
||||
- LIVENESS: every job has an exit no single party can block (reclaimExpired, permissionless finalize,
|
||||
resolveByTimeout, reclaimUnsettled).
|
||||
|
||||
## Real test result
|
||||
## MEASURED results, 2026-07-20
|
||||
|
||||
`npx hardhat test test/AereComputeMarketV3.test.js` (from aerenew/contracts):
|
||||
13 passing (~2s). Covers: ZK pay-on-valid + reject-invalid + wrong-spec rejection; OPTIMISTIC
|
||||
finalize + dispute-slash; REPLAY dispute (provider upheld) + off-chain re-run match; ERC-20 reward
|
||||
allowlist accept/reject; Falcon valid-accept + tampered-reject + wrong-amount-reject +
|
||||
sig-on-nonpqc-job reject; solvency across a mixed batch; deadline reclaim with bond slash.
|
||||
From `aerenew/contracts`:
|
||||
|
||||
`npx hardhat compile`
|
||||
-> `Compiled 1 Solidity file successfully (evm target: paris).`
|
||||
|
||||
`npx hardhat test aere-contracts/test/AereComputeMarketV3.test.js test/AereComputeMarketV3.liveness.test.js`
|
||||
-> `28 passing (7s)`, 0 failing.
|
||||
|
||||
From `aerenew/formal-consensus`, `python computemarket_smt.py`
|
||||
-> 21 PROVED, 4 CEX-FOUND (negative controls firing as designed), 0 FAILED.
|
||||
|
||||
Full-repo `npx hardhat test` did NOT complete: it segfaults (node exit 139) inside the Falcon KAT
|
||||
suites. PRE-EXISTING and unrelated to this work: `npx hardhat test test/AereFalcon1024Verifier.test.js`
|
||||
alone reproduces the same segfault on a file this task never touched. Excluding the 8 heavy Falcon-KAT
|
||||
files, the run reached 1044 passing / 0 failing before a 10-minute harness timeout truncated it.
|
||||
|
||||
## Grounding used
|
||||
|
||||
- Built on AereComputeMarketV2 job/escrow model (depin/).
|
||||
- ZK: ISP1Verifier.sol + SP1VerifierGateway.sol; deployed gateway 0x9ca479C8c52C0EbB4599319a36a5a017BCC70628.
|
||||
- Built on the AereComputeMarketV2 job/escrow model (depin/).
|
||||
- ZK: ISP1Verifier.sol + SP1VerifierGateway.sol; deployed gateway
|
||||
0x9ca479C8c52C0EbB4599319a36a5a017BCC70628.
|
||||
- Falcon: input encoding + fail-closed raw-32-byte return pattern from AerePQCMessageVerifier.sol;
|
||||
test uses MockPQCPrecompile(1) @0x0AE1 and MockSp1Verifier (reverts on invalid), MockERC20Lending.
|
||||
tests use MockPQCPrecompile(1) @0x0AE1, MockSp1Verifier (reverts on invalid), MockERC20Lending.
|
||||
|
||||
## Flags
|
||||
|
||||
- [VERIFY] ZK path tested vs MockSp1Verifier (mirrors gateway revert-on-invalid); real gateway wired at deploy.
|
||||
- [VERIFY] Falcon path tested vs MockPQCPrecompile; real wire encoding KAT-proven elsewhere; 0x0AE1 live on 2800.
|
||||
- [MEASURE] Real GPU supply, off-chain provers, real SP1 proving are external (adoption, not code).
|
||||
- Not deployed; founder-gated.
|
||||
- [VERIFY] ZK path tested vs MockSp1Verifier (mirrors gateway revert-on-invalid); real gateway wired at
|
||||
deploy. Real SP1 proving has NOT been run against V3.
|
||||
- [VERIFY] Falcon path tested vs MockPQCPrecompile. Real Falcon signing has NOT been run against V3;
|
||||
the wire encoding is KAT-proven elsewhere and 0x0AE1 is live on 2800.
|
||||
- [DEPLOY DEPENDENCY] A pqcSettlement job is unsettleable on any chain lacking a live 0x0AE1, since
|
||||
_falconVerify fails closed. Deploy on 2800 or a precompile-carrying testnet, not a generic EVM chain.
|
||||
- [MEASURE] Real GPU supply, off-chain provers and real SP1 proving are external (adoption, not code).
|
||||
- [PUBLIC REPO DRIFT] `aerenew/publish-bundle/aere-contracts/.../AereComputeMarketV3.sol` still holds
|
||||
the PRE-review V3 (requester-held key, no timeout exits). That is the version mirrored to the public
|
||||
repo. Re-syncing the bundle is a publish action and is FOUNDER-GATED; not done here.
|
||||
- NOT DEPLOYED, NOT AUDITED. Founder-gated.
|
||||
|
||||
@ -15,8 +15,15 @@ V3 unifies the verification rails that were split across the earlier coordinatio
|
||||
post-quantum settlement gate. The deployed V1 and V2 DePIN contracts are untouched; V3 is a new,
|
||||
independent contract.
|
||||
|
||||
Source: `aerenew/contracts/contracts/depin/AereComputeMarketV3.sol`
|
||||
Test: `aerenew/contracts/test/AereComputeMarketV3.test.js` (13 passing)
|
||||
Source: `aere-contracts/contracts/depin/AereComputeMarketV3.sol`
|
||||
Tests:
|
||||
- `aere-contracts/test/AereComputeMarketV3.test.js` (14 cases: safety, "nobody is paid without evidence")
|
||||
- `aerenew/contracts/test/AereComputeMarketV3.liveness.test.js` (14 cases: liveness and griefing,
|
||||
"no single party can freeze the escrow")
|
||||
- `aere-research/formal-consensus/computemarket_smt.py` (z3 model of the escrow-solvency invariant)
|
||||
|
||||
MEASURED 2026-07-20, `npx hardhat test aere-contracts/test/AereComputeMarketV3.test.js test/AereComputeMarketV3.liveness.test.js`
|
||||
-> `28 passing (7s)`, 0 failing.
|
||||
|
||||
## The three verification modes
|
||||
|
||||
@ -50,7 +57,7 @@ arbiter: verifiable inference, zk coprocessing, anything where the requester wan
|
||||
rather than after a delay. The cost is that the provider must run a real prover.
|
||||
|
||||
The verifier reference. V3 calls the `ISP1Verifier` interface
|
||||
(`aerenew/contracts/contracts/zkverify/ISP1Verifier.sol`), the same interface implemented by the
|
||||
(`aere-contracts/contracts/zkverify/ISP1Verifier.sol`), the same interface implemented by the
|
||||
deployed `SP1VerifierGateway` at `0x9ca479C8c52C0EbB4599319a36a5a017BCC70628` on Aere Network chain
|
||||
2800. V3 does not reimplement proof verification; it references and calls the existing gateway. The
|
||||
gateway routes on the proof's first four bytes to the correct SP1 verifier and reverts on an invalid
|
||||
@ -69,26 +76,59 @@ lying.
|
||||
|
||||
## Post-quantum settlement path
|
||||
|
||||
Any job (in any mode) can set `pqcSettlement = true` and register an 897-byte Falcon-512 settlement
|
||||
key. When set, the final release of funds to the provider additionally requires a Falcon-512 signature
|
||||
by that key over a domain-separated settlement digest binding `(chainId, contract, jobId, provider,
|
||||
token, amount, resultHash)`. The signature is verified IN FULL on-chain by the live native precompile
|
||||
at `0x0AE1` (activated on Aere mainnet 2800 at block 9,189,161), using the same input encoding proven
|
||||
against the live precompile in `AerePQCMessageVerifier`.
|
||||
Any job in any mode can set `pqcSettlement = true`. When set, the final release of funds additionally
|
||||
requires a Falcon-512 signature over a domain-separated settlement digest binding `(chainId, contract,
|
||||
jobId, provider, token, amount, resultHash)`. The signature is verified IN FULL on-chain by the live
|
||||
native precompile at `0x0AE1` (activated on Aere mainnet 2800 at block 9,189,161), using the same input
|
||||
encoding proven against the live precompile in `AerePQCMessageVerifier`.
|
||||
|
||||
The point: the payout authorization is post-quantum. A quantum adversary who forged the classical
|
||||
secp256k1 transaction sender still cannot authorize a payout without the Falcon private key. The digest
|
||||
binds the exact payout figure and result, so an authorization can never be replayed to another job,
|
||||
chain, contract, or amount. A tampered or missing signature reverts the release and nothing is paid
|
||||
(fail-closed).
|
||||
### Whose key, and why it matters
|
||||
|
||||
Scope boundary. This gate authorizes PAYOUTS. It does NOT make Aere consensus post-quantum. Blocks
|
||||
remain Besu QBFT with classical secp256k1 validators. What is post-quantum here is the authenticity of
|
||||
the settlement authorization, not block production.
|
||||
The settlement key is the PROVIDER's, and the provider registers it when it claims the job. This is the
|
||||
single most consequential design decision in the PQC path, so it is worth stating why.
|
||||
|
||||
Disputed jobs are settled by the arbiter's ruling rather than the happy-path release, so the Falcon
|
||||
gate applies to the normal accept/finalize/ZK settle paths; arbiter resolution of a disputed job is the
|
||||
arbiter's authority.
|
||||
The property being bought is: a quantum adversary who has broken the provider's classical secp256k1
|
||||
identity still cannot make this contract pay out that provider's earnings, because the payout also
|
||||
needs a Falcon private key that Shor's algorithm does not reach. That hardens the highest-value
|
||||
authorization in the system, which is the one that moves money to a new owner.
|
||||
|
||||
Binding the key to the REQUESTER instead would have been actively harmful. The requester would gain a
|
||||
permanent veto over paying for correct work: it could simply never sign, and the provider could never
|
||||
be paid. That converts a solved failure mode (a permissionless `finalize` means the buyer's cooperation
|
||||
is never required) back into an unsolved one. An earlier revision of this contract had the key on the
|
||||
requester; it was moved to the provider precisely because of this.
|
||||
|
||||
### Where PQC is deliberately NOT used
|
||||
|
||||
Posting, claiming, submitting, disputing and arbitration are all plain ECDSA, on purpose.
|
||||
|
||||
None of those operations move value to a new owner. The worst a forged claim or submission achieves is
|
||||
the loss of the forger's own bond. Disputes are adjudicated on evidence (a recomputed result hash),
|
||||
not on who signed the challenge. Adding Falcon signatures to those paths would cost calldata and gas
|
||||
and buy no additional guarantee. A design that reaches for post-quantum signatures on every entrypoint
|
||||
is marketing, not engineering, so this one does not.
|
||||
|
||||
### Two scope boundaries, stated plainly
|
||||
|
||||
CONSENSUS IS NOT POST-QUANTUM. Aere consensus is classical secp256k1 ECDSA QBFT. Blocks are produced
|
||||
and sealed by classical validator signatures. The post-quantum material in this contract is at the
|
||||
signature and settlement layer only. Nothing here changes block production.
|
||||
|
||||
THE ZK PROOFS ARE NOT POST-QUANTUM. The SP1 gateway verifies Groth16/PLONK proofs over the BN254
|
||||
pairing curve. BN254 security rests on the hardness of discrete logarithms, which Shor's algorithm
|
||||
breaks. A `ZK_VERIFIED` job's proof is therefore CLASSICAL and Shor-breakable, and the on-chain
|
||||
verifier is a classical verifier.
|
||||
|
||||
The consequence is specific and should not be glossed: setting `pqcSettlement = true` on a
|
||||
`ZK_VERIFIED` job hardens WHO MAY RECEIVE the payout. It does NOT make the correctness proof
|
||||
quantum-safe. Against an adversary with a cryptographically relevant quantum computer, that adversary
|
||||
could forge a BN254 proof for a false result, and the Falcon gate would then faithfully authorize
|
||||
payment for provably-wrong work to the legitimate provider key. The combination reads stronger than it
|
||||
is, which is exactly why it is written out here rather than left implicit.
|
||||
|
||||
If you need post-quantum correctness rather than post-quantum payout authorization, the honest answer
|
||||
today is REPLAY mode, whose security rests on keccak256 (a hash, with only a Grover square-root
|
||||
speedup, not a Shor break) plus the ability of any watcher to re-execute.
|
||||
|
||||
## Escrow-solvency guarantee
|
||||
|
||||
@ -121,36 +161,192 @@ states.
|
||||
- Deadlines. A claimed job that misses its deadline without a submission lets the requester reclaim the
|
||||
reward and slashes the provider bond to the requester.
|
||||
|
||||
## Failure modes
|
||||
|
||||
A marketplace that only works when everyone behaves is not a marketplace. These are the ways this one
|
||||
is attacked, and what happens in each case. Each has a test in
|
||||
`test/AereComputeMarketV3.liveness.test.js` unless marked otherwise.
|
||||
|
||||
### The provider takes the job and vanishes
|
||||
|
||||
The provider posts a bond to claim. If the deadline passes with no submission, `reclaimExpired` returns
|
||||
the reward to the requester AND slashes the provider's bond to the requester. Vanishing is strictly
|
||||
loss-making, and the requester is compensated for the wasted deadline. A late submission is refused.
|
||||
|
||||
Residual risk: a provider can still grief by claiming jobs it never intends to run, burning the
|
||||
requester's time until each deadline expires. The bond prices this but does not prevent it. A
|
||||
reputation layer or a per-provider claim limit would; neither is in V3.
|
||||
|
||||
### The buyer refuses to acknowledge correct work
|
||||
|
||||
Fully solved for non-PQC jobs, and it is the reason `finalize` exists. Once the challenge window
|
||||
closes, `finalize` is PERMISSIONLESS: any address, including the provider itself or an unrelated
|
||||
bystander, can call it and the reward is released. The requester's cooperation is never required and
|
||||
the requester has no veto. `acceptResult` exists only as an early-release convenience.
|
||||
|
||||
For a PQC job the same holds, because the required signature is the PROVIDER's, not the requester's.
|
||||
The requester still cannot block payment. This is the direct payoff of that key-ownership decision.
|
||||
|
||||
### The provider never produces its Falcon authorization
|
||||
|
||||
A PQC job can only be paid with the provider's Falcon signature. If the provider loses the key or
|
||||
simply stops, the reward would sit in escrow forever. `reclaimUnsettled` closes this: after the
|
||||
challenge window plus `PQC_SETTLEMENT_GRACE` (7 days), the requester reclaims the reward and the
|
||||
provider's bond is RETURNED to the provider, not slashed.
|
||||
|
||||
The bond is returned deliberately. Failing to sign is not proven fraud, so slashing would punish what
|
||||
may be simple key loss. The provider forfeits the reward, which puts the entire cost of silence on the
|
||||
only party that holds the key and wants the money. Before the grace period elapses this path reverts,
|
||||
so a requester cannot use it to dodge paying for correct work.
|
||||
|
||||
### The arbiter never resolves a dispute
|
||||
|
||||
This was the worst hole in the design, and it is worth being blunt: an arbitrated escrow whose arbiter
|
||||
goes offline, is coerced, or is censored freezes the reward AND both bonds permanently, with no
|
||||
recovery. `resolveByTimeout` closes it. After `ARBITRATION_TIMEOUT` (14 days) ANY address can unwind a
|
||||
stale dispute NEUTRALLY: the reward returns to the requester, and both bonds return to their posters.
|
||||
|
||||
Nothing is slashed, because nothing was adjudicated. An absent arbiter must not be able to enrich
|
||||
either side by doing nothing, since otherwise "make the arbiter unavailable" becomes a strategy. The
|
||||
z3 model carries a negative control showing that a timeout unwind which tries to pick a winner
|
||||
under-backs the escrow.
|
||||
|
||||
Residual risk: this weakens the dispute system into "a dispute the arbiter ignores becomes a no-sale".
|
||||
A provider who did correct work and was frivolously challenged loses the reward if the arbiter never
|
||||
rules. That is a real cost, accepted because permanent fund lock is worse. Arbiter liveness remains a
|
||||
trust assumption; V3 bounds the damage rather than removing it.
|
||||
|
||||
### A challenger is right but nobody is watching
|
||||
|
||||
NOT SOLVED, and this is the honest weak point of both optimistic modes.
|
||||
|
||||
The security of REPLAY and OPTIMISTIC rests entirely on at least one honest party re-running the work
|
||||
and disputing within the window. If nobody watches, a provider can submit garbage and be paid by
|
||||
`finalize` with no recourse. The contract cannot manufacture a watcher.
|
||||
|
||||
What V3 does provide: the full result bytes are emitted on-chain for inline jobs, so watching requires
|
||||
no privileged access or private data feed; and a successful challenge pays the challenger the entire
|
||||
provider bond, so watching is profitable in proportion to that bond. What it does NOT provide: any
|
||||
guarantee that a watcher exists, any subsidy for watching a job that turns out to be honest, or any
|
||||
staking of watchers. The requester's practical defence is to be its own watcher, or to size the
|
||||
challenge window long enough for a third party to act.
|
||||
|
||||
Requesters who cannot rely on a watcher existing should use `ZK_VERIFIED`, which needs no watcher at
|
||||
all, and pay the proving cost. That is the real tradeoff between the modes.
|
||||
|
||||
### The job output is too large to put on chain
|
||||
|
||||
A 40 GB tensor checkpoint does not fit in calldata. A job can declare `offchainResult = true`, and the
|
||||
provider then calls `submitResultRef(id, resultHash, uri)`: the chain stores the binding keccak256
|
||||
COMMITMENT, and the URI is a retrieval hint.
|
||||
|
||||
DATA AVAILABILITY IS NOT SOLVED BY THIS. The contract cannot check that the URI resolves, that it keeps
|
||||
resolving, or that its contents hash to `resultHash`. If the provider serves nothing, a challenger
|
||||
cannot replay the work. The design's answer is that an unavailable result is indistinguishable from a
|
||||
wrong one and should be disputed as such; off-chain jobs remain disputable on identical terms. That is
|
||||
a coherent answer, not a complete one. Requesters who cannot tolerate it should require inline results
|
||||
or `ZK_VERIFIED`.
|
||||
|
||||
### Other paths
|
||||
|
||||
- Double-pay: every job reaches a terminal status exactly once; a second payout is guard-infeasible
|
||||
(proved in the z3 model; all fund-moving entrypoints are reentrancy-guarded).
|
||||
- Admin drain: there is no owner and no sweep. The arbiter can only route a DISPUTED job's escrow among
|
||||
that job's own requester, provider and challenger. Governance can only flip a token allowlist boolean.
|
||||
- Replay of a Falcon authorization: the digest binds chainId, contract, jobId, provider, token, amount
|
||||
and resultHash, so an authorization cannot be reused for another job, chain, contract, or figure.
|
||||
- Fee-on-transfer or rebasing reward tokens: rejected at escrow time.
|
||||
|
||||
## Job lifecycle (summary)
|
||||
|
||||
```
|
||||
postJob Open requester escrows reward (+ mode/pqc params)
|
||||
claimJob Claimed provider posts the required native-AERE bond (0 for ZK)
|
||||
submitResult Submitted REPLAY / OPTIMISTIC: result bytes emitted, window starts
|
||||
postJob Open requester escrows reward (+ mode / pqc / offchain params)
|
||||
claimJob Claimed provider posts the required native-AERE bond (0 for ZK) and,
|
||||
for a pqc job, registers ITS OWN Falcon-512 key
|
||||
submitResult Submitted REPLAY / OPTIMISTIC inline: result bytes emitted, window starts
|
||||
submitResultRef Submitted REPLAY / OPTIMISTIC off-chain: (hash, URI) committed, window starts
|
||||
submitResultZK Paid ZK_VERIFIED: proof verified on-chain, paid in the same tx
|
||||
acceptResult Paid requester accepts a Submitted result early
|
||||
finalize Paid anyone, after the window closes with no dispute
|
||||
finalize Paid ANYONE, after the window closes with no dispute
|
||||
dispute Disputed challenger posts a matching bond within the window
|
||||
resolveDispute Paid/Slashed arbiter rules; a bad result slashes the provider bond to the challenger
|
||||
resolveByTimeout Refunded ANYONE, after ARBITRATION_TIMEOUT: neutral unwind of a stale dispute
|
||||
reclaimUnsettled Refunded requester, after the window + PQC_SETTLEMENT_GRACE, if the provider
|
||||
never produced its Falcon authorization (bond returned, not slashed)
|
||||
cancelJob Refunded requester reclaims an unclaimed job's escrow
|
||||
reclaimExpired Refunded requester reclaims a claimed job that blew its deadline (bond slashed)
|
||||
```
|
||||
|
||||
Every job has an exit that no single party can block. That is the liveness claim, and each clause of it
|
||||
has a test.
|
||||
|
||||
## What V3 does NOT solve
|
||||
|
||||
Stated flatly, because a design document that only lists strengths is a brochure.
|
||||
|
||||
1. It does not create compute supply. Real GPU and accelerator capacity, the off-chain provers, and
|
||||
real SP1 proving are EXTERNAL to this contract [MEASURE]. V3 is a settlement and verification rail.
|
||||
A rail with no providers is not a market, and this contract cannot make providers appear.
|
||||
2. It does not guarantee a watcher exists. Both optimistic modes are only as safe as the most attentive
|
||||
honest party. See the failure mode above.
|
||||
3. It does not solve data availability for large outputs. `submitResultRef` commits to a hash and a
|
||||
retrieval hint, nothing more.
|
||||
4. It does not make ZK proofs quantum-safe. On-chain verification is classical BN254 and Shor-breakable.
|
||||
5. It does not make Aere consensus post-quantum. Consensus is classical secp256k1 ECDSA QBFT.
|
||||
6. It does not remove the arbiter as a trust assumption. It bounds the damage an absent arbiter can do
|
||||
(14 days, then a neutral unwind), but a present and dishonest arbiter can still rule wrongly on any
|
||||
dispute it resolves in time. There is no appeal, no arbiter bond, and no arbiter slashing.
|
||||
7. It does not price compute, match buyers to sellers, or rank providers. There is no reputation, no
|
||||
discovery, and no order book. A requester must already know which provider it wants, or accept
|
||||
whoever claims first.
|
||||
8. It does not prevent claim-squatting, as described above.
|
||||
9. It does not verify that a job spec is meaningful, or that `specHash` corresponds to anything a
|
||||
provider can actually run. The commitment is opaque to the contract by design.
|
||||
10. It is not audited and not deployed.
|
||||
|
||||
## Honest status
|
||||
|
||||
- Contract: built and tested. `AereComputeMarketV3.sol` compiles under solc 0.8.23 (the repo standard)
|
||||
and the 13-case Hardhat suite passes, covering all three modes, the Falcon settlement gate, the ERC-20
|
||||
reward path, the solvency invariant, and no-double-pay.
|
||||
- Contract: built, compiles, tested. `AereComputeMarketV3.sol` compiles under solc 0.8.23 (repo
|
||||
standard). MEASURED 2026-07-20: `npx hardhat compile` printed `Compiled 1 Solidity file successfully
|
||||
(evm target: paris)`; `npx hardhat test aere-contracts/test/AereComputeMarketV3.test.js
|
||||
test/AereComputeMarketV3.liveness.test.js` printed `28 passing (7s)`, 0 failing.
|
||||
- Formal: `aere-research/formal-consensus/computemarket_smt.py` proves the escrow-solvency invariant
|
||||
inductively over the modelled transitions, including the two new exit paths, with 4 negative controls
|
||||
that fire as expected. BOUNDARY: this models the DESIGN accounting, not the compiled EVM bytecode.
|
||||
- ZK verification path [VERIFY]: exercised against `MockSp1Verifier`, which mirrors the deployed gateway
|
||||
semantics (reverts on an invalid proof). The reference verifier is the deployed `SP1VerifierGateway`
|
||||
at `0x9ca479C8c52C0EbB4599319a36a5a017BCC70628`; wiring V3 to it on mainnet is a deploy-time
|
||||
constructor argument.
|
||||
at `0x9ca479C8c52C0EbB4599319a36a5a017BCC70628`; wiring V3 to it is a deploy-time constructor
|
||||
argument. Real SP1 proving has NOT been run against V3 [MEASURE].
|
||||
- Falcon settlement path [VERIFY]: exercised against `MockPQCPrecompile` at `0x0AE1`, which parses the
|
||||
Falcon-512 spec offsets. The real wire encoding is separately KAT-proven in `AerePQCMessageVerifier`
|
||||
and against the live mainnet precompile. On mainnet 2800 the precompile at `0x0AE1` is live.
|
||||
- Real compute supply [MEASURE]: real GPU / accelerator supply, the off-chain provers, and the real SP1
|
||||
proving are EXTERNAL to this contract. They require actual hardware providers running the reference
|
||||
provider daemon. This is adoption, not code, exactly like validator decentralization. V3 is the trust
|
||||
and settlement rail; it does not by itself constitute a live compute market with real providers.
|
||||
- No new token. Rewards, escrow, bonds, and payment are native AERE or an allowlisted existing ERC-20.
|
||||
- Not deployed. This contract is built for publication and review. Deployment is founder-gated.
|
||||
Falcon-512 spec offsets. Real Falcon signing has NOT been run against V3. The wire encoding is
|
||||
separately KAT-proven in `AerePQCMessageVerifier` and against the live mainnet precompile. On mainnet
|
||||
2800 the precompile at `0x0AE1` is live.
|
||||
- DEPLOYMENT DEPENDENCY: a `pqcSettlement` job is unsettleable on any chain where `0x0AE1` is not a live
|
||||
Falcon-512 precompile, because `_falconVerify` fails closed. On such a chain the escrow would only
|
||||
exit via `reclaimUnsettled`. V3 must therefore be deployed on Aere mainnet 2800 (or a testnet
|
||||
carrying the precompiles), not on a generic EVM chain.
|
||||
- Real compute supply [MEASURE]: adoption, not code, exactly like validator decentralization.
|
||||
- No new token. Rewards, escrow, bonds and payment are native AERE or an allowlisted existing ERC-20.
|
||||
- NOT DEPLOYED, NOT AUDITED. Built for publication and review. Deployment is FOUNDER-GATED.
|
||||
|
||||
## Relationship to V1 and V2 (deployed, untouched)
|
||||
|
||||
| | V1 `AereComputeMarket` | V2 `AereComputeMarketV2` | V3 (this) |
|
||||
|---|---|---|---|
|
||||
| Address (chain 2800) | `0xf0c8178a5d9feb0f70C5f184e79edeEDaddcF350` | `0x33E3B06A7344f0B201fdD11B18bC244c84dbca32` | not deployed |
|
||||
| Deployed | 2026-07-07 | 2026-07-09 | founder-gated |
|
||||
| Verification | optimistic + Foundation arbitration | same, plus on-chain spec/result bytes | per-job REPLAY / ZK_VERIFIED / OPTIMISTIC |
|
||||
| Provider bond | stake floor | configurable stake floor | per-job bond, slashable to challenger |
|
||||
| Reward asset | native AERE | native AERE | native AERE or allowlisted ERC-20 |
|
||||
| Arbiter absent | escrow locked | escrow locked | neutral unwind after 14 days |
|
||||
| Large outputs | inline only | inline only | inline or (hash, URI) commitment |
|
||||
| PQ payout gate | none | none | optional Falcon-512 via `0x0AE1` |
|
||||
| Admin sweep | `sweepSlashPool` (Foundation) | `sweepSlashPool` (Foundation) | none |
|
||||
|
||||
V1 and V2 remain live and untouched. V2's real shortcoming was not that it was broken: three genuine
|
||||
end-to-end settlements ran against it on mainnet on 2026-07-09 (see
|
||||
`deployments/compute-market-e2e.json`, jobs 0, 1 and 2, all reaching status 5 = Paid). The shortcoming
|
||||
was that verification was a single fixed optimistic path with the Foundation as arbiter, so the
|
||||
guarantee was identical whether the work was cheaply replayable or needed a real proof, and an
|
||||
unresponsive arbiter had no timeout. V3 makes the guarantee a per-job choice and gives every path a
|
||||
bounded exit.
|
||||
|
||||
@ -2,12 +2,29 @@
|
||||
|
||||
**Chain:** Aere Network mainnet, chain ID 2800 (`0xaf0`). Execution client: Hyperledger Besu 26.4.0 with QBFT consensus (classical secp256k1 ECDSA, N=7 validators, f=2), approximately 0.5 second blocks. This document is a developer reference: it states, EIP by EIP, where Aere's EVM matches Ethereum mainnet and where it deliberately differs.
|
||||
|
||||
Aere tracks Ethereum's hard forks so that its EVM surface matches mainnet at the same addresses and opcodes: London and Shanghai apply from genesis, Cancun and Prague (Pectra) activated together at block 2,075,363, and Osaka (Fusaka) at block 2,106,606. A small set of deviations is intentional and disclosed here, because Aere is a QBFT chain with no separate beacon (consensus) layer and no blob data availability market. Anything not matching Ethereum is a design decision, not an oversight, and each is called out in the matrix and again in the deviations recap at the end.
|
||||
Aere tracks Ethereum's hard forks so that its EVM surface matches mainnet at the same addresses and opcodes: London and Shanghai apply from genesis, Cancun and Prague (Pectra) activated together at block 2,075,341, and Osaka (Fusaka) at block 2,106,597. A small set of deviations is intentional and disclosed here, because Aere is a QBFT chain with no separate beacon (consensus) layer and no blob data availability market. Anything not matching Ethereum is a design decision, not an oversight, and each is called out in the matrix and again in the deviations recap at the end.
|
||||
|
||||
## How to read this
|
||||
|
||||
- **Status** is one of: **Supported** (matches Ethereum), **Partial** (present but materially limited on Aere), **Not implemented** (absent), **No-op** (present in the ruleset but neutralized, returns a defined zero/empty value under QBFT).
|
||||
- Every row is intended to be literally true. Cells that could not be verified against the repository's genesis or fork configuration carry an explicit **[VERIFY: ...]** note for a human to confirm before publication.
|
||||
- Every row is intended to be literally true. Cells that could not be verified against the repository's genesis or fork configuration carry an explicit **[VERIFY: ...]** note. A `[VERIFY]` note is a permanent, deliberate disclosure that the named fact is **NOT MEASURED**. It is published as it stands, it does not block publication, and it is closed only by a measurement, never by deletion. The full rule is `VERIFY-POLICY.md` at the root of this repository.
|
||||
- A figure taken from a spec or a config file is a **price**. A figure produced by querying the running chain is a **measurement**. Rows marked *(measured 2026-07-19)* were produced by read-only JSON-RPC against `https://rpc.aere.network`, and the method is stated in "How the measured gas figures were produced" at the end of this document. Nothing in this file was written by sending a transaction.
|
||||
|
||||
### Second validation pass, 2026-07-19 (independent re-measurement)
|
||||
|
||||
This document was re-validated end to end against the running chain by an independent pass whose brief was to assume nothing in it was true. Every activation height was re-derived by binary search rather than read from this file; every price claim was re-measured with a freshly built and freshly calibrated probe; behavioural claims were driven with real `eth_call`s and compared byte for byte.
|
||||
|
||||
**Result: the matrix held up.** No gas figure, activation height, status, or economic claim in it was found to be wrong. Three open flags were closed, one was narrowed, and three points of imprecision were corrected:
|
||||
|
||||
- **`blobSchedule` attribution (corrected).** The EIP-7691 row said the raised schedule was set "in config". The *values* are right (live `eth_config`: target 6, max 9), but `blobSchedule` is absent from all four genesis files -- the schedule comes from Besu's built-in default for the active fork, not from Aere's genesis.
|
||||
- **Blob base-fee update fraction (corrected).** The EIP-7516 row cited `fake_exponential(1, 0, 3338477)`. 3,338,477 is the *Cancun* constant; the live chain reports 5,007,716, the *Prague* (EIP-7691) value. The 1 wei conclusion is unaffected.
|
||||
- **SHAKE256 figure (disambiguated).** "A 160-byte input" was ambiguous between total input and `data` length; the row now states the fitted gas model and the packed encoding instead of a single point.
|
||||
|
||||
**It also propagated a correction outward.** `AERE-PROTOCOL-SPECIFICATION.md` was still carrying the superseded Pectra and Osaka heights (2,075,363 and 2,106,606) in nine places, including its normative activation predicates and its Appendix A fork table. Those were wrong by 22 and 9 blocks and have been corrected to the measured 2,075,341 and 2,106,597. The two documents now agree.
|
||||
|
||||
### Measurement provenance for the 2026-07-19 pass
|
||||
|
||||
The gas figures, the two fork-boundary heights, and the blob base fee in this document were re-derived from the live chain on 2026-07-19 while diagnosing the Nethermind second client (see `aerenew/cross-client-determinism/`). That pass corrected four values that had been carried from specs rather than measured: the Pectra and Osaka activation heights, the P-256 precompile gas, and the blob base fee. Each correction is called out inline.
|
||||
- "The fork" or "the AerePQC hard fork" refers to Aere's client-only Besu `futureEips` milestone (`futureEipsTime = 1783820272`), which activated at block 9,189,161 (2026-07-12) and bundled the native post-quantum precompiles, the EIP-2935 write path, and EIP-7939. No re-genesis was involved.
|
||||
|
||||
### Fork timeline on chain 2800
|
||||
@ -15,11 +32,22 @@ Aere tracks Ethereum's hard forks so that its EVM surface matches mainnet at the
|
||||
| Ethereum fork | Aere activation | Notes |
|
||||
|---|---|---|
|
||||
| London, Shanghai | Genesis (block 0) | `londonBlock: 0`, `shanghaiTime: 0` in genesis config |
|
||||
| Cancun + Prague (Pectra) | Block 2,075,363 | `cancunTime == pragueTime == 1780189051`; Cancun and Prague share one activation instant on Aere |
|
||||
| Osaka (Fusaka) | Block 2,106,606 | `osakaTime == 1780220351` |
|
||||
| Cancun + Prague (Pectra) | **Block 2,075,341** *(measured 2026-07-19)* | `cancunTime == pragueTime == 1780189051`; Cancun and Prague share one activation instant on Aere |
|
||||
| Osaka (Fusaka) | **Block 2,106,597** *(measured 2026-07-19)* | `osakaTime == 1780220351` |
|
||||
| AerePQC milestone (post-Osaka) | Block 9,189,161 | Besu `futureEipsTime == 1783820272`; PQC precompiles + EIP-2935 write path + EIP-7939 |
|
||||
|
||||
[VERIFY: block heights 2,075,363 and 2,106,606. The genesis config gates Cancun/Prague/Osaka by timestamp (1780189051 / 1780189051 / 1780220351), not by block number, so these heights are the observed first-block-past-timestamp and should be confirmed against the live chain's head history.]
|
||||
**Correction (2026-07-19).** This table previously read 2,075,363 and 2,106,606. Both were wrong. The heights are gated by timestamp, not by block number, so they have to be read off the chain, and when they were, two independent signals agreed:
|
||||
|
||||
| Block | Timestamp | `requestsHash` present |
|
||||
|---|---|---|
|
||||
| 2,075,340 | 1780189050 | no |
|
||||
| **2,075,341** | **1780189051** (`pragueTime`) | **yes** (`sha256("")`) |
|
||||
| 2,106,596 | 1780220350 | yes |
|
||||
| **2,106,597** | **1780220351** (`osakaTime`) | yes |
|
||||
|
||||
Block 2,075,341 is the first block whose timestamp reaches `pragueTime`, and it is also the first block to carry a `requestsHash` at all, which is an independent confirmation of the Pectra boundary. Block 2,106,597 is the first block whose timestamp reaches `osakaTime`. Both agree with the checkpoints the cross-client harness derived by binary search (`aerenew/cross-client-determinism/`). Block heights on this chain are not a stable API: they are an observation about when a timestamp was crossed, and they are recorded here only because they are useful for locating the boundary in an explorer.
|
||||
|
||||
**AerePQC height 9,189,161: now re-derived (2026-07-19, second pass).** This was previously flagged as carried from configuration rather than measured. It has since been confirmed by the same timestamp binary search used for the other two boundaries: block 9,189,160 has timestamp 1783820271 and block 9,189,161 has timestamp **1783820272**, exactly `futureEipsTime`, making it the first block at or past the activation instant. Note the scope of that confirmation: it establishes the *height at which the configured timestamp is first crossed*, which is the same standard applied to Pectra and Osaka. It is not a behavioural probe of the precompiles at that height -- the public RPC prunes historical state, so `eth_call` at 9,189,161 still cannot be used to watch the band switch on. The precompiles are separately confirmed live *at head* by direct measurement (see the Aere additions table).
|
||||
|
||||
---
|
||||
|
||||
@ -29,7 +57,7 @@ Aere tracks Ethereum's hard forks so that its EVM surface matches mainnet at the
|
||||
|
||||
| EIP | Name | Status | Difference from Ethereum |
|
||||
|---|---|---|---|
|
||||
| 1559 | Fee market (base fee, type-2 txs) | Partial | Fee-market mechanics present, plus a 1 Gwei base-fee floor live since block 10,141,734 (raised the real minimum from 7 wei). Aere adds no consensus base-fee burn narrative: its "burn" is a separate validator-reward cut (see deviations). [VERIFY: base-fee disposal on chain 2800, whether the 1559 base fee is protocol-burned as on Ethereum or credited.] |
|
||||
| 1559 | Fee market (base fee, type-2 txs) | Partial | Fee-market mechanics present, plus a 1 Gwei base-fee floor live since block 10,141,734 (raised the real minimum from 7 wei). **Floor boundary re-confirmed by direct measurement 2026-07-19**: block 10,141,733 has `baseFeePerGas = 7` wei and block 10,141,734 has `baseFeePerGas = 0x3b9aca00 = 1,000,000,000` wei, and it holds at 1 Gwei at every later block sampled through head. `eth_feeHistory` at head likewise reports `baseFeePerGas` of `0x3b9aca00`. Aere adds no consensus base-fee burn narrative: its "burn" is a separate validator-reward cut (see deviations). [VERIFY (narrowed 2026-07-19): base-fee *disposal*. Measurement rules out crediting to the coinbase (zero coinbase delta across a fee-paying block); burned-versus-routed-elsewhere is still open, see open flag 2.] |
|
||||
| 3198 | BASEFEE opcode | Supported | Returns the current base fee, which is floored at 1 Gwei (see EIP-1559). |
|
||||
| 3529 | Reduction in refunds | Supported | Matches Ethereum. |
|
||||
| 3541 | Reject contract code starting with 0xEF | Supported | Matches Ethereum. Reserves the 0xEF lead byte (the EOF prefix). |
|
||||
@ -38,37 +66,50 @@ Aere tracks Ethereum's hard forks so that its EVM surface matches mainnet at the
|
||||
| 3860 | Limit and meter initcode | Supported | Matches Ethereum. |
|
||||
| 4895 | Beacon chain push withdrawals as operations | No-op | Withdrawal-operation ruleset present, but Aere has no beacon layer to originate withdrawals, so none are produced. |
|
||||
|
||||
### Cancun (block 2,075,363)
|
||||
### Istanbul-era precompiles and pricing (active from genesis)
|
||||
|
||||
Aere starts at London, so every earlier fork is folded into genesis and these are all live. They are listed explicitly because they are **priced** rules, not feature flags: a client that carries the opcode but the wrong price produces a different `gasUsed` and forks. That is not hypothetical. Both EIP-1108 and EIP-152 were missing from the Nethermind second client's chainspec on 2026-07-19, which made it charge pre-Istanbul alt_bn128 prices and halt (see `aerenew/cross-client-determinism/LIVE-BESU-VS-NETHERMIND-2026-07-19.md`).
|
||||
|
||||
| EIP | Name | Status | Difference from Ethereum |
|
||||
|---|---|---|---|
|
||||
| 1153 | Transient storage (TLOAD / TSTORE) | Supported | Matches Ethereum. |
|
||||
| 4844 | Shard blob transactions | Partial | Type-3 blob transactions are present in the EVM, but Aere runs no blob data-availability market, so blobs carry no fee and are not served/persisted as on Ethereum. See EIP-7516. |
|
||||
| 4788 | Beacon block root in the EVM | No-op | The beacon-root ring buffer returns 0x0: a QBFT chain has no separate beacon/consensus layer to expose a root from. |
|
||||
| 5656 | MCOPY instruction | Supported | Matches Ethereum. |
|
||||
| 196 | alt_bn128 add and mul (`0x06`, `0x07`) | Supported | Matches Ethereum. Verified live: `ecAdd` and `ecMul` both return 64 bytes for the standard generator inputs. |
|
||||
| 197 | alt_bn128 pairing check (`0x08`) | Supported | Matches Ethereum. Verified live for k = 0, 1, 2 and 4 pairs. |
|
||||
| 1108 | Reduce alt_bn128 precompile gas costs | Supported | Matches Ethereum. **Post-1108 prices confirmed by measurement, not by config.** Measured 2026-07-19 against the live chain: `ecAdd` **150**, `ecMul` **6,000**, `ecPairing` **45,000 + 34,000 per pair**. The pre-1108 schedule (500 / 40,000 / 100,000 + 80,000 per pair) is ruled out by a margin of 34,000 gas on `ecMul` alone and 239,000 gas on a 4-pair `ecPairing`, far outside any measurement noise. This is the pricing an on-chain BN254 Groth16 verifier depends on; a client on the pre-1108 schedule starves such a verification of gas. |
|
||||
| 152 | Blake2b `F` compression function (`0x09`) | Supported | Matches Ethereum. Present and fail-closed: probed with a malformed (zero-length) input, it consumes all forwarded gas and reports failure, which is the behavior EIP-152 specifies for an input that is not exactly 213 bytes. **Per-round price now measured on a well-formed 213-byte input** *(measured 2026-07-19)*: `rounds = 12` costs exactly **12** gas and `rounds = 100` costs exactly **100** gas, that is, cost == rounds, the EIP-152 schedule. |
|
||||
| 198 | Big integer modular exponentiation (`0x05`) | Supported | Matches Ethereum at **Osaka** pricing. **Closed by measurement 2026-07-19, and the answer distinguishes the repricing generation.** A minimal 1-byte base/exponent/modulus call (`b=8, e=9, m=10`) costs **500** gas. EIP-2565's floor is 200 and EIP-7883's is 500, so the measurement rules out EIP-2565-only pricing and confirms **EIP-7883 (Osaka) modexp repricing is live** on chain 2800. This was open flag 5; a client still on the EIP-2565 schedule would undercharge modexp by 300 gas at the floor and diverge. |
|
||||
|
||||
### Cancun (block 2,075,341)
|
||||
|
||||
| EIP | Name | Status | Difference from Ethereum |
|
||||
|---|---|---|---|
|
||||
| 1153 | Transient storage (TLOAD / TSTORE) | Supported | Matches Ethereum. Confirmed live by execution *(measured 2026-07-19)*: a state-override `eth_call` running `TSTORE(0, 0x42); TLOAD(0)` returns `0x..42`. |
|
||||
| 4844 | Shard blob transactions | Partial | Type-3 blob transactions are present in the EVM and the Cancun blob header fields are carried (`blobGasUsed` and `excessBlobGas` are present and both read `0x0` on live blocks), but Aere runs no blob data-availability market, so no blob is ever included and the blob fee never leaves its floor. See EIP-7516. |
|
||||
| 4788 | Beacon block root in the EVM | No-op | The beacon-root ring buffer returns 0x0: a QBFT chain has no separate beacon/consensus layer to expose a root from. Live blocks carry `parentBeaconBlockRoot = 0x00..00`. |
|
||||
| 5656 | MCOPY instruction | Supported | Matches Ethereum. Confirmed live by execution *(measured 2026-07-19)*: a state-override `eth_call` using `MCOPY` to copy a word from offset 0 to offset 32 returns the copied value. |
|
||||
| 6780 | SELFDESTRUCT only in same transaction | Supported | Matches Ethereum. |
|
||||
| 7516 | BLOBBASEFEE opcode | No-op | Returns 0: there is no blob market, so there is no blob base fee. |
|
||||
| 7516 | BLOBBASEFEE opcode | Supported (pinned at the floor) | **Corrected 2026-07-19: this previously read "No-op, returns 0". That was wrong.** The opcode is live and returns **1 wei**, the EIP-4844 `MIN_BASE_FEE_PER_BLOB_GAS`, not 0. Live blocks carry `excessBlobGas = 0x0`, and `blob_base_fee = fake_exponential(1, 0, 5007716) = 1`. **Correction (2026-07-19): this previously cited an update fraction of 3,338,477.** That is the *Cancun* `BLOB_BASE_FEE_UPDATE_FRACTION`; the live chain's `eth_config` reports `baseFeeUpdateFraction = 5007716`, the *Prague* (EIP-7691) value. The result is 1 wei either way because `excessBlobGas` is 0 and `fake_exponential(1, 0, k) = 1` for every `k`, so the conclusion was right, but the constant quoted for the active fork was wrong. Confirmed by `eth_feeHistory` on chain 2800, which reports `baseFeePerBlobGas: ["0x1", "0x1"]`. Because Aere runs no blob market, `excessBlobGas` never rises, so the value is permanently pinned at the floor of 1 rather than being absent or zero. See the caveat on probing this opcode in "How the measured gas figures were produced". |
|
||||
|
||||
### Prague / Pectra (block 2,075,363)
|
||||
### Prague / Pectra (block 2,075,341)
|
||||
|
||||
| EIP | Name | Status | Difference from Ethereum |
|
||||
|---|---|---|---|
|
||||
| 2537 | BLS12-381 curve precompiles | Supported | Matches Ethereum. |
|
||||
| 2537 | BLS12-381 curve precompiles | Supported | Matches Ethereum. **Prices confirmed by measurement, not by config** *(measured 2026-07-19)*: `BLS12_G1ADD` (`0x0b`) **375**, `BLS12_G2ADD` (`0x0d`) **600**, `BLS12_MAP_FP_TO_G1` (`0x10`) **5,500**, `BLS12_MAP_FP2_TO_G2` (`0x11`) **23,800** -- each exactly the EIP-2537 schedule. All seven BLS addresses `0x0b`..`0x11` are listed in the live `eth_config` precompile set. |
|
||||
| 2935 | Save historical block hashes in state | Supported | Standard 8191-block history-storage ring buffer at `0x0000F90827F1C53a10cb7A02335B175320002935`, written by consensus. Nominally listed at Pectra but the system contract was not populated on mainnet until the AerePQC fork (block 9,189,161) added the write path; from that block `eth_getCode` returns the canonical runtime and the 8191-block window is live. |
|
||||
| 6110 | Supply validator deposits on chain | Partial | The deposit-request ruleset is part of the Pectra parity Aere tracks, but Aere has no beacon layer to consume deposits, so a deposit does not create or fund a QBFT validator (the validator set is QBFT-managed). [VERIFY: whether the deposit system contract is actually populated on mainnet 2800; EIP-2935's contract was not populated until block 9,189,161, so this must be checked directly.] |
|
||||
| 7002 | Execution-layer triggerable withdrawals/exits | Partial | Withdrawal-request ruleset present, but no beacon layer consumes exits, so it does not affect the QBFT validator set. [VERIFY: system contract populated on mainnet; header requests handling.] |
|
||||
| 7251 | Increase MAX_EFFECTIVE_BALANCE (consolidations) | Partial | Consolidation-request ruleset present, but no beacon layer to act on it under QBFT. [VERIFY: system contract populated on mainnet.] |
|
||||
| 6110 | Supply validator deposits on chain | Partial | The deposit-request ruleset is part of the Pectra parity Aere tracks, but Aere has no beacon layer to consume deposits, so a deposit does not create or fund a QBFT validator (the validator set is QBFT-managed). **CLOSED by measurement 2026-08-01** (head block 11,810,041, `https://rpc.aere.network`): `eth_getCode` returns **0 bytes** at the EIP-6110 deposit contract `0x00000961Ef480Eb55e80D19ad83579A64c007002`, at the EIP-7251 consolidation contract `0x0000BBdDc7CE488642fb579F8B00f3a590007251`, and at `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`. The live header carries `requestsHash` = `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`, which is the SHA-256 of the empty string, and `parentBeaconBlockRoot` = all zeros. So: none of the request system contracts is populated, and the header requests list is empty. That is exactly what "ruleset present, no beacon layer" predicts, and it is now measured rather than flagged. (Contrast EIP-2935 in the row above, which **is** populated, at 83 bytes.) |
|
||||
| 7002 | Execution-layer triggerable withdrawals/exits | Partial | Withdrawal-request ruleset present, but no beacon layer consumes exits, so it does not affect the QBFT validator set. **CLOSED by measurement 2026-08-01** (head block 11,810,041, `https://rpc.aere.network`): `eth_getCode` returns **0 bytes** at the EIP-6110 deposit contract `0x00000961Ef480Eb55e80D19ad83579A64c007002`, at the EIP-7251 consolidation contract `0x0000BBdDc7CE488642fb579F8B00f3a590007251`, and at `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`. The live header carries `requestsHash` = `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`, which is the SHA-256 of the empty string, and `parentBeaconBlockRoot` = all zeros. So: none of the request system contracts is populated, and the header requests list is empty. That is exactly what "ruleset present, no beacon layer" predicts, and it is now measured rather than flagged. (Contrast EIP-2935 in the row above, which **is** populated, at 83 bytes.) |
|
||||
| 7251 | Increase MAX_EFFECTIVE_BALANCE (consolidations) | Partial | Consolidation-request ruleset present, but no beacon layer to act on it under QBFT. **CLOSED by measurement 2026-08-01** (head block 11,810,041, `https://rpc.aere.network`): `eth_getCode` returns **0 bytes** at the EIP-6110 deposit contract `0x00000961Ef480Eb55e80D19ad83579A64c007002`, at the EIP-7251 consolidation contract `0x0000BBdDc7CE488642fb579F8B00f3a590007251`, and at `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`. The live header carries `requestsHash` = `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`, which is the SHA-256 of the empty string, and `parentBeaconBlockRoot` = all zeros. So: none of the request system contracts is populated, and the header requests list is empty. That is exactly what "ruleset present, no beacon layer" predicts, and it is now measured rather than flagged. (Contrast EIP-2935 in the row above, which **is** populated, at 83 bytes.) |
|
||||
| 7549 | Move committee index outside signature | Not implemented | Beacon consensus-layer change only, with no execution-layer/EVM surface. It has no applicability under QBFT. |
|
||||
| 7623 | Increase calldata cost | Supported | Matches Ethereum (calldata floor-cost accounting). |
|
||||
| 7685 | General purpose execution layer requests | Partial | The requests framework (the umbrella for 6110/7002/7251) exists in the ruleset, but Aere has no beacon layer to consume the requests. [VERIFY: whether mainnet block headers carry a non-empty requests hash and the request system contracts are populated.] |
|
||||
| 7702 | Set EOA account code (delegation) | Supported | Matches Ethereum. This is the EOA-delegation primitive Aere carries (and the reason EIP-3074 is not needed). |
|
||||
| 7691 | Blob throughput increase | Partial | The blob schedule is raised at Prague (target 6, max 9) in config, but with no blob data-availability market the increase has no practical effect. |
|
||||
| 7685 | General purpose execution layer requests | Partial | The requests framework (the umbrella for 6110/7002/7251) exists in the ruleset, but Aere has no beacon layer to consume the requests. **CLOSED by measurement 2026-08-01** (head block 11,810,041, `https://rpc.aere.network`): `eth_getCode` returns **0 bytes** at the EIP-6110 deposit contract `0x00000961Ef480Eb55e80D19ad83579A64c007002`, at the EIP-7251 consolidation contract `0x0000BBdDc7CE488642fb579F8B00f3a590007251`, and at `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`. The live header carries `requestsHash` = `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`, which is the SHA-256 of the empty string, and `parentBeaconBlockRoot` = all zeros. So: none of the request system contracts is populated, and the header requests list is empty. That is exactly what "ruleset present, no beacon layer" predicts, and it is now measured rather than flagged. (Contrast EIP-2935 in the row above, which **is** populated, at 83 bytes.) |
|
||||
| 7702 | Set EOA account code (delegation) | Supported | Matches Ethereum. This is the EOA-delegation primitive Aere carries (and the reason EIP-3074 is not needed). **Delegation resolution confirmed live** *(measured 2026-07-19)*: an account whose code is set to the designator (`0xef0100` followed by a 20-byte target address) executes the target's code when called, while the same account given a non-designator `0xEF`-prefixed blob (`0xef9900` followed by the same address) is rejected with `Invalid opcode: 0xef`. So the `0xef0100` prefix is honored as a delegation indicator and no other `0xEF` form is executable, which is exactly the EIP-7702 plus EIP-3541 combination. |
|
||||
| 7691 | Blob throughput increase | Partial | The active blob schedule is **target 6, max 9, `baseFeeUpdateFraction` 5,007,716** -- the EIP-7691 raised schedule -- confirmed by reading `eth_config` on the live chain *(measured 2026-07-19)*. With no blob data-availability market the increase has no practical effect. **Correction (2026-07-19): this row previously said the schedule was set "in config". That was wrong as to source.** `blobSchedule` is **absent from all four genesis files** (`aere-genesis-current.json`, `aere-genesis-pectra.json`, `aere-genesis-fusaka.json`, `aerenew/genesis.json`); none of them declares one. The schedule the chain actually runs comes from **Besu's built-in default for the active fork**, not from Aere's genesis. The values are correct; the attribution was not. A reimplementer must therefore hardcode the EIP-7691 schedule rather than expect to read it out of Aere's genesis, and a client that defaults to the Cancun schedule (target 3, max 6, fraction 3,338,477) would carry a different blob-fee curve. |
|
||||
|
||||
### Fusaka / Osaka (block 2,106,606) and the post-Osaka milestone
|
||||
### Fusaka / Osaka (block 2,106,597) and the post-Osaka milestone
|
||||
|
||||
| EIP | Name | Status | Difference from Ethereum |
|
||||
|---|---|---|---|
|
||||
| 7825 | Transaction gas limit cap (2^24 = 16,777,216) | Supported | Matches Ethereum; the per-transaction gas cap is enforced on chain 2800 (real transactions have executed under it). |
|
||||
| 7951 | secp256r1 (P-256) signature verification at `0x100` | Supported | Matches Ethereum's Osaka. Live and verified on chain 2800 *(measured 2026-07-19)*. See the `0x100` row under "Aere additions" for the measured gas and semantics. Activated with the Osaka ruleset at `osakaTime = 1780220351`, block 2,106,597. This is the precompile Aere's passkey/WebAuthn accounts sit on, so it is load-bearing rather than decorative. |
|
||||
| 7825 | Transaction gas limit cap (2^24 = 16,777,216) | Supported | Matches Ethereum; the per-transaction gas cap is enforced on chain 2800 (real transactions have executed under it). Note this is a per-transaction cap; the live **block** gas limit reads `0x1fffffffffffff` (2^53 - 1). |
|
||||
| 7939 | Count leading zeros (CLZ) opcode | Supported | Present. On Aere it activated at the post-Osaka AerePQC milestone (block 9,189,161), which the live EIP-2124 fork-id folds in. [VERIFY: activation height for 7939 specifically, confirmed against the live fork schedule.] |
|
||||
| 7594 | PeerDAS (peer data availability sampling) | Not implemented | No active role under QBFT: Aere runs no blob data-availability market, so there is no data-availability sampling role to perform. |
|
||||
| 7805 | FOCIL (fork-choice enforced inclusion lists) | Not implemented | No-op under QBFT: there is no fork-choice or proposer-inclusion layer to enforce inclusion lists against. |
|
||||
@ -88,18 +129,20 @@ These are callable addresses that are not part of the base Ethereum mainnet prec
|
||||
|
||||
| Address | Name | Status | Notes |
|
||||
|---|---|---|---|
|
||||
| `0x0AE1` | Falcon-512 signature verify | Live on mainnet | Activated at block 9,189,161 (AerePQC fork). Thin wrapper over Bouncy Castle 1.83; NIST KAT verified. |
|
||||
| `0x0AE2` | Falcon-1024 signature verify | Live on mainnet | Activated at block 9,189,161. NIST KAT verified. |
|
||||
| `0x0AE3` | ML-DSA-44 signature verify (FIPS 204) | Live on mainnet | Activated at block 9,189,161. ACVP verified. |
|
||||
| `0x0AE4` | SLH-DSA-SHA2-128s signature verify (FIPS 205) | Live on mainnet | Activated at block 9,189,161. ACVP verified. |
|
||||
| `0x0AE5` | SHAKE256 (FIPS 202) | Live on mainnet | Activated at block 9,189,161. |
|
||||
| `0x0AE6` | ML-KEM-768 encapsulation (FIPS 203) | Testnet only | Built and ACVP-verified (25/25) on an isolated QBFT testnet. NOT on mainnet 2800; a mainnet staticcall hits an empty account and returns empty. Founder- and audit-gated. |
|
||||
| `0x0AE7` | Falcon HashToPoint (SHAKE256 sampler) | Testnet only | Built and KAT-verified (12/12) on isolated testnet. NOT on mainnet 2800. Founder- and audit-gated. |
|
||||
| `0x0AE1` | Falcon-512 signature verify | Live on mainnet | Activated at block 9,189,161 (AerePQC fork). Thin wrapper over Bouncy Castle 1.83; NIST KAT verified. Gas **40,000**, measured on the live chain 2026-07-19 and matching the committed schedule `Falcon512VerifyGas = 40_000`. |
|
||||
| `0x0AE2` | Falcon-1024 signature verify | Live on mainnet | Activated at block 9,189,161. NIST KAT verified. Gas **75,000** (measured), matching the committed `FALCON1024_VERIFY_GAS = 75000`. |
|
||||
| `0x0AE3` | ML-DSA-44 signature verify (FIPS 204) | Live on mainnet | Activated at block 9,189,161. ACVP verified. Gas **55,000** (measured). |
|
||||
| `0x0AE4` | SLH-DSA-SHA2-128s signature verify (FIPS 205) | Live on mainnet | Activated at block 9,189,161. ACVP verified. Gas **350,000** (measured). |
|
||||
| `0x0AE5` | SHAKE256 (FIPS 202) | Live on mainnet | Activated at block 9,189,161. Variable cost by input and output length. **Full gas model re-derived on the live chain across 10 input shapes** *(measured 2026-07-19)*, fitting with zero residual: `gas = 60 + 12 * ( ceil(len(data)/32) + ceil(min(outLen, 65536)/32) )`, where the packed input is `outLen` (32-byte big-endian word) followed by `data`. Three properties are load-bearing and all three are measured, not assumed: (1) the two word counts are **rounded up separately, not combined** -- `outLen=33, data=33` costs 108 gas (4 words), where a combined `ceil((33+33)/32)` model predicts 3 words and 96 gas; (2) `outLen` **saturates** at `MAX_OUTLEN = 65536` -- `outLen=100000, data=32` costs 24,648, identical to what 65,536 would cost; (3) the `outLen` framing word is **not** itself charged as data. **Clarification (2026-07-19): this row previously read "a 160-byte input returning 65,536 bytes measured 24,684 gas", which was ambiguous.** 24,684 gas corresponds to **128 bytes of `data`** (a 160-byte *total* input, of which the first 32 bytes are the `outLen` framing word). A call with 160 bytes of actual `data` costs **24,696**. The figure was right under one reading of "input" and wrong under the other, so it is now stated as the model plus the encoding. This independently reconfirms the separate-rounding correction made to `aerenew/eips/eip-draft-shake256-precompile.md`. |
|
||||
| `0x0AE6` | ML-KEM-768 encapsulation (FIPS 203) | Testnet only | Built and ACVP-verified (25/25) on an isolated QBFT testnet. NOT on mainnet 2800: re-confirmed 2026-07-20 by gas differential, a mainnet `STATICCALL` to `0x0AE6` charges **0 gas** against a codeless control, versus 40,000/75,000/55,000/350,000/24,648 for the live `0x0AE1`..`0x0AE5`. Decisive because `gasRequirement` is a flat 60,000 for every input, so an active `0x0AE6` would bill it even while returning empty. Note the empty return by itself proves nothing: `0x0AE5` is live and also returns empty for a short input. Founder- and audit-gated. |
|
||||
| `0x0AE7` | Falcon HashToPoint (SHAKE256 sampler) | Testnet only | Built and KAT-verified (12/12) on isolated testnet. NOT on mainnet 2800, re-confirmed by the same measurement. Founder- and audit-gated. |
|
||||
| `0x0AE8` | BabyBear/FRI STARK verify (skeleton) | Reference skeleton only | Non-working, fail-closed by construction (returns empty for every input). Not deployed on mainnet and explicitly must not be activated until the crypto core is ported. Scope caveat (2026-07-19 finding): the generic components confirmed so far verify BabyBear + FRI STARKs (Aere's OWN Plonky3 circuits), NOT SP1 6.1.0, which is Hypercube (KoalaBear multilinear); retargeting to SP1 6.1.0 is a separate ~22 to 32 person-week effort. See `AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md`. |
|
||||
| `0x100` | P256Verify / secp256r1 (RIP-7212 / RIP-7951) | Live on mainnet | Native P-256 signature verification for passkeys/WebAuthn at a fixed cost of about 3,450 gas. Active from the Osaka/Fusaka ruleset. Note: this is a shared Rollup Improvement Proposal being standardized into Ethereum's Osaka, so it is standards-aligned rather than Aere-proprietary. |
|
||||
| `0x100` | P256Verify / secp256r1 (EIP-7951, formerly RIP-7212) | Live on mainnet | Native P-256 signature verification for passkeys/WebAuthn. Gas **6,900**, measured on the live chain 2026-07-19. **Corrected: this row previously read "about 3,450 gas". That was the original RIP-7212 price, which was doubled to 6,900 when the proposal was standardized into Ethereum's Osaka as EIP-7951.** Active from the Osaka/Fusaka ruleset (`osakaTime = 1780220351`, block 2,106,597). Standards-aligned, not Aere-proprietary. Verified semantics: a valid signature returns a 32-byte `0x..01`; an invalid one returns **empty** (not a zero word, which is how the `0x0AE1`..`0x0AE4` band fails), and the full 6,900 gas is charged either way. Signature malleability is **not** restricted: both the low-s and high-s forms of the same signature verify, matching the spec. Cross-client confirmed: the Nethermind second client returns byte-identical results and charges identical gas. |
|
||||
|
||||
All post-quantum precompiles are signature/hash/KEM verifiers on the EVM path. None of them make Aere's consensus post-quantum: mainnet 2800 still seals blocks with classical secp256k1 QBFT.
|
||||
|
||||
**Warm/cold note.** The inherited Ethereum precompiles (`0x01`..`0x0A`) and the EIP-7951 verifier at `0x100` are pre-warmed under EIP-2929, so a call to them pays the 100 gas warm-access charge. The Aere-specific band at `0x0AE1`..`0x0AE5` is **not** in the pre-warmed set: a first call in a transaction pays the 2,600 gas cold-account charge on top of the verify price. Measured 2026-07-19. Budget for it when sizing a PQC-verifying transaction.
|
||||
|
||||
---
|
||||
|
||||
## Deliberate deviations recap
|
||||
@ -107,7 +150,11 @@ All post-quantum precompiles are signature/hash/KEM verifiers on the EVM path. N
|
||||
The intentional differences from Ethereum, all a consequence of Aere being a QBFT chain with no beacon layer and no blob market:
|
||||
|
||||
1. **Base fee floor plus a validator-reward burn, not a consensus base-fee burn.** Aere applies a 1 Gwei EIP-1559 base-fee floor (live since block 10,141,734). Separately, Aere's "burn" is a cut of the validator coinbase block reward (37.5% under the current configuration, hard-capped at 50%), routed through the `AereCoinbaseSplitterV2` splitter into immutable destinations. This must not be described as a base-fee burn.
|
||||
2. **EIP-4844 blobs present, EIP-7516 BLOBBASEFEE returns 0.** Blob transactions exist in the EVM, but there is no blob data-availability market, so the blob base fee is 0.
|
||||
|
||||
**Burn parameters confirmed on chain 2026-07-19** by reading the deployed `AereCoinbaseSplitterV2` at `0x8C1A48eFA57b66fEE743A00E3899c29ad3Fd27b4`: `burnBps() = 3750` (37.5%), `MAX_BURN_BPS() = 5000` (the 50% ceiling), `sinkBps() = 1500`, `MAX_SINK_BPS() = 3000`, `rebateBps() = 4750`. Every figure matches the documented configuration exactly, and `3750 + 1500 + 4750 = 10000` closes.
|
||||
|
||||
Two structural facts confirm the separation is real rather than editorial. First, the live block **coinbase is a plain EOA with no code** (`eth_getCode` on the block `miner` returns `0x`), so nothing is deducted from the reward by consensus -- the split happens only when a forwarder sends the reward on to the splitter, which is application-layer wiring above consensus, exactly as described. Second, the base fee is separately confirmed **not credited to that coinbase** (open flag 2), so the two mechanisms do not touch. [MEASURE: `AereCoinbaseSplitterV2.totalBurned()` currently reads **0**, while the older V1 splitter at `0xb4b0eCe9011613A5b84248a9B42a0f309E6F01Ec` reads 137,352,594,046,167,719 wei burned. So V2 is deployed and correctly configured but has not yet received flow; the burn described here is live as a configuration and as a V1 flow, and the V2 path is not yet carrying volume. Confirm the forwarder's current target before describing V2 as the operative path.]
|
||||
2. **EIP-4844 blobs present, EIP-7516 BLOBBASEFEE pinned at 1 wei.** Blob transactions exist in the EVM, but there is no blob data-availability market, so no blob is ever included, `excessBlobGas` never rises above 0, and the blob base fee sits permanently at the EIP-4844 floor of 1 wei. It is not 0 and the opcode is not neutralized. *(Corrected 2026-07-19; this recap previously said 0.)*
|
||||
3. **EIP-4788 parent beacon block root returns 0x0.** A QBFT chain has no separate beacon/consensus layer to source a root from.
|
||||
4. **EIP-3074 not implemented, superseded by EIP-7702.** EIP-7702 is the EOA-delegation primitive Aere carries.
|
||||
5. **PeerDAS (EIP-7594), FOCIL (EIP-7805), and EOF (EIP-7692) have no active role under QBFT.** PeerDAS has no data-availability role (no blob market), FOCIL has no fork-choice/proposer-inclusion layer to enforce, and EOF is not activated under the current ruleset (0xEF stays reserved by EIP-3541).
|
||||
@ -116,11 +163,53 @@ The intentional differences from Ethereum, all a consequence of Aere being a QBF
|
||||
|
||||
---
|
||||
|
||||
## Open [VERIFY] flags for the human before external publication
|
||||
## Closed by measurement on 2026-07-19
|
||||
|
||||
1. **Pectra/Fusaka block heights (2,075,363 / 2,106,606).** Genesis gates these by timestamp, not block number. Confirm the heights against the live chain's head history.
|
||||
2. **EOF off under `futureEips`.** Confirm the AerePQC `futureEips` protocol spec (futureEipsTime = 1783820272, block 9,189,161) does not enable the EOF opcode set / EIP-3540/3670 container validation. Served genesis, the Nethermind fork-id mirror, and the engineering spec all indicate EOF is off; inspect the fork build's spec definition to close the loop, since the milestone rides Besu's `futureEips` key (EOF's usual staging ground in stock Besu).
|
||||
3. **EIP-1559 base-fee disposal.** Confirm whether the 1559 base fee is protocol-burned (as on Ethereum) or credited on chain 2800. The documented Aere "burn" is a separate validator-reward cut, so the base-fee disposal itself should be stated precisely.
|
||||
4. **Validator-lifecycle request contracts (6110/7002/7251/7685).** Verify whether the deposit/withdrawal/consolidation system contracts are actually populated on mainnet (EIP-2935's contract was not populated until block 9,189,161) and whether mainnet block headers carry a requests hash. Regardless of the outcome, no beacon layer consumes these requests, so the "Partial" status and the no-effect-on-validator-set caveat hold.
|
||||
5. **EIP-7939 activation height.** Confirm CLZ activated at the post-Osaka AerePQC milestone (block 9,189,161) rather than at Osaka (block 2,106,606); the Nethermind live-sync mirror maps it to the post-Osaka boundary.
|
||||
6. **P256Verify framing.** Confirmed at `0x100`, about 3,450 gas, from the Osaka/Fusaka ruleset (RIP-7212 / RIP-7951). Noted as standards-aligned rather than Aere-proprietary; keep that framing if publishing under an "additions" heading.
|
||||
These were open [VERIFY] flags. They are now measurements, not prices.
|
||||
|
||||
1. **Pectra/Fusaka block heights.** Closed. Measured **2,075,341** and **2,106,597**, by reading block timestamps either side of each activation instant and cross-checking against the first appearance of `requestsHash`. The previously published 2,075,363 and 2,106,606 were wrong and have been corrected throughout this document.
|
||||
2. **P256Verify gas.** Closed, and the previous figure was wrong. Measured **6,900**, not 3,450. The precompile is live, verifies correctly, fails closed with an empty return, and does not restrict signature malleability.
|
||||
3. **EIP-1108 alt_bn128 pricing.** Closed. Measured `ecAdd` 150, `ecMul` 6,000, `ecPairing` 45,000 + 34,000 per pair, that is, the post-1108 schedule.
|
||||
4. **EIP-7516 blob base fee.** Closed, and the previous claim was wrong. It is 1 wei (the EIP-4844 floor), not 0.
|
||||
|
||||
## System contract population on mainnet (measured 2026-07-19)
|
||||
|
||||
`eth_getCode` at `latest` on chain 2800. This closes most of what was open flag 4.
|
||||
|
||||
| Contract | Address | Code on mainnet |
|
||||
|---|---|---|
|
||||
| EIP-2935 history storage | `0x0000F90827F1C53a10cb7A02335B175320002935` | **83 bytes** (populated) |
|
||||
| EIP-7002 withdrawal requests | `0x00000961Ef480Eb55e80D19ad83579A64c007002` | **none** |
|
||||
| EIP-7251 consolidation requests | `0x0000BBdDc7CE488642fb579F8B00f3a590007251` | **none** |
|
||||
| EIP-6110 deposit contract | `0x00000000219ab540356cBB839Cbe05303d7705Fa` | **none** |
|
||||
| EIP-4788 beacon roots ring buffer | `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02` | **none** |
|
||||
|
||||
Live mainnet block headers **do** carry `requestsHash`, and it is always `sha256("") = 0xe3b0c442...b7852b855`, the empty-requests hash. Besu computes that hash without executing the absent predeploys. This exact combination (a `requestsHash` in the header, but no code at the request predeploys) is what halted the Nethermind second client on 2026-07-19; see the cross-client write-up.
|
||||
|
||||
Because the EIP-4788 ring buffer has no code, a call to it succeeds with **empty** returndata rather than returning a zero word. Consumers that decode the result as a `bytes32` will see `0x00..00`, which is why the EIP-4788 row above is described as returning `0x0`, but the distinction matters to a contract that checks `returndatasize`.
|
||||
|
||||
## Open [VERIFY] flags: facts published as NOT MEASURED
|
||||
|
||||
**Second validation pass, 2026-07-19 (independent re-measurement).** All five flags below were re-attacked directly against the live chain. **Three are now closed by measurement, one is narrowed, and one remains genuinely open.** The instrument was re-calibrated from scratch before any of it was trusted (see the method appendix).
|
||||
|
||||
1. ~~**EOF off under `futureEips`.**~~ **CLOSED by measurement.** This no longer rests on indirect corroboration. Executing candidate code at head through `eth_call` with a state override: the EOF v1 container magic `0xef0001...` is rejected with `Invalid opcode: 0xef` (so EIP-3540 container validation is not parsing it), and the EOF-only opcodes `RJUMP` (`0xe0`), `CALLF` (`0xe3`) and `EXTCALL` (`0xf8`) are each rejected as `Invalid opcode` (so the EOF opcode set is not enabled). Five independent probes, all fail-closed. **EOF is not activated**, and `0xEF` stays reserved by EIP-3541 legacy behavior. This was the highest-risk open item because the milestone rides Besu's `futureEips` key; it is settled.
|
||||
2. **EIP-1559 base-fee disposal.** **Narrowed, still open.** Ruled out: the base fee is **not credited to the coinbase**. Measured on block 10,487,561 (1 transaction, `gasUsed` 22,474, `effectiveGasPrice` 1 Gwei, i.e. equal to `baseFeePerGas`, so the priority tip was zero): the coinbase balance delta across that block was **exactly 0 wei**, where crediting the base fee would have moved 22,474,000,000,000 wei. Because the tip was zero, this cannot by itself separate "protocol-burned" from "routed elsewhere" -- both models predict a zero delta. Closing it needs a block with a **nonzero** priority tip and unpruned state. The chain is currently quiet (no logs in the last 5,000 blocks), and the one tipped transaction located, `0xb659...9ec1` at block 9,200,542 (tip 0.1 Gwei), sits below the public RPC's pruning horizon so its balances cannot be read. Either run the check on the archive node or read the client source.
|
||||
3. ~~**EIP-2935 contract bytes.**~~ **CLOSED by measurement, two ways.** (a) *Byte level*: the 83 bytes at `0x0000F90827F1C53a10cb7A02335B175320002935` are byte-for-byte the canonical EIP-2935 runtime `0x3373...fffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500`. Disassembly confirms the two jump targets are the `JUMPDEST` at `0x42` (revert path) and the `JUMPDEST` at `0x46` (the `SSTORE` path taken when `caller == SYSTEM_ADDRESS`), and the length is exactly 83 bytes. (b) *Functional level, which is stronger*: calling the contract with the block number of `head - 100` returns that block's hash, byte-identical to `eth_getBlockByNumber`. The ring buffer is not merely populated, it is serving correct history.
|
||||
4. **EIP-7939 activation height.** **Partially closed.** The opcode itself is confirmed **live and correct at head** *(measured)*: `PUSH1 0x01; CLZ` returns 255 and `PUSH0; CLZ` returns 256. Only the *boundary* remains unverified -- whether CLZ turned on at the AerePQC milestone (block 9,189,161) or at Osaka (block 2,106,597) -- and that is still not probeable by `eth_call` because the public RPC has pruned state at both heights. Needs the archive node or a source read.
|
||||
5. ~~**EIP-198 / EIP-2565 / EIP-7883 modexp pricing.**~~ **CLOSED by measurement, and the answer is specific.** A minimal `b=8, e=9, m=10` modexp call costs **500** gas. EIP-2565's floor is 200 and EIP-7883's is 500, so **EIP-7883 (Osaka) modexp repricing is live** and EIP-2565-only pricing is ruled out. The concern that motivated this flag was well founded in kind: a client left on the EIP-2565 schedule undercharges modexp by 300 gas at the floor and would diverge on any modexp-using transaction.
|
||||
|
||||
**Newly measured in this pass and previously unstated:** EIP-2537 BLS12-381 prices (`G1ADD` 375, `G2ADD` 600, `MAP_FP_TO_G1` 5,500, `MAP_FP2_TO_G2` 23,800, all exactly the spec schedule); EIP-152 blake2f per-round price (cost == rounds, verified at 12 and 100 rounds); EIP-7702 delegation resolution (the `0xef0100` designator executes the target, non-designator `0xEF` forms are rejected); EIP-1153 and EIP-5656 confirmed by execution rather than by ruleset membership; and the complete `0x0AE5` SHAKE256 gas model fitted across 10 shapes with zero residual.
|
||||
|
||||
## How the measured gas figures were produced
|
||||
|
||||
Every gas figure marked *(measured)* came from the same read-only technique, and it is worth stating because the obvious techniques do not work here.
|
||||
|
||||
**What does not work.** `eth_estimateGas` returns a binary-search result with a small buffer (it reported 66,845 where the true cost is 66,000), and EIP-7623's calldata floor can mask a precompile's price entirely: a 160-byte call to `0x100` costs the same whether or not the precompile exists, because the floor dominates. Neither is precise enough to distinguish a 3,450 gas price from a 6,900 gas one.
|
||||
|
||||
**What works.** An `eth_call` with a **state override** that installs a small bytecode probe at a scratch address. The probe reads `GAS`, performs a `STATICCALL` to the target, reads `GAS` again, and returns the difference along with the call's success flag and `RETURNDATASIZE`. Inside the EVM there is no calldata floor, so the difference is the true charged cost plus a fixed harness overhead. That overhead is then calibrated away using two precompiles whose prices are fixed by spec and cannot drift: `ecRecover` at a flat 3,000 and the identity precompile at 15 + 3 per word. Both calibrations agreed on an overhead of 127 gas (100 warm-access plus 27 of probe opcodes), and the identity precompile then read back its spec price of 30 exactly. Residual noise is under 15 gas, from memory expansion inside the measured window, which is far below the margins being distinguished.
|
||||
|
||||
**A trap worth recording.** The `BASEFEE` opcode returns **0** inside `eth_call` on this chain, even though the block header and `eth_feeHistory` both report 1 Gwei. Besu simulates calls against a zero base fee. So `eth_call` is not admissible evidence about `BASEFEE` or `BLOBBASEFEE`, and the blob base fee in this document was established from `eth_feeHistory` and the header's `excessBlobGas` instead, not from the opcode. Any future probe of a fee-context opcode needs the same caution.
|
||||
|
||||
**Recalibration note (2026-07-19, second pass).** The method reproduces, but the *overhead constant is a property of the probe, not of the chain*, and should not be treated as a checkable figure. The second pass rebuilt the probe independently -- `CALLDATACOPY`, a pre-warming `STATICCALL`, `GAS`, `STATICCALL`, `GAS`, `SWAP1`, `SUB`, `MSTORE`, `RETURN` -- and calibrated to a fixed overhead of **117** gas (100 warm-access plus 17 gas of probe opcodes), not the 127 recorded above, because it uses a slightly shorter opcode sequence between the two `GAS` reads. The calibration itself was exact in a way worth stating as the acceptance bar: against the identity precompile at `15 + 3 * ceil(len/32)` the implied overhead was **117 at every input length tested** (0, 32, 64, 96, 128 and 160 bytes) with no drift, an empty-address control read **exactly 117**, and `ecRecover` read back its flat spec price of **3,000** exactly. Residual noise was zero, not merely small. Anyone rebuilding the probe should calibrate their own constant the same way and only trust the instrument once the control and a spec-fixed price both come back exact -- the number to reproduce is the *measured price* after subtraction, not the overhead.
|
||||
|
||||
The probe scripts are throwaway and were not committed. What is reproducible is the method plus the calibration constants above; anyone can rebuild the probe and should get the same numbers against `https://rpc.aere.network`.
|
||||
|
||||
@ -41,7 +41,7 @@ Attacker goals and defenses:
|
||||
- **Forge a block or seal without a validator key.** Defended by ECDSA seal recovery plus the requirement that every recovered committer be a member of the stored validator set, with a per-block quorum of 5 distinct committers. Forgery reduces to forging secp256k1 ECDSA, which is classically hard. It is not quantum-hard: a cryptographically-relevant quantum computer running Shor breaks the seal signature, which is the central reason consensus is described honestly as classical, not post-quantum.
|
||||
- **Equivocate or split the chain (safety attack).** QBFT tolerates up to `f = 2` Byzantine validators at N = 7 with safety unconditional (no fork) under the standard BFT bound. Beyond 2 Byzantine validators (more than one third), safety is lost: a 3-of-7 collusion can violate agreement. This is a hard bound, not a soft target.
|
||||
- **Stall the chain (liveness attack) at the fault boundary.** With exactly 2 validators down, all 5 survivors must prepare and commit with zero slack. QBFT round-robin proposer selection plus a doubling round-change timeout means an unlucky proposer sequence can exceed a fixed measurement window before an alive proposer's round succeeds. Adversarial soak testing on an isolated testnet (100 kill-2-of-7 cycles: 40 mixed-client RT=4, 40 mixed-client RT=1, 20 pure-Besu) recorded 0 forks and 100/100 self-resync, with a rare (about 5 percent), temporary, self-healing zero-progress window at the exact f = 2 boundary. That tail is inherent to partially-synchronous BFT (FLP: liveness is eventual, not bounded-time, at the boundary) and was not removable by timeout tuning. It is not a fork and not a permanent halt.
|
||||
- **Grind proposer selection or exploit locking.** IBFT 2.0 locking (retain the prepared block and prepare-certificate, carry it in round-change, re-propose the justified block) is the property that prevents a stale or conflicting proposal from being committed across a round change. It is formally modeled (`formal-consensus/qbft_locking_smt.py`) and enforced by the live Besu producer.
|
||||
- **Grind proposer selection or exploit locking.** IBFT 2.0 locking (retain the prepared block and prepare-certificate, carry it in round-change, re-propose the justified block) is the property that prevents a stale or conflicting proposal from being committed across a round change. It is formally modeled (`aere-research/formal-consensus/qbft_locking_smt.py`) and enforced by the live Besu producer.
|
||||
- **The centralization threat itself.** All 7 validators are Foundation-operated. The Nakamoto coefficient is therefore approximately 1: a single operator (the Foundation) can in principle halt or, if it chose to run more than 2 equivocating nodes, break safety. This is the single most important limitation in this document. It is disclosed, not hidden, and is not mitigated by cryptography; the only present mitigation is operator honesty plus a public decentralization roadmap. See Assumption A-3.
|
||||
- **Second-client cross-check.** A patched Nethermind validates live chain 2800, runs the PQC precompiles, and produces byte-identical QBFT blocks that stock Besu accepts (demonstrated offline via block import, not yet as a live devp2p producer). It currently acts as a client-diversity fail-safe cross-check. It is not a live producing validator, and until the IBFT locking findings are implemented in its engine and soak-verified against an active-Byzantine scenario, it is safe only as an observing or voting participant below the `q - f` threshold, not as a producer.
|
||||
|
||||
@ -70,18 +70,18 @@ Attacker goals and defenses:
|
||||
|
||||
### 1.4 Bridge and Cross-Chain
|
||||
|
||||
The cross-chain surface is optimistic intent settlement (AereSpokePool, ERC-7683 / Across-V3 style), an institutional settlement hub (AereSettlementHubV2), Hyperlane-style warp routes, and zk light clients (QBFT and Ethereum). The escrow accounting of the two core contracts is machine-checked: the SpokePool `balance >= totalLocked + totalBond` invariant and the SettlementHub `balance >= committedLiabilities` invariant are each proved inductive in z3 (`formal-consensus/spokepool_smt.py`, `settlementhub_smt.py`), with negative controls that reproduce a real under-backing counterexample when a guard is removed.
|
||||
The cross-chain surface is optimistic intent settlement (AereSpokePool, ERC-7683 / Across-V3 style), an institutional settlement hub (AereSettlementHubV2), Hyperlane-style warp routes, and zk light clients (QBFT and Ethereum). The escrow accounting of the two core contracts is machine-checked: the SpokePool `balance >= totalLocked + totalBond` invariant and the SettlementHub `balance >= committedLiabilities` invariant are each proved inductive in z3 (`aere-research/formal-consensus/spokepool_smt.py`, `settlementhub_smt.py`), with negative controls that reproduce a real under-backing counterexample when a guard is removed.
|
||||
|
||||
Attacker goals and defenses:
|
||||
|
||||
- **Drain escrowed principal.** Defended by the proven solvency invariants above: every settle path pays only an allowlisted solver, cancel refunds only the depositor, withdraw returns only the caller's own free bond, and any sweep of residual is strictly bounded to `balance - committed` so it can never touch a parked intent or a posted bond. No path sends funds to an arbitrary caller address.
|
||||
- **Claim without filling (optimistic-bond attack).** This is the disclosed weak point. A claim does not prove the destination fill; settle releases the user's locked input to the solver after a challenge window unless challenged, and Phase-1 challenge only emits an event (the Foundation arbitrates and slashes off-chain). A rogue or key-compromised allowlisted solver could claim across many orders in one window and lose only the fixed bond, which does not scale with the value at risk. In Phase 1 this is bounded by a permissioned, Foundation-vetted solver allowlist and is documented in the contract NatSpec. It is a trust assumption, not a hidden bug. Before any permissionless phase, the bond must exceed the maximum stealable value per window.
|
||||
- **Claim without filling (optimistic-bond attack).** This is the disclosed weak point. A claim does not prove the destination fill; settle releases the user's locked input to the solver after a challenge window unless challenged, and Phase-1 challenge only emits an event (the Foundation arbitrates and slashes off-chain). An allowlisted solver acting dishonestly, whether deliberately or because its signing authority has stopped being under its own control, could claim across many orders in one window and lose only the fixed bond, which does not scale with the value at risk. In Phase 1 this is bounded by a permissioned, Foundation-vetted solver allowlist and is documented in the contract NatSpec. It is a trust assumption, not a hidden bug. Before any permissionless phase, the bond must exceed the maximum stealable value per window.
|
||||
- **Break accounting with a hostile token.** The SpokePool credits nominal input amounts, so a fee-on-transfer or rebasing input token can break its per-token backing invariant (a disclosed low-to-medium finding); the SettlementHubV2 closes this with an explicit asset allowlist that can exclude such tokens. Exposure is nil while inputs are restricted to vetted standard ERC-20s.
|
||||
- **Forge a cross-chain message or light-client header.** The zk light clients verify proofs of the source chain's consensus rather than trusting a relayer. Their soundness inherits the ZK-layer assumption (Assumption A-5) and, for the QBFT light client, the same classical-BN254 caveat as Section 1.3.
|
||||
|
||||
### 1.5 Accounts and Account Abstraction
|
||||
|
||||
Aere supports ERC-4337 v0.7 (AereEntryPointV2), EIP-7702 upgrade-in-place, WebAuthn / P-256 passkey smart accounts, a Falcon-512-owned post-quantum smart account (AerePQCAccount), a hybrid ECDSA-plus-Falcon authorizer (AereHybridAuth), and a t-of-n post-quantum threshold account. The chain exposes the standard `ecrecover` (3,000 gas) and a P-256 verification precompile (RIP-7212 / RIP-7951 at `0x100`, 3,450 gas), both at their standard protocol gas costs.
|
||||
Aere supports ERC-4337 v0.7 (AereEntryPointV2), EIP-7702 upgrade-in-place, WebAuthn / P-256 passkey smart accounts, a Falcon-512-owned post-quantum smart account (AerePQCAccount), a hybrid ECDSA-plus-Falcon authorizer (AereHybridAuth), and a t-of-n post-quantum threshold account. The chain exposes the standard `ecrecover` (3,000 gas) and a P-256 verification precompile (EIP-7951 / RIP-7951 at `0x100`, **6,900 gas**), both at their standard protocol gas costs and both re-measured on live chain 2800 on 2026-07-19. (Corrected from a previous "3,450 gas": that is the superseded RIP-7212 Layer-2 price, which RIP-7951 doubled when it was standardized for mainnet.)
|
||||
|
||||
Attacker goals and defenses:
|
||||
|
||||
@ -140,7 +140,7 @@ The guarantees in Section 2 hold only under the following assumptions. If an ass
|
||||
- **A-4 Keccak collision resistance.** Block hashing, Merkle-Patricia state proofs, and commit-seal pre-images assume keccak-256 is collision-resistant.
|
||||
- **A-5 Proof-system soundness.** The SP1 / Plonky3, RISC Zero, and Halo2 proof systems are sound: a verifying proof implies the asserted statement, except with negligible probability. The on-chain verifiers are assumed to correctly implement these systems (backed by KAT / fixture tests, not by a from-scratch soundness proof).
|
||||
- **A-6 NIST PQC hardness.** The hardness assumptions behind Falcon (NTRU lattice), ML-DSA / ML-KEM (module lattice), and SLH-DSA (hash-based) are unbroken. Signature-layer post-quantum guarantees are void if these are broken.
|
||||
- **A-7 Audited primitive library.** The precompiles rely on the correctness of Bouncy Castle (`bcprov-jdk18on-1.83.jar`) for Falcon / ML-DSA / SLH-DSA / SHAKE. A bug in that library is a bug in the precompiles.
|
||||
- **A-7 Third-party primitive library, unaudited.** The precompiles rely on the correctness of Bouncy Castle (`bcprov-jdk18on-1.83.jar`) for Falcon / ML-DSA / SLH-DSA / SHAKE. A bug in that library is a bug in the precompiles. This assumption is load-bearing and it is not discharged by anyone else: `bcprov-jdk18on` is the general-purpose provider, not a FIPS validated module, and we know of no published third-party audit of it. The Bouncy Castle FIPS module (BC-FJA, CMVP #4743 and #4943) is a different artifact that Aere does not ship, and neither of its certificates lists any post-quantum algorithm in any case. See `AERE-NIST-VALIDATION-STATUS.md` section 3.4 for the full citation trail.
|
||||
- **A-8 Device and WebAuthn security.** Passkey / P-256 account security assumes the device secure element protects the private key and that the WebAuthn ceremony is not subverted on the client. This is outside the chain's control.
|
||||
- **A-9 BN254 is honest until replaced.** The on-chain ZK verifiers use BN254 pairings, which are Shor-breakable. They are assumed secure against classical adversaries only, and this assumption is explicitly temporary: it stands until the planned direct hash-based STARK verifier (Section 1.3) is made real, audited, and activated. Under a cryptographically-relevant quantum adversary, the ZK verification layer and the QBFT light client offer no guarantee.
|
||||
- **A-10 Precompile determinism.** Every precompile is a pure function of its input bytes, reads no chain state or nondeterministic source, and every node runs an identical client build, so all nodes compute the identical result and gas charge. A divergence here would be a consensus fault.
|
||||
@ -212,7 +212,7 @@ This section records, for each load-bearing architecture decision, what was chos
|
||||
|
||||
### 4.8 Deliberate compatibility deviations from the Ethereum roadmap
|
||||
|
||||
Aere tracks Ethereum's hard forks (Pectra activated at block 2,075,363; Fusaka / Osaka at block 2,106,606) so that its EVM surface matches mainnet at the same addresses. Several roadmap features are, however, deliberately neutralized or absent because Aere is a QBFT chain with no separate consensus (beacon) layer and no blob data-availability market. These are design decisions, disclosed here so an integrator is not surprised:
|
||||
Aere tracks Ethereum's hard forks (Pectra activated at block 2,075,341; Fusaka / Osaka at block 2,106,597, both re-measured 2026-08-02) so that its EVM surface matches mainnet at the same addresses. Several roadmap features are, however, deliberately neutralized or absent because Aere is a QBFT chain with no separate consensus (beacon) layer and no blob data-availability market. These are design decisions, disclosed here so an integrator is not surprised:
|
||||
|
||||
- **Base fee has a floor plus a validator-reward burn**, not a consensus base-fee burn (see 4.7). The floor is 1 Gwei, live from block 10,141,734.
|
||||
- **EIP-4844 blob transactions are present in the EVM, but `BLOBBASEFEE` (EIP-7516) returns 0** because there are no blobs: Aere runs no blob data-availability market.
|
||||
@ -285,7 +285,7 @@ A safety-first summary that holds across every mode tested: **in all adversarial
|
||||
|
||||
**Halt / fork / continue.** The chain is unaffected. No revert of consensus, no halt, no fork. The calling contract simply sees a not-verified result.
|
||||
|
||||
**Status.** PROVEN. This as-shipped behavior was verified against the live chain and reconciled into the precompile documentation (the earlier draft's "MUST revert" framing was corrected to the actual fail-closed zero-word / empty-output behavior). Evidence: the AIP reconcile in `aerenew/research/aip-draft-pqc-precompiles.md` "As shipped" corrections.
|
||||
**Status.** PROVEN. This as-shipped behavior was verified against the live chain and reconciled into the precompile documentation (the earlier draft's "MUST revert" framing was corrected to the actual fail-closed zero-word / empty-output behavior). Evidence: the AIP reconcile in `aere-research/research/aip-draft-pqc-precompiles.md` "As shipped" corrections.
|
||||
|
||||
### 5.7 The bridge goes down
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
# Spec 9: Aere entropy honesty fix — real drand BLS verification
|
||||
# Spec 9: Aere entropy honesty fix, real drand BLS verification
|
||||
|
||||
## The gap (what was dishonest)
|
||||
|
||||
`aerenew/contracts/contracts/oracle/AereRandomnessBeacon.sol` (live-deployed at
|
||||
`aere-contracts/contracts/oracle/AereRandomnessBeacon.sol` (live-deployed at
|
||||
`0x25b6317efD8C7d425210F56Ee1E204852CD8213C`) shipped with a placeholder
|
||||
verifier:
|
||||
|
||||
@ -22,8 +22,8 @@ canonical randomness (`SHA-256(signature)`).
|
||||
|
||||
New files (the live beacon was NOT modified):
|
||||
|
||||
- `aerenew/contracts/contracts/oracle/AereRandomnessBeaconV2.sol`
|
||||
- `library AereDrandQuicknetBLS` — real BLS12-381 verification on EIP-2537:
|
||||
- `aere-contracts/contracts/oracle/AereRandomnessBeaconV2.sol`
|
||||
- `library AereDrandQuicknetBLS`, real BLS12-381 verification on EIP-2537:
|
||||
- `messageForRound` = `SHA-256(round as 8-byte big-endian)` (quicknet is UNCHAINED)
|
||||
- `hashToField` = RFC 9380 `expand_message_xmd` (SHA-256, len 128) + reduce
|
||||
mod p via MODEXP. Uses only SHA-256 (0x02) + MODEXP (0x05), so it runs on
|
||||
@ -35,10 +35,10 @@ New files (the live beacon was NOT modified):
|
||||
(p ≡ 3 mod 4, sqrt = a^((p+1)/4)); consumes drand's exact 48-byte sig.
|
||||
- `verifyRoundCompressed` = pairing check `e(H(m),pk) * e(sig,-G2) == 1` via
|
||||
`BLS12_PAIRING_CHECK` (0x0f).
|
||||
- `contract AereRandomnessBeaconV2` — `submitRound` ALWAYS verifies (no phase
|
||||
- `contract AereRandomnessBeaconV2`, `submitRound` ALWAYS verifies (no phase
|
||||
flag, no admin off-switch); stores canonical `SHA-256(signature)` randomness.
|
||||
- `aerenew/contracts/test/AereRandomnessBeaconV2.test.js` — real drand vectors.
|
||||
- `aerenew/contracts/hardhat.config.prague.js` — pins the local `hardhat`
|
||||
- `aere-contracts/test/AereRandomnessBeaconV2.test.js`, real drand vectors.
|
||||
- `aerenew/contracts/hardhat.config.prague.js`, pins the local `hardhat`
|
||||
network to the `prague` hardfork so EIP-2537 is available for the full test.
|
||||
|
||||
**Fail-closed everywhere:** any wrong-length input, absent precompile (empty
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
## What was built (all new files, deployed origin contracts untouched)
|
||||
|
||||
1. `aerenew/contracts/contracts/intents/AereDestinationSettler.sol`
|
||||
1. `aere-contracts/contracts/intents/AereDestinationSettler.sol`
|
||||
- Implements ERC-7683 `IDestinationSettler.fill(bytes32 orderId, bytes originData, bytes fillerData)`
|
||||
from the existing `contracts/intents/IERC7683.sol` (reused, not redefined).
|
||||
from the existing `aere-contracts/contracts/intents/IERC7683.sol` (reused, not redefined).
|
||||
- A solver (msg.sender = filler) delivers the promised output straight to the recipient
|
||||
on Aere via OpenZeppelin SafeERC20 (no custody), records the fill, emits `Filled`.
|
||||
- `originData` = the origin's declared output leg, matching AereSpokePool `_buildResolved`:
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
2. Finality / repayment wiring (real reference, not a live cross-chain claim):
|
||||
- Declares `IAereQbftFinalityLightClient` matching the deployed
|
||||
`contracts/interop/AereZkQbftLightClient.sol` (0xCaDA54FA...6488): the SP1 Groth16
|
||||
`aere-contracts/contracts/interop/AereZkQbftLightClient.sol` (0xCaDA54FA...6488): the SP1 Groth16
|
||||
QBFT-finality prover (guest `qbft-lightclient-guest`, quorum ceil(2N/3) = 5-of-7).
|
||||
- `FILLED_EVENT_SIG` + `Filled` log + `fillCommitment` are the on-chain surface an
|
||||
origin-side `AereOutboundVerifierV2`-style verifier consumes: it proves the `Filled`
|
||||
@ -29,7 +29,7 @@
|
||||
- The light client is deployed on the consuming/origin chain (Aere is native on Aere),
|
||||
so the settler does NOT call it on-chain; documented, not faked.
|
||||
|
||||
3. `aerenew/contracts/test/destination-settler.test.js` - RAN, 4 passing:
|
||||
3. `aere-contracts/test/destination-settler.test.js` - RAN, 4 passing:
|
||||
- valid fill: delivers output, records fill, emits Filled, fillCommitment matches
|
||||
- duplicate fill reverts (AlreadyFilled)
|
||||
- mismatched-output reverts (OutputMismatch) - tested short amount, wrong recipient, wrong token
|
||||
|
||||
@ -5,14 +5,14 @@ the origin and destination halves compose, the solver flow, the repayment proof
|
||||
and the honest status of what is on-chain today versus what needs the off-chain solver
|
||||
and finality prover.
|
||||
|
||||
Contract: `aerenew/contracts/contracts/intents/AereDestinationSettler.sol`
|
||||
Interface: ERC-7683 `IDestinationSettler` (`contracts/intents/IERC7683.sol`)
|
||||
Test: `aerenew/contracts/test/destination-settler.test.js` (4 passing)
|
||||
Contract: `aere-contracts/contracts/intents/AereDestinationSettler.sol`
|
||||
Interface: ERC-7683 `IDestinationSettler` (`aere-contracts/contracts/intents/IERC7683.sol`)
|
||||
Test: `aere-contracts/test/destination-settler.test.js` (4 passing)
|
||||
|
||||
## Why a destination settler at all
|
||||
|
||||
Aere Network already ships the ORIGIN side of ERC-7683: `AereSpokePool`
|
||||
(`contracts/intents/AereSpokePool.sol`) is an `IOriginSettler`. A user locks input
|
||||
(`aere-contracts/contracts/intents/AereSpokePool.sol`) is an `IOriginSettler`. A user locks input
|
||||
tokens on the origin chain and emits an `Open` event that declares the OUTPUT leg they
|
||||
want on the destination chain (token, amount, recipient). What was missing is the
|
||||
DESTINATION half: the contract a solver calls to actually deliver that output and to
|
||||
@ -106,7 +106,7 @@ The origin chain must learn "this exact fill was included in a block that is FIN
|
||||
Aere Network" without trusting a relayer. Aere Network already has the machinery, and
|
||||
the settler is built to plug into it.
|
||||
|
||||
1. FINALITY prover. `contracts/interop/AereZkQbftLightClient.sol` (live on consuming
|
||||
1. FINALITY prover. `aere-contracts/contracts/interop/AereZkQbftLightClient.sol` (live on consuming
|
||||
chains at `0xCaDA54FA...6488`) proves, in the SP1 zkVM (guest
|
||||
`qbft-lightclient-guest`), that one Aere header is QBFT-final: it decodes the Besu
|
||||
QBFT `extraData`, recomputes both Besu hash pre-images, ecrecovers each committed
|
||||
@ -115,7 +115,7 @@ the settler is built to plug into it.
|
||||
settler declares this interface as `IAereQbftFinalityLightClient` for reference. This
|
||||
prover runs on the consuming/origin chain, not on Aere Network (Aere is native there),
|
||||
so the settler does not call it on-chain.
|
||||
2. INCLUSION plus delivery. `contracts/interop/AereOutboundVerifierV2.sol` is the
|
||||
2. INCLUSION plus delivery. `aere-contracts/contracts/interop/AereOutboundVerifierV2.sol` is the
|
||||
origin-side pattern that CONSUMES such a proof. It accepts an SP1 proof that a
|
||||
specific Aere log was included in a QBFT-final Aere block (finality plus receipt
|
||||
inclusion, one guest), binds the proof's committed `validatorSetRoot` to its own
|
||||
@ -156,7 +156,7 @@ form. The exact receipt-trie inclusion encoding for this settler's `Filled` log
|
||||
|
||||
## Honest status
|
||||
|
||||
ON-CHAIN and tested today (`test/destination-settler.test.js`, 4 passing on Hardhat):
|
||||
ON-CHAIN and tested today (`aere-contracts/test/destination-settler.test.js`, 4 passing on Hardhat):
|
||||
|
||||
- A valid fill delivers the output to the recipient, records the fill, emits `Filled`,
|
||||
and exposes the record plus `fillCommitment`.
|
||||
|
||||
@ -21,7 +21,7 @@ New dir: `aerenew/contracts/contracts/erc8004/`
|
||||
window + cap + PQC). Settlement routes through the existing AERE402 rail (not redeployed); optional
|
||||
SETTLEMENT_EXECUTOR gate.
|
||||
|
||||
Test: `aerenew/contracts/test/erc8004-adapters.test.js`
|
||||
Test: `aere-contracts/test/erc8004-adapters.test.js`
|
||||
Doc: `aerenew/docs/AERE-ERC8004-X402-CONFORMANCE.md` (mapping table + PQC differentiator + honest status)
|
||||
|
||||
## REAL test result
|
||||
|
||||
@ -1,5 +1,17 @@
|
||||
# Aere Network: ERC-8004 and x402/AP2 Conformance
|
||||
|
||||
> **SUPERSEDED ON CONFORMANCE CLAIMS, 2026-07-20.**
|
||||
> This document describes a SEMANTIC MODEL of ERC-8004, not the standard's actual interface, and it
|
||||
> was never tested against the deployed contracts. A live read-only conformance suite run on
|
||||
> 2026-07-20 against chain 2800 measured **8 of 41 items passing: 0 of 28 ERC-8004 items, 0 of 3 x402
|
||||
> items, 8 of 9 post-quantum items.** The word "conformance" in this document's title is not earned.
|
||||
> Read `AERE-ERC8004-X402-CONFORMANCE-RESULT-2026-07-20.md` for the measured result and
|
||||
> `aerenew/contracts/test/erc8004-x402-conformance.live.test.js` for the suite.
|
||||
> Two specific corrections to what follows: ERC-8004 REQUIRES the Identity Registry to be an ERC-721
|
||||
> with URIStorage, which Aere's adapter is not; and the "18 passing" test below asserts against a
|
||||
> `MockPQCPrecompile` installed via `hardhat_setCode`, not against the live precompiles.
|
||||
> The architecture description below remains accurate and is kept for that reason.
|
||||
|
||||
Status: adapters built and tested. The live deployed agent contracts are unchanged. Adoption of these
|
||||
standards by the wider agent ecosystem is external to Aere and is not something Aere controls.
|
||||
|
||||
@ -35,7 +47,7 @@ New directory `aerenew/contracts/contracts/erc8004/`:
|
||||
| `AereValidationRegistry8004.sol` | ERC-8004 Validation registry with POST-QUANTUM proofs (the differentiator). |
|
||||
| `AereAP2MandateVerifier.sol` | x402/AP2 payment mandate verifier with a Falcon-512 (PQC) mandate signature. |
|
||||
|
||||
Test: `aerenew/contracts/test/erc8004-adapters.test.js` (18 passing, see "Test result" below).
|
||||
Test: `aere-contracts/test/erc8004-adapters.test.js` (18 passing, see "Test result" below).
|
||||
|
||||
The adapters take the live contract addresses in their constructors and wrap them. They never redeploy
|
||||
or modify the underlying deployed primitives.
|
||||
@ -189,7 +201,7 @@ field set and encoding with the final specs before claiming wire level conforman
|
||||
Command, run from `aerenew/contracts`:
|
||||
|
||||
```
|
||||
npx hardhat test test/erc8004-adapters.test.js
|
||||
npx hardhat test aere-contracts/test/erc8004-adapters.test.js
|
||||
```
|
||||
|
||||
Result: 18 passing.
|
||||
|
||||
@ -25,7 +25,7 @@ PROVED and every NEGATIVE CONTROL fired.
|
||||
|
||||
### A. computemarket_smt.py -> AereComputeMarketV3, ESCROW SOLVENCY
|
||||
|
||||
Contract: `aerenew/contracts/contracts/depin/AereComputeMarketV3.sol`
|
||||
Contract: `aere-contracts/contracts/depin/AereComputeMarketV3.sol`
|
||||
Invariant (the contract's own `isSolvent`): per asset T, `bal[T] >= totalLiabilities[T]` and
|
||||
`totalLiabilities[T] >= 0`, where a reward is escrowed in its own `token` and EVERY provider/challenger
|
||||
bond is native AERE (address(0)). So native liabilities carry native-token rewards PLUS all bonds; an
|
||||
@ -62,7 +62,7 @@ not re-proved by this SMT model.
|
||||
|
||||
### B. destinationsettler_smt.py -> AereDestinationSettler, NO-ARBITRARY-RECIPIENT + ATOMICITY
|
||||
|
||||
Contract: `aerenew/contracts/contracts/intents/AereDestinationSettler.sol`
|
||||
Contract: `aere-contracts/contracts/intents/AereDestinationSettler.sol`
|
||||
Guards modelled from the real `fill()`: G1 declOrderId==orderId, G2 declRecipient!=0, G3
|
||||
declOutputToken!=0, G4 declOutputAmount!=0, G5 fills[orderId].filler==0 (unfilled), G6 delivered token
|
||||
== declared token AND delivered recipient == declared recipient AND delivered amount >= declared amount.
|
||||
@ -83,8 +83,7 @@ Negative controls:
|
||||
attacker=2, deliveredRecipient=2]
|
||||
- no-AlreadyFilled settler CAN double-fill one order (double repayment)
|
||||
- no-ZeroRecipient settler CAN record a delivery to address(0)
|
||||
- no-OutputMismatch settler CAN record a wrong-token delivery [witness: declOutputToken=1,
|
||||
deliveredToken=2]
|
||||
- no-OutputMismatch settler CAN record a wrong-token delivery [witness: declared output token id 1, delivered token id 2]
|
||||
|
||||
[VERIFY] Delivery ATOMICITY (effects-before-interaction record, then a single SafeERC20 pull
|
||||
solver->recipient that reverts the whole tx on failure, under nonReentrant) is an EVM-revert property
|
||||
@ -93,7 +92,7 @@ validator-set-anchored finality+inclusion proof and is out of scope here.
|
||||
|
||||
### C. migrator_smt.py -> AereAccountMigrator, ONLY-DESTINATION + ATOMICITY
|
||||
|
||||
Contract: `aerenew/contracts/contracts/pqc/AereAccountMigrator.sol`
|
||||
Contract: `aere-contracts/contracts/pqc/AereAccountMigrator.sol`
|
||||
Guards modelled from the real `_migrate()`: H1 destination!=0, H2 length match, H3 each token/amount
|
||||
!=0, H4 moveNative => msg.value!=0, H5 !moveNative => msg.value==0 (StrayNative, the no-strand guard),
|
||||
H6 every ERC-20 leg is safeTransferFrom(caller, destination, amount), H7 native leg forwards the full
|
||||
|
||||
@ -5,11 +5,30 @@ Source review: `aerenew/docs/AERE-SECURITY-REVIEW-NEW-CONTRACTS.md` (no CRITICAL
|
||||
Applied fixes: `aerenew/docs/AERE-SECURITY-FIXES.md` (M1 fixed, L1 x3 fixed, L2 fixed, L3 documented).
|
||||
Solc 0.8.23, OpenZeppelin v4.9.x.
|
||||
|
||||
STATUS: NOTHING HERE IS DEPLOYED. Every contract below is founder-gated. This document is the exact,
|
||||
ordered procedure to deploy and verify each one WHEN the founder greenlights it. It does not deploy
|
||||
anything. Confirmed on 2026-07-19 that none of these 17 contracts has a `deployments/*.json` entry and
|
||||
none appears in `aerenew/sdk-js/src/addresses.ts`. Activation is the founder's decision, and where noted
|
||||
it also requires an external audit and, for three of them, a zk circuit that does not yet exist.
|
||||
STATUS UPDATE (2026-07-19): the founder greenlit the low-risk set ("hai incepe" -> deploy the clean Wave A).
|
||||
SEVEN clean contracts are now DEPLOYED and verified on mainnet 2800 (identity + compliance stack, all CLEAN
|
||||
in the security review, formally verified, no fund custody, no drainable admin, wired only to live addresses):
|
||||
|
||||
- AereRandomnessBeaconV2 0xaDC45101D408E88d3268e2262CD53F3A4eC92cfD
|
||||
- AereRecoveryRegistry 0x7A0A49C7485b7516d8fAC48CC04a2820E151A1d5
|
||||
- AereIdentityRegistry8004 0x5C65105E14BBD1aBb0c6bc76f3BcB340bbc308Ba
|
||||
- AereValidationRegistry8004 0xa8805c575227B2a81f71A1Cd4E2f7727aE2ada8C
|
||||
- AereBitstringStatusList 0x3C13a0c568F5d953d2Ef1d6B067B5D701649d6CB (nonRevocationVerifier = address(0))
|
||||
- AereTrustRegistry 0x9CF8b66e01eC6F4b40e11eef2AD59eF982F7BbD1 (owner = deployer; transfer to Foundation is a pending founder action)
|
||||
- AereVerifiableCredential 0x2c97d9808c44a98038B6a8D7fFcD686df625530f
|
||||
|
||||
Deployed from the designated deployer 0xbeB3..6465, total gas 7,961,951, ~0.00805 AERE, block ~10,412,111.
|
||||
Record: `aerenew/contracts/deployments/wave-a-identity-compliance-2026-07-19.json`. Consensus was NOT touched
|
||||
(still classical secp256k1 QBFT); these are application/account-layer contracts. "Deployed" is not "in
|
||||
production use": AereTrustRegistry still needs its owner transferred to the Foundation and issuers accredited
|
||||
before it asserts anything real.
|
||||
|
||||
STILL NOT DEPLOYED (the rest of the 17): the fund-flow contracts (AereAccountMigrator, AereDestinationSettler,
|
||||
AereVectorStore, AereComputeMarketV3) remain external-audit-gated; AereAP2MandateVerifier and
|
||||
AerePQAttestationKeyRegistry remain founder-config gated; and AerePQAggregateVerifier /
|
||||
AereFinalityCertificateVerifier / AerePQAggregateModule remain circuit-gated (their immutable vkeys pin SP1
|
||||
circuits that do not exist yet). The ordered procedure below still governs those. Activation of any of them is
|
||||
the founder's decision, and where noted also requires an external audit and a zk circuit that does not yet exist.
|
||||
|
||||
---
|
||||
|
||||
@ -154,7 +173,7 @@ is implied and not repeated each time.
|
||||
factory's own `predictAddress(pubKey, salt)` (CREATE2 parity).
|
||||
- A `migrate` with `moveNative=false` and non-zero `msg.value` reverts `StrayNative`; with an empty token
|
||||
array and `moveNative=false` reverts `NothingToMigrate`.
|
||||
- Run `aerenew/contracts/test/account-migrator.test.js` against a fork / live-like config.
|
||||
- Run `aere-contracts/test/account-migrator.test.js` against a fork / live-like config.
|
||||
- Gate: DEPLOY-WHEN-READY. External audit recommended because it moves user balances (no custody, but it
|
||||
is the tx that sweeps an EOA). Verdict CLEAN.
|
||||
|
||||
@ -169,7 +188,7 @@ is implied and not repeated each time.
|
||||
`DRAND_PERIOD()` == 3, `DRAND_GENESIS()` == 1692803367.
|
||||
- `verifyRound(round, sig)` with a REAL drand quicknet round returns true; with a tampered signature
|
||||
returns false (fail-closed). Confirm NO admin (no verification-off switch, no `owner()`).
|
||||
- Run `aerenew/contracts/test/AereRandomnessBeaconV2.test.js`.
|
||||
- Run `aere-contracts/test/AereRandomnessBeaconV2.test.js`.
|
||||
- Gate: DEPLOY-WHEN-READY. CLEAN. Honest note: drand BLS is classical, verifying it does not make the
|
||||
randomness post-quantum.
|
||||
|
||||
@ -184,7 +203,7 @@ is implied and not repeated each time.
|
||||
- `submitRecovery` with a valid Falcon signature over `recordChallenge(...)` appends a record and bumps
|
||||
the operator nonce; a tampered signature reverts `PQCVerificationFailed` and appends nothing.
|
||||
- Confirm NO owner / admin (append-only, no `owner()`).
|
||||
- Run `aerenew/contracts/test/AereRecoveryRegistry.test.js`.
|
||||
- Run `aere-contracts/test/AereRecoveryRegistry.test.js`.
|
||||
- Gate: DEPLOY-WHEN-READY. CLEAN (I4: `getRecord` on a bad id reverts `UnknownOperator`, cosmetic).
|
||||
|
||||
### A4. intents/AereDestinationSettler
|
||||
@ -198,7 +217,7 @@ is implied and not repeated each time.
|
||||
a second `fill` of the same order reverts `AlreadyFilled`; a good fill emits `Filled`, records the
|
||||
`FillRecord`, and `fillCommitment(orderId)` returns a non-zero binder.
|
||||
- Confirm NO custody / admin (solver-to-recipient direct transfer, no `owner()`).
|
||||
- Run `aerenew/contracts/test/destination-settler.test.js`.
|
||||
- Run `aere-contracts/test/destination-settler.test.js`.
|
||||
- Gate: DEPLOY-WHEN-READY for the on-chain filling side. The origin-chain repayment loop (SP1 prover over
|
||||
the `qbft-lightclient-guest` ELF plus an AereOutboundVerifierV2-style verifier deployed on the origin
|
||||
chain) is [MEASURE] and NOT part of this deploy; the settler is complete without it, but a solver is not
|
||||
@ -218,7 +237,7 @@ is implied and not repeated each time.
|
||||
on each enroll / key rotation.
|
||||
- Confirm a non-validator cannot register a key for another address (`registerAttestationKey` uses
|
||||
`msg.sender`), and a non-owner `enrollValidator` reverts `Ownable: caller is not the owner`.
|
||||
- Run `aerenew/contracts/test/AerePQFinalityCertificate.test.js` (covers registry + verifier).
|
||||
- Run `aere-contracts/test/AerePQFinalityCertificate.test.js` (covers registry + verifier).
|
||||
- Gate: FOUNDER-ACTION. The owner (Foundation, later the Timelock, founder-signed) enrolls the validator
|
||||
addresses; then EACH validator registers its OWN hash-based attestation key. Transfer ownership to the
|
||||
Foundation / Timelock after deploy. CLEAN. Note: this registry is only useful once C2 is live, which is
|
||||
@ -243,7 +262,7 @@ is implied and not repeated each time.
|
||||
revocation bits are terminal (clearing reverts `RevocationIsTerminal`), suspension bits are reversible.
|
||||
- `verifyNonRevocation(...)` reverts `NonRevocationNotConfigured` while the circuit is unset (so callers
|
||||
can never mistake "unconfigured" for "not revoked").
|
||||
- Run `aerenew/contracts/test/aere-pq-screen.test.js` (covers trust registry + VC + status list).
|
||||
- Run `aere-contracts/test/aere-pq-screen.test.js` (covers trust registry + VC + status list).
|
||||
- Gate: DEPLOY-WHEN-READY for the bitstring mechanism. The zk non-revocation feature is CIRCUIT-GATED:
|
||||
`ADMIN` calls `setNonRevocationVKey(<real vkey>)` only once the SP1 non-revocation circuit is built.
|
||||
CLEAN (I2: status roots are controller-attested by design; `getWord` allows independent recomputation).
|
||||
@ -263,7 +282,7 @@ is implied and not repeated each time.
|
||||
(the current Falcon-root controller) and reverts `NotController` otherwise; `resolveByDomain` /
|
||||
`getAgent` return the bound metadata; `didString(agentId)` == `did:aere:2800:<agentId>`.
|
||||
- Confirm NO owner / admin.
|
||||
- Run `aerenew/contracts/test/erc8004-adapters.test.js`.
|
||||
- Run `aere-contracts/test/erc8004-adapters.test.js`.
|
||||
- Gate: DEPLOY-WHEN-READY. CLEAN. [VERIFY] against the finalized ERC-8004 identity interface: Aere anchors
|
||||
the id to the Falcon-rooted DID id rather than minting a sequential ERC-721 id (documented divergence).
|
||||
|
||||
@ -282,7 +301,7 @@ is implied and not repeated each time.
|
||||
`responseChallenge(...)` and reverts `PQCValidationFailed` on a tampered proof; a request completes
|
||||
exactly once.
|
||||
- Confirm NO owner / admin.
|
||||
- Run `aerenew/contracts/test/erc8004-adapters.test.js`.
|
||||
- Run `aere-contracts/test/erc8004-adapters.test.js`.
|
||||
- Gate: DEPLOY-WHEN-READY. CLEAN (I5: permissionless request creation is storage-spam only, harmless).
|
||||
|
||||
### A9. erc8004/AereAP2MandateVerifier
|
||||
@ -306,7 +325,7 @@ is implied and not repeated each time.
|
||||
`NotSettlementExecutor`; from the executor with a valid signature within the window it records the spend
|
||||
and enforces the cap; a cap overflow reverts `MandateCapExceeded`.
|
||||
- Confirm NO owner / admin and NO fund custody (cap is accounting only).
|
||||
- Run `aerenew/contracts/test/erc8004-adapters.test.js` (includes the settlement-executor-gate test).
|
||||
- Run `aere-contracts/test/erc8004-adapters.test.js` (includes the settlement-executor-gate test).
|
||||
- Gate: FOUNDER-CONFIG at deploy. Production MUST pass a non-zero `settlementExecutor_`. CLEAN except the
|
||||
documented L3 open-path risk, which the non-zero executor closes.
|
||||
|
||||
@ -325,7 +344,7 @@ is implied and not repeated each time.
|
||||
true only for an ACTIVE issuer with the type in scope; `revokeIssuer` is terminal (a revoked issuer can
|
||||
never be reinstated); `verifyIssuerSignature` is fail-closed.
|
||||
- A non-owner `accreditIssuer` / `suspendIssuer` / `revokeIssuer` reverts `Ownable: caller is not the owner`.
|
||||
- Run `aerenew/contracts/test/aere-pq-screen.test.js`.
|
||||
- Run `aere-contracts/test/aere-pq-screen.test.js`.
|
||||
- Gate: FOUNDER-ACTION. After deploy, transfer ownership to the Foundation (the trusted-list operator),
|
||||
then accredit real issuers. CLEAN. Deploying does not assert any real institution is accredited.
|
||||
|
||||
@ -347,7 +366,7 @@ is implied and not repeated each time.
|
||||
by any address other than that provider reverts `NotReceiptProvider` and leaves the receipt unconsumed;
|
||||
the bound provider consumes it successfully.
|
||||
- Confirm NO owner / admin and no balance held across calls (delta-measured forward to recipient).
|
||||
- Run `aerenew/contracts/test/aere-vector-store.test.js`.
|
||||
- Run `aere-contracts/test/aere-vector-store.test.js`.
|
||||
- Gate: DEPLOY-WHEN-READY. External audit recommended (routes AERE402 payments). CLEAN with L2 fixed.
|
||||
|
||||
### A12. depin/AereComputeMarketV3
|
||||
@ -372,7 +391,7 @@ is implied and not repeated each time.
|
||||
`submitResultZK` after `verifyProof`; a `pqcSettlement` job's payout requires a valid Falcon signature
|
||||
over `settlementDigest(...)` or reverts `NotPQCAuthorized`.
|
||||
- Confirm NO owner and no sweep (only arbiter routing + governance allowlist).
|
||||
- Run `aerenew/contracts/test/AereComputeMarketV3.test.js` (includes the L1 construction-guard test).
|
||||
- Run `aere-contracts/test/AereComputeMarketV3.test.js` (includes the L1 construction-guard test).
|
||||
- Gate: EXTERNAL-AUDIT-GATED before mainnet (it is the highest-value fund-flow contract: escrowed rewards +
|
||||
provider / challenger bonds). FOUNDER-CONFIG for arbiter and governance. CLEAN, L1 fixed.
|
||||
|
||||
@ -395,7 +414,7 @@ is implied and not repeated each time.
|
||||
submit feedback in `{-1,0,+1}`; `removeFeedbackAuthor` re-blocks; only the owner manages the allowlist.
|
||||
- `canWriteThrough()` is true only when the reputation instance lists this adapter as an attestor
|
||||
(`AdapterNotAttestor` otherwise).
|
||||
- Run `aerenew/contracts/test/erc8004-adapters.test.js`.
|
||||
- Run `aere-contracts/test/erc8004-adapters.test.js`.
|
||||
- Gate: FOUNDER-ACTION for write-through. READ path is deploy-when-ready against the live instance. For
|
||||
write-through the Foundation must deploy / point a reputation instance that lists this adapter, then the
|
||||
owner authorizes feedback authors. Transfer ownership to the Foundation. M1 fixed.
|
||||
@ -417,7 +436,7 @@ is implied and not repeated each time.
|
||||
- `isValid(id)` flips to false the instant the issuer is suspended / revoked in A10 or the credential's
|
||||
status bit is set in A6.
|
||||
- Confirm NO owner / admin.
|
||||
- Run `aerenew/contracts/test/aere-pq-screen.test.js`.
|
||||
- Run `aere-contracts/test/aere-pq-screen.test.js`.
|
||||
- Gate: DEPLOY-WHEN-READY (after A10 + A6). CLEAN.
|
||||
|
||||
### C1. mpc/AerePQAggregateVerifier
|
||||
@ -436,7 +455,7 @@ is implied and not repeated each time.
|
||||
is fail-closed on every binding mismatch (root / threshold / size / scheme / digest / below-threshold)
|
||||
and delegates the one cryptographic check to `verifyProof`.
|
||||
- Confirm NO owner / admin and no fund custody.
|
||||
- Run `aerenew/contracts/test/AerePQAggregate.test.js` (uses a MOCK gateway; the real circuit is not
|
||||
- Run `aere-contracts/test/AerePQAggregate.test.js` (uses a MOCK gateway; the real circuit is not
|
||||
exercised, so passing tests do NOT prove end-to-end aggregation).
|
||||
- Gate: DEPENDENCY-GATED. DO NOT DEPLOY until the SP1 aggregation circuit exists and its real vkey is
|
||||
derived on a dedicated non-infra box. L1 fixed.
|
||||
@ -458,7 +477,7 @@ is implied and not repeated each time.
|
||||
- `currentQuorumThreshold()` == ceil(2N/3) for the live registry set (N=7 gives 5). `verifyCertificate`
|
||||
is fail-closed on root / size / domain / quorum mismatch; a rotation in A5 invalidates old certificates.
|
||||
- Confirm NO owner / admin.
|
||||
- Run `aerenew/contracts/test/AerePQFinalityCertificate.test.js` (MOCK gateway; real circuit not exercised).
|
||||
- Run `aere-contracts/test/AerePQFinalityCertificate.test.js` (MOCK gateway; real circuit not exercised).
|
||||
- Gate: DEPENDENCY-GATED. DO NOT DEPLOY until the PQ-finality aggregation circuit exists and its real vkey
|
||||
is known, AND A5 is deployed with the validator set enrolled and keyed. Additive to consensus, never a
|
||||
consensus flip. CLEAN, already carries the `VerifierHasNoCode` guard.
|
||||
@ -474,7 +493,7 @@ is implied and not repeated each time.
|
||||
`validateUserOp` returns 0 only when the signature carries a valid aggregate proof for the account's
|
||||
committee over `userOpHash`, else 1 (never reverts on a malformed signature).
|
||||
- Confirm NO owner / admin (singleton, per-account state keyed by `msg.sender`).
|
||||
- Run `aerenew/contracts/test/AerePQAggregate.test.js`.
|
||||
- Run `aere-contracts/test/AerePQAggregate.test.js`.
|
||||
- Gate: DEPENDENCY-GATED (through C1). [VERIFY] the ERC-7579 signature-unwrapping against the specific
|
||||
account stack (Safe7579 / Kernel / Nexus) you install it under. CLEAN.
|
||||
|
||||
|
||||
@ -29,11 +29,11 @@ Notes that apply to the whole table:
|
||||
|
||||
| Scheme | NIST standard | Standard status | Vectors we validate against | Where in repo | Honest caveat |
|
||||
|---|---|---|---|---|---|
|
||||
| ML-DSA-44 (Dilithium2), precompile `0x0AE3` | FIPS 204 | FINAL (Aug 2024). ACVP vectors exist. | Official NIST ACVP ML-DSA-sigVer-FIPS204 vectors, test group 8 (internal interface, externalMu=false). Accept the valid vector, reject the official crafted-invalid vectors (modified message, bad z, bad commitment, bad hint) plus explicit byte-flips and malformed lengths. | Fixture: `aerenew/contracts/test/fixtures/mldsa44-acvp-tg8.json`. Harness (subset): `aerenew/contracts/test/mldsa44Verifier.test.js`. Full 15/15: `aerenew/contracts/scripts/test-mldsa-local.js`. Native-fork KAT result: `aerenew/parallel/combined-fork-binary/logs/nist_kat_bc183.txt` (15 match, 0 mismatch). | These are genuine ACVP sigVer vectors, so "ACVP-style validation" is accurate here. It remains self-validation, not a CAVP/ACVP certificate. |
|
||||
| SLH-DSA-SHA2-128s (SPHINCS+-SHA2-128s-simple), precompile `0x0AE4` | FIPS 205 | FINAL (Aug 2024). ACVP vectors exist. | Official NIST ACVP SLH-DSA-sigVer-FIPS205 vectors, test group 31 (internal interface, preHash none). All 14 vectors reproduce NIST's expected testPassed value (accept the valid vectors, reject the invalid ones), plus byte-flip rejects. | Fixture: `aerenew/contracts/test/fixtures/sphincs-sha2-128s-acvp-tg31.json`. Harness: `aerenew/contracts/test/AereSphincsVerifier.test.js`. Native-fork KAT result: `nist_kat_bc183.txt` (14 match, 0 mismatch). | Genuine ACVP sigVer vectors. The fixture records the upstream ACVP-Server file SHA-256 hashes for reproducibility. Still self-validation, not a certificate. |
|
||||
| ML-KEM-768, precompile `0x0AE6` | FIPS 203 | FINAL (Aug 2024). ACVP vectors exist. | Official NIST ACVP ML-KEM-encapDecap-FIPS203 vectors (deterministic encapsulation: given ek and m, assert ciphertext c and shared key k match). README records 25/25. | Fetcher: `aerenew/pqc-fork/kat/fetch_acvp_mlkem.py`. Runner: `aerenew/pqc-fork/kat/MlKemAcvpKat.java`. Committed vectors: `aerenew/pqc-fork/vectors/mlkem768_acvp.txt`. Result: `aerenew/pqc-fork/results/kat-results-mlkem.json`. | TESTNET ONLY. This precompile is NOT active on Aere mainnet. It was built and KAT-verified on an isolated single-validator QBFT testnet. Mainnet activation is founder-gated and has not happened. |
|
||||
| SHAKE256, precompile `0x0AE5` | FIPS 202 | FINAL (long-standing). KAT/ACVP available. | FIPS 202 known-answer digests, for example the empty-string SHAKE256(32) value `0x46b9dd2b...ed5762f` and a short-message ("abc") digest. Asserted equal to the FIPS 202 reference output. | Solidity-level assertion in `aerenew/contracts/test/AereFalcon512Verifier.test.js`. On-chain eth_call check: `aerenew/parallel/combined-fork-binary/scripts/check5_precompiles.py`. Native-fork KAT result: `nist_kat_bc183.txt` (4 match, 0 mismatch). | What is committed and asserted here is a small set of FIPS 202 KAT digests, not the full NIST ACVP SHA-3/SHAKE test-group suite. Described honestly as KAT. `[VERIFY: if a claim of full ACVP SHAKE coverage is ever wanted, commit and run the complete NIST ACVP SHA-3 vector set.]` |
|
||||
| Falcon-512, precompile `0x0AE1`; Falcon-1024, precompile `0x0AE2` | FIPS 206 (FN-DSA) | DRAFT / NOT FINALIZED (expected around 2027). No official ACVP path yet. | Round-3 / reference Known Answer Test vectors only (the official Falcon reference `falconNNN-KAT.rsp` from the round-3 submission). Accept the official KAT signature and a second KAT vector, reject a tampered signature, a tampered message, a tampered signed-message blob, and a valid signature under the wrong public key. | Falcon-512 fixture: `aerenew/contracts/test/falcon512_kat0.json`; harness: `aerenew/contracts/test/AereFalcon512Verifier.test.js`. Falcon-1024 fixture: `aerenew/contracts/test/falcon1024_kat0.json`; harness: `aerenew/contracts/test/AereFalcon1024Verifier.test.js`. Native-fork KAT result: `nist_kat_bc183.txt` (valid + reject for both). | HONEST KEY POINT. There is no final FN-DSA standard and no official ACVP validation path for Falcon yet. Aere validates Falcon against round-3 / reference KAT vectors only and CANNOT claim FIPS or ACVP validation for Falcon until FIPS 206 finalizes. Do not describe Falcon as "ACVP-validated" or "FIPS-validated" anywhere in public copy. |
|
||||
| ML-DSA-44 (Dilithium2), precompile `0x0AE3` | FIPS 204 | FINAL (Aug 2024). ACVP vectors exist. | Official NIST ACVP ML-DSA-sigVer-FIPS204 vectors, test group 8 (internal interface, externalMu=false). Accept the valid vector, reject the official crafted-invalid vectors (modified message, bad z, bad commitment, bad hint) plus explicit byte-flips and malformed lengths. | Fixture: `aere-contracts/test/fixtures/mldsa44-acvp-tg8.json`. Harness (subset): `aere-contracts/test/mldsa44Verifier.test.js`. Full 15/15: `aerenew/contracts/scripts/test-mldsa-local.js`. Native-fork KAT result: `aerenew/parallel/combined-fork-binary/logs/nist_kat_bc183.txt` (15 match, 0 mismatch). | These are genuine ACVP sigVer vectors, so "ACVP-style validation" is accurate here. It remains self-validation, not a CAVP/ACVP certificate. |
|
||||
| SLH-DSA-SHA2-128s (SPHINCS+-SHA2-128s-simple), precompile `0x0AE4` | FIPS 205 | FINAL (Aug 2024). ACVP vectors exist. | Official NIST ACVP SLH-DSA-sigVer-FIPS205 vectors, test group 31 (internal interface, preHash none). All 14 vectors reproduce NIST's expected testPassed value (accept the valid vectors, reject the invalid ones), plus byte-flip rejects. | Fixture: `aere-contracts/test/fixtures/sphincs-sha2-128s-acvp-tg31.json`. Harness: `aere-contracts/test/AereSphincsVerifier.test.js`. Native-fork KAT result: `nist_kat_bc183.txt` (14 match, 0 mismatch). | Genuine ACVP sigVer vectors. The fixture records the upstream ACVP-Server file SHA-256 hashes for reproducibility. Still self-validation, not a certificate. |
|
||||
| ML-KEM-768, precompile `0x0AE6` | FIPS 203 | FINAL (Aug 2024). ACVP vectors exist. | Official NIST ACVP ML-KEM-encapDecap-FIPS203 vectors (deterministic encapsulation: given ek and m, assert ciphertext c and shared key k match). README records 25/25. | Fetcher: `aere-research/kat/fetch_acvp_mlkem.py`. Runner: `aere-research/kat/MlKemAcvpKat.java`. Committed vectors: `aere-research/vectors/mlkem768_acvp.txt`. Result: `aere-research/results/kat-results-mlkem.json`. | TESTNET ONLY. This precompile is NOT active on Aere mainnet. It was built and KAT-verified on an isolated single-validator QBFT testnet. Mainnet activation is founder-gated and has not happened. |
|
||||
| SHAKE256, precompile `0x0AE5` | FIPS 202 | FINAL (long-standing). KAT/ACVP available. | FIPS 202 known-answer digests, for example the empty-string SHAKE256(32) value `0x46b9dd2b...ed5762f` and a short-message ("abc") digest. Asserted equal to the FIPS 202 reference output. | Solidity-level assertion in `aere-contracts/test/AereFalcon512Verifier.test.js`. On-chain eth_call check: `aerenew/parallel/combined-fork-binary/scripts/check5_precompiles.py`. Native-fork KAT result: `nist_kat_bc183.txt` (4 match, 0 mismatch). | What is committed and asserted here is a small set of FIPS 202 KAT digests, not the full NIST ACVP SHA-3/SHAKE test-group suite. Described honestly as KAT. `[VERIFY: if a claim of full ACVP SHAKE coverage is ever wanted, commit and run the complete NIST ACVP SHA-3 vector set.]` |
|
||||
| Falcon-512, precompile `0x0AE1`; Falcon-1024, precompile `0x0AE2` | FIPS 206 (FN-DSA) | DRAFT / NOT FINALIZED (expected around 2027). No official ACVP path yet. | Round-3 / reference Known Answer Test vectors only (the official Falcon reference `falconNNN-KAT.rsp` from the round-3 submission). Accept the official KAT signature and a second KAT vector, reject a tampered signature, a tampered message, a tampered signed-message blob, and a valid signature under the wrong public key. | Falcon-512 fixture: `aere-contracts/test/falcon512_kat0.json`; harness: `aere-contracts/test/AereFalcon512Verifier.test.js`. Falcon-1024 fixture: `aere-contracts/test/falcon1024_kat0.json`; harness: `aere-contracts/test/AereFalcon1024Verifier.test.js`. Native-fork KAT result: `nist_kat_bc183.txt` (valid + reject for both). | HONEST KEY POINT. There is no final FN-DSA standard and no official ACVP validation path for Falcon yet. Aere validates Falcon against round-3 / reference KAT vectors only and CANNOT claim FIPS or ACVP validation for Falcon until FIPS 206 finalizes. Do not describe Falcon as "ACVP-validated" or "FIPS-validated" anywhere in public copy. |
|
||||
|
||||
### 2.1 The Falcon caveat, stated plainly
|
||||
|
||||
@ -54,7 +54,7 @@ For the finalized signature schemes (ML-DSA-44 and SLH-DSA-128s) the reject vect
|
||||
|
||||
Validation is performed at more than one layer, and all layers must agree:
|
||||
|
||||
- Solidity / EVM layer. Hardhat test suites deploy the on-chain verifier contracts and drive them against the committed JSON fixtures. Examples: `aerenew/contracts/test/mldsa44Verifier.test.js`, `aerenew/contracts/test/AereSphincsVerifier.test.js`, `aerenew/contracts/test/AereFalcon512Verifier.test.js`, `aerenew/contracts/test/AereFalcon1024Verifier.test.js`.
|
||||
- Solidity / EVM layer. Hardhat test suites deploy the on-chain verifier contracts and drive them against the committed JSON fixtures. Examples: `aere-contracts/test/mldsa44Verifier.test.js`, `aere-contracts/test/AereSphincsVerifier.test.js`, `aere-contracts/test/AereFalcon512Verifier.test.js`, `aere-contracts/test/AereFalcon1024Verifier.test.js`.
|
||||
- Native precompile layer. The precompile implementations themselves (Bouncy Castle backed) are exercised by a Java KAT harness on a separate build host, driven by `aerenew/parallel/combined-fork-binary/scripts/run_kat.sh`, which compiles and runs the probe against `bcprov-jdk18on-1.83.jar`. The committed result of that run is `aerenew/parallel/combined-fork-binary/logs/nist_kat_bc183.txt`: Falcon-512 and Falcon-1024 valid plus reject, ML-DSA-44 15/15, SLH-DSA-128s 14/14, SHAKE256 4/4, zero mismatches.
|
||||
- Live on-chain layer. After the fork cross, all five mainnet precompiles were exercised by direct `eth_call` against a running node (`aerenew/parallel/combined-fork-binary/scripts/check5_precompiles.py`), and a verify-and-record probe wrote accept/reject results into contract state (`aerenew/dryrun-results/dryrun/phase_postfork_kat.sh`), confirming that an invalid vector reverts on-chain and a valid one records success.
|
||||
|
||||
@ -62,6 +62,52 @@ Validation is performed at more than one layer, and all layers must agree:
|
||||
|
||||
The signature and KEM math is provided by Bouncy Castle, specifically bcprov-jdk18on-1.83.jar, as recorded in `run_kat.sh` and in the build record `aerenew/parallel/combined-fork-binary/BUILD_INFO.txt`. Aere's contribution is the EVM precompile plumbing, the calldata encoding, the gas accounting, and the validation harness, not a new implementation of ML-DSA, SLH-DSA, Falcon, ML-KEM, or SHAKE.
|
||||
|
||||
### 3.4 Audit status of the primitive library itself
|
||||
|
||||
This section exists because of a specific correction. Until 2026-08-03, 19 places across 17 published
|
||||
files described the dependency with an unsupported adjective, calling the library audited. No
|
||||
audit was ever cited,
|
||||
because none of the audits that exist covers what we use. The adjective has been removed from every
|
||||
published file. What follows is what can actually be cited, with certificate numbers.
|
||||
|
||||
- **What Aere ships is not a validated module.** The artifact on the client classpath is
|
||||
`bcprov-jdk18on-1.83.jar`, the general-purpose Bouncy Castle provider. It is not a FIPS validated
|
||||
cryptographic module and it carries no certificate number. We searched for a published third-party
|
||||
security audit of it and did not find one. Until we can name and link such an audit, the honest
|
||||
statement is that the library is unaudited so far as we know, and Aere makes no audit claim about
|
||||
it.
|
||||
- **A validated Bouncy Castle module does exist, but it is a different artifact.** BC-FJA, the Bouncy
|
||||
Castle FIPS Java API, ships as the `bc-fips` jar. Its active CMVP certificates are #4743 (BC-FJA
|
||||
2.0.0, FIPS 140-3, validated 2024-07-29) and #4943 (BC-FJA 2.1.1, validated 2025-01-17). Aere does
|
||||
not ship BC-FJA. No part of either certificate covers anything on the Aere client classpath.
|
||||
- **Neither certificate would cover our algorithms even if we did ship BC-FJA.** We read the approved
|
||||
algorithm table on both certificate pages directly. Neither #4743 nor #4943 lists ML-DSA, SLH-DSA,
|
||||
ML-KEM or Falcon. Both cover classical primitives only: AES, the SHA families, HMAC, RSA, DSA,
|
||||
ECDSA, KDFs and DRBGs. The Bouncy Castle FIPS roadmap describes BC-FJA 2.1 as adding post-quantum
|
||||
algorithms at the API level, but an algorithm present in a validated module's API is not the same
|
||||
as an algorithm on its CMVP approved list, and only the latter is a validation claim.
|
||||
- **Falcon could not be covered by any certificate today.** FIPS 206 (FN-DSA, the standardized form
|
||||
of Falcon) is still a draft. Falcon-512 (`0x0AE1`) and Falcon-1024 (`0x0AE2`) are two of the five
|
||||
precompiles live on Aere mainnet, so two fifths of the live PQC surface rests on a scheme that has
|
||||
no finalized standard to be validated against.
|
||||
- **What Aere can honestly say about the library is narrow, and it is said in section 3.2.** The exact
|
||||
jar is pinned by version and recorded in the build record, and its outputs are reproduced
|
||||
bit-for-bit against the official NIST KAT and ACVP vectors, in both the accept and the reject
|
||||
direction. That is reproducible evidence of correct behaviour on the published vectors. It is not
|
||||
an audit. It says nothing about side channels, memory safety, resource exhaustion, or behaviour on
|
||||
inputs that no published vector covers.
|
||||
- **Residual risk, stated plainly.** Assumption A-7 in `AERE-ENGINEERING-SECURITY-SPEC.md` stands
|
||||
unchanged and is now the whole of the claim: a bug in Bouncy Castle is a bug in the Aere
|
||||
precompiles, and no third party has certified that library against that risk for the algorithms we
|
||||
actually use.
|
||||
|
||||
Sources for this section, all read directly on 2026-08-03:
|
||||
NIST CMVP certificate #4743 <https://csrc.nist.gov/projects/cryptographic-module-validation-program/Certificate/4743>,
|
||||
NIST CMVP certificate #4943 <https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4943>,
|
||||
Bouncy Castle FIPS FAQ <https://www.bouncycastle.org/about/bouncy-castle-fips-faq/>,
|
||||
Bouncy Castle Java FIPS roadmap <https://www.bouncycastle.org/download/bouncy-castle-java-fips/roadmap/>,
|
||||
NIST FIPS 206 (FN-DSA) status <https://csrc.nist.gov/presentations/2025/fips-206-fn-dsa-falcon>.
|
||||
|
||||
## 4. What this is NOT
|
||||
|
||||
This section exists to prevent overclaiming. Each line is a thing an auditor, a bank, or a developer might reasonably ask about, answered honestly.
|
||||
@ -82,9 +128,11 @@ The point of self-validation is that anyone can rerun it. The committed inputs (
|
||||
|
||||
---
|
||||
|
||||
### Appendix A: items flagged for human verification before publishing
|
||||
### Appendix A: facts published as NOT MEASURED ([VERIFY] flags)
|
||||
|
||||
Each item below is a permanent, deliberate disclosure that the named fact is **NOT MEASURED**. It is published as it stands, it does not block publication, and it is closed only by a measurement, never by deletion. The full rule is `VERIFY-POLICY.md` at the root of this repository.
|
||||
|
||||
- `[VERIFY]` The native Bouncy Castle KAT harness source (referred to as `Probe.java` in `run_kat.sh`) and the flat vector files it consumes (`falcon512.txt`, `falcon1024.txt`, `mldsa44.txt`, `slhdsa128s.txt`, `shake256.txt`, expected on a separate build host at `<work>/probe/` and `<fork>/probe/`) are NOT committed to this repository. What IS committed is the result log (`nist_kat_bc183.txt`), the JSON fixtures, the Solidity/JS harnesses, and the run scripts. Decide whether to commit `Probe.java` and the flat vector files so the native-layer run is fully reproducible from the repo alone.
|
||||
- `[VERIFY]` SHAKE256 coverage is described as KAT (a small set of FIPS 202 known-answer digests), not full ACVP SHA-3/SHAKE suite coverage. If a stronger claim is ever wanted, commit and run the complete NIST ACVP SHA-3 vector set first.
|
||||
- `[VERIFY]` The Falcon KAT provenance cited in the harness comment is `falcon512-KAT.rsp`, vector 0, SHA-256 `dd75c946...b5cd`, reproduced from the round-3 submission. Only the extracted vector-0 (and vector-1) JSON is committed, not the original `.rsp` file. Confirm the `.rsp` source hash independently if provenance is challenged.
|
||||
- `[VERIFY]` Confirm the block number for mainnet precompile activation (9,189,161) and the precompile addresses `0x0AE1` through `0x0AE5` against the live chain before publishing, and confirm ML-KEM-768 (`0x0AE6`) and Falcon HashToPoint (`0x0AE7`) remain testnet only.
|
||||
- `[VERIFY]` Confirm the block number for mainnet precompile activation (9,189,161) and the precompile addresses `0x0AE1` through `0x0AE5` against the live chain, and confirm ML-KEM-768 (`0x0AE6`) and Falcon HashToPoint (`0x0AE7`) remain testnet only.
|
||||
|
||||
@ -62,16 +62,16 @@ Both expose the `IVotes` interface that OpenZeppelin's Governor reads via `getPa
|
||||
|
||||
### 2.3 The post-quantum threshold account
|
||||
|
||||
`AereThresholdAccount` (source `aerenew/contracts/contracts/mpc/AereThresholdAccount.sol`) is a non-custodial ERC-4337 v0.7 smart account whose owner is a t-of-n post-quantum committee. A call is authorized only when at least `threshold` DISTINCT committee members each supply a valid NIST post-quantum signature (Falcon-512 or Falcon-1024 or ML-DSA-44 or SLH-DSA-128s) over the account's domain-separated challenge, every leg verified in full, on-chain, through the live precompiles. No single party's key can move funds; there is no admin, owner override, or recovery backdoor. It exposes two domain-separated paths: an ERC-4337 `validateUserOp` path (bundler), and a direct `executeThreshold(target, value, data, legs)` self-relay path with its own `execNonce` replay barrier. Each leg is verified through the shared library `AerePQCThreshold`, whose scheme-to-precompile routing is `1 = Falcon-512 (0x0AE1)`, `2 = Falcon-1024 (0x0AE2)`, `3 = ML-DSA-44 (0x0AE3)`, `4 = SLH-DSA-128s (0x0AE4)`.
|
||||
`AereThresholdAccount` (source `aere-contracts/contracts/mpc/AereThresholdAccount.sol`) is a non-custodial ERC-4337 v0.7 smart account whose owner is a t-of-n post-quantum committee. A call is authorized only when at least `threshold` DISTINCT committee members each supply a valid NIST post-quantum signature (Falcon-512 or Falcon-1024 or ML-DSA-44 or SLH-DSA-128s) over the account's domain-separated challenge, every leg verified in full, on-chain, through the live precompiles. No single party's key can move funds; there is no admin, owner override, or recovery backdoor. It exposes two domain-separated paths: an ERC-4337 `validateUserOp` path (bundler), and a direct `executeThreshold(target, value, data, legs)` self-relay path with its own `execNonce` replay barrier. Each leg is verified through the shared library `AerePQCThreshold`, whose scheme-to-precompile routing is `1 = Falcon-512 (0x0AE1)`, `2 = Falcon-1024 (0x0AE2)`, `3 = ML-DSA-44 (0x0AE3)`, `4 = SLH-DSA-128s (0x0AE4)`.
|
||||
|
||||
Deployment status of the threshold family:
|
||||
|
||||
| Component | Address | Status |
|
||||
| --- | --- | --- |
|
||||
| `AereThresholdAccountFactory` (CREATE2 factory for the account) | `0xf8fCC337d7749Ff2935D755C5F3934e2B70779E8` | LIVE on mainnet, but carries a duplicate-committee-key finding; 0 accounts ever created (zero exposure). Superseded by a source-only fix. |
|
||||
| Account factory V2 (fixed, rejects duplicate keys) | not on mainnet | Source-fixed; mainnet redeploy is founder-gated. `[VERIFY: a session note recorded a V2 factory at 0x69734E4044B1C5943B9256A73De41B101BFA2633, but it was not independently confirmed on-chain and is treated here as not deployed. Confirm before citing as live.]` |
|
||||
| Account factory V2 (rejects duplicate keys) | `0x69734E4044B1C5943B9256A73De41B101BFA2633` | **Deployed. Code present at `0x69734E4044B1C5943B9256A73De41B101BFA2633`: 6,835 bytes measured at head block 11,810,041 on 2026-08-01, against 6,717 bytes at V1 `0xf8fCC337…`. The earlier "treated here as not deployed" is therefore wrong and is withdrawn.** What is **NOT MEASURED** is the build identity: we could not reproduce that runtime from the repository artifact (the artifact is 7,407 bytes and matches neither V1, nor V2, nor a metadata-trimmed variant of either), so we cannot yet assert from bytecode that the deployed code is the duplicate-key-guard build. The honest status is **deployed, code present, build identity NOT MEASURED**. Do not cite it as the fixed factory until the build is reproduced. |
|
||||
| `AereThresholdPQCRegistry` (registry-style t-of-n PQC authorization, buggy) | `0x9a6096F6FB3a7E54cF70DE12Cb3903Ae79D1C213` | LIVE, same duplicate-key finding, 0 committees (zero exposure). Superseded. |
|
||||
| `AereThresholdPQCRegistry` V2 (fixed) | `0x8Fbfe1C72E8c83ca2a0c475ce3648D47bCC8643c` | Deployed and live on mainnet, inert (0 committees). |
|
||||
| `AereThresholdPQCRegistry` V2 (fixed) | `0x8Fbfe1C72E8c83ca2a0c475ce3648D47bCC8643c` | Deployed and live on mainnet, inert (0 committees). 5,909 bytes of live code measured 2026-08-01. **Not in `sdk-js/src/addresses.ts`**, which still carries only the superseded V1 `0x9a6096F6…`; the registry needs updating so it does not point integrators at the buggy one. |
|
||||
| `AereThresholdRegistry` (classical threshold-ECDSA sibling, clean) | `0x875BA0dbA1806Ad9aE57627d705ecA12139D1EF4` | LIVE, no fund custody, 0 committees. Metadata plus `ecrecover`, not post-quantum. |
|
||||
|
||||
The registry V2 (`0x8Fbfe1...`) proves the t-of-n Falcon verification path end to end on live precompiles today. The account factory that would mint a control-bearing threshold account with the duplicate-key fix is not yet on mainnet; its redeploy is founder-gated (see Section 4).
|
||||
@ -145,12 +145,14 @@ The end-to-end property is that every authority-bearing decision on the path, wh
|
||||
|
||||
| Element | Classification | Basis |
|
||||
| --- | --- | --- |
|
||||
| Falcon-512 verification of a governance signature | Capability, live | `0x0AE1` live since block 9,189,161; used in production by `AerePQCAttestation`, `AerePQCKeyRegistry`, `AereThresholdPQCRegistry` V2. |
|
||||
| Falcon-512 verification of a governance signature | Capability, live | `0x0AE1` live since block 9,189,161; deployed and exercised end to end by `AerePQCAttestation`, `AerePQCKeyRegistry`, `AereThresholdPQCRegistry` V2. See the usage note below. |
|
||||
| Falcon-authenticated ballot via EIP-1271 voter (A1) | Capability, on existing primitives | Unmodified OpenZeppelin `castVoteBySig` plus EIP-1271 already routes signature authority to the voter account; needs a precompile-backed `AerePQCAccount` voter, no Governor change. |
|
||||
| Explicit `castVoteWithFalconSig` extension (A2) | New contract work | A new, small `AerePQCGovernor` counting extension plus a proof-of-possession key binding. Audit-scoped. |
|
||||
| t-of-n Falcon committee holding a Timelock role (B) | Capability in principle, gated in practice | `AereThresholdAccount` exists and its verification path is proven; a control-bearing account needs the founder-gated factory V2 redeploy (below). Wiring is a role grant on the Timelock. |
|
||||
| End-to-end post-quantum-authorized upgrade (C) | Composition of the above | No new consensus or protocol change; a composition of A, B, and the standard lifecycle. |
|
||||
|
||||
**Usage note, stated honestly.** An earlier revision of this table said the `0x0AE1` precompile was "used in production" by those three contracts. That claim was withdrawn on 2026-07-20 because nothing in this repository established it. What IS established and independently checkable: the precompile is live from block 9,189,161, and the three contracts are deployed with non-empty bytecode (MEASURED via `eth_getCode`: `AerePQCAttestation` at `0x465d9E3b476BF98Aa1393079e240Db5D2a9bEA6A` returns 4,402 bytes, `AerePQCKeyRegistry` at `0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691` returns 6,430 bytes). What is NOT established is ongoing real-world usage: a bounded `eth_getLogs` sample over the most recent 5,000 blocks (to head block 10,572,989) returned zero events for both addresses. That sample covers roughly 42 minutes of chain time and therefore does not establish lifetime call counts in either direction; a lifetime count would require an indexer scan that has not been run. Read "deployed and callable" as proven and "in production use" as unproven.
|
||||
|
||||
### 4.2 Governance is inert today
|
||||
|
||||
Nothing in this design is live governance. The Governor and Timelock own nothing and control nothing until an audit-gated ownership transfer, live voting power is zero because no AERE is staked, and the Foundation key (a single-key EOA, not yet a multisig) still owns effectively every Ownable protocol contract across 7 Foundation-operated QBFT validators. A passed proposal, classical or post-quantum-signed, changes nothing about the protocol until stake exists and ownership is migrated. This design does not change that status; it specifies the authentication the governance layer should use if and when it is activated.
|
||||
@ -204,7 +206,7 @@ The one-sentence statement of scope: this specifies how governance authenticates
|
||||
| `AereGovLockV2` (govAERE) | `0x547F58B087BEbB1746d6159070E755b868C27731` | Canonical vote source. |
|
||||
| `AereStakedGovVotes` (original gAERE) | `0xD7575795A055cb093957B86f0607871A2D37805C` | Deprecated ERC20Votes adapter. |
|
||||
| `AereThresholdAccountFactory` (live V1) | `0xf8fCC337d7749Ff2935D755C5F3934e2B70779E8` | Duplicate-key finding; 0 accounts; superseded. |
|
||||
| Account factory V2 (fixed) | not on mainnet | Founder-gated redeploy. `[VERIFY: 0x69734E4044B1C5943B9256A73De41B101BFA2633 recorded in a session note, not confirmed on-chain; treated as not deployed.]` |
|
||||
| Account factory V2 | `0x69734E4044B1C5943B9256A73De41B101BFA2633` | Deployed, 6,835 bytes of live code measured 2026-08-01 (V1 is 6,717). Build identity **NOT MEASURED**: the repo artifact is 7,407 bytes and reproduces neither version, so we cannot yet assert from bytecode that this is the duplicate-key-guard build. |
|
||||
| `AereThresholdPQCRegistry` V1 (buggy) | `0x9a6096F6FB3a7E54cF70DE12Cb3903Ae79D1C213` | 0 committees; superseded. |
|
||||
| `AereThresholdPQCRegistry` V2 (fixed) | `0x8Fbfe1C72E8c83ca2a0c475ce3648D47bCC8643c` | Deployed and live, inert. |
|
||||
| `AereThresholdRegistry` (ECDSA sibling) | `0x875BA0dbA1806Ad9aE57627d705ecA12139D1EF4` | Classical threshold-ECDSA, not post-quantum. |
|
||||
@ -214,4 +216,4 @@ The one-sentence statement of scope: this specifies how governance authenticates
|
||||
| `AerePQCAttestation` | `0x465d9E3b476BF98Aa1393079e240Db5D2a9bEA6A` | Reference pattern: on-chain precompile-verified, domain-separated, replay-protected. |
|
||||
| `AereGovernorV2Timelock` guardian (design) | to be an `AereThresholdAccount` | Minted by the fixed factory V2 once founder-gated redeploy occurs. |
|
||||
|
||||
Source files: `aerenew/contracts/contracts/mpc/AereThresholdAccount.sol`, `aerenew/contracts/contracts/mpc/AerePQCThreshold.sol`, `aerenew/docs/GOVERNANCE.md`, `aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md`, `aerenew/docs/AUDIT-FINDING-THRESHOLD-DUPLICATE-KEYS-2026-07-15.md`, `aerenew/sdk-js/src/addresses.ts`.
|
||||
Source files: `aere-contracts/contracts/mpc/AereThresholdAccount.sol`, `aere-contracts/contracts/mpc/AerePQCThreshold.sol`, `aerenew/docs/GOVERNANCE.md`, `aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md`, `aerenew/docs/AUDIT-FINDING-THRESHOLD-DUPLICATE-KEYS-2026-07-15.md`, `aerenew/sdk-js/src/addresses.ts`.
|
||||
|
||||
@ -5,27 +5,27 @@ Constant-cost on-chain verification of a t-of-n POST-QUANTUM committee authoriza
|
||||
succinct SP1 proof, exposed as an ERC-4337 path and a portable ERC-7579 validator module.
|
||||
|
||||
### Files (new, no deployed contracts modified)
|
||||
- `aerenew/contracts/contracts/mpc/AerePQAggregateVerifier.sol`
|
||||
- `registerCommittee(root, t, n, scheme)` — stores committee (root = commitment to n PQC keys;
|
||||
- `aere-contracts/contracts/mpc/AerePQAggregateVerifier.sol`
|
||||
- `registerCommittee(root, t, n, scheme)`, stores committee (root = commitment to n PQC keys;
|
||||
keys NOT stored on-chain, so cost stays O(1) in n). Permissionless, no admin, no funds.
|
||||
- `verifyAggregate(committeeId, messageDigest, publicValues, proofBytes)` view — strict fail-closed:
|
||||
- `verifyAggregate(committeeId, messageDigest, publicValues, proofBytes)` view, strict fail-closed:
|
||||
binds committeeRoot / t / n / scheme / messageDigest / validCount>=t, then ONE
|
||||
`SP1_GATEWAY.verifyProof(pinnedVKey, publicValues, proofBytes)`. Reverts on any mismatch or bad proof.
|
||||
- `tryVerifyAggregate(...)` view — non-reverting bool (try/catch wrap) for 4337/7579 SHOULD-not-revert.
|
||||
- `recordAggregate(...)` — strict verify + provenance attestation event.
|
||||
- `tryVerifyAggregate(...)` view, non-reverting bool (try/catch wrap) for 4337/7579 SHOULD-not-revert.
|
||||
- `recordAggregate(...)`, strict verify + provenance attestation event.
|
||||
- Immutable `SP1_GATEWAY` (chain 2800 canonical Succinct gateway 0x9ca479C8…70628) and
|
||||
`AGGREGATE_PROGRAM_VKEY` (pinned circuit; registrant cannot swap circuits).
|
||||
- Public-values layout (fixed 192 bytes / 6 words):
|
||||
`abi.encode(bytes32 committeeRoot, uint256 t, uint256 n, uint256 scheme, bytes32 msgDigest, uint256 validCount)`.
|
||||
- `aerenew/contracts/contracts/modular/AerePQAggregateModule.sol`
|
||||
- `aere-contracts/contracts/modular/AerePQAggregateModule.sol`
|
||||
- ERC-7579 type-1 validator (matches OZ draft-IERC7579 `IERC7579Validator`): `onInstall`/`onUninstall`/
|
||||
`isModuleType`, `validateUserOp(PackedUserOperation, bytes32)->uint256` (0/1), and
|
||||
`isValidSignatureWithSender(address,bytes32,bytes)->bytes4` (0x1626ba7e / 0xffffffff).
|
||||
- Singleton, per-account committee binding keyed by msg.sender (AereSessionKeyValidator pattern).
|
||||
- Signature layout: `abi.encode(bytes publicValues, bytes proofBytes)`; malformed => FAILED, no revert.
|
||||
- Local PackedUserOperation struct (self-contained, portable to any EVM chain).
|
||||
- `aerenew/contracts/test/AerePQAggregate.test.js` — 17 tests.
|
||||
- `aerenew/docs/AERE-PQ-AGGREGATE.md` — scheme, gas argument, 4337/7579 portability, Bank28 use case,
|
||||
- `aere-contracts/test/AerePQAggregate.test.js`, 17 tests.
|
||||
- `aerenew/docs/AERE-PQ-AGGREGATE.md`, scheme, gas argument, 4337/7579 portability, Bank28 use case,
|
||||
honest [MEASURE] status.
|
||||
|
||||
## REAL test result
|
||||
|
||||
@ -6,7 +6,7 @@ on-chain in ONE call, WITHOUT changing QBFT consensus and WITHOUT a re-genesis.
|
||||
|
||||
## Deliverables (all new, no deployed contract modified)
|
||||
|
||||
1. `aerenew/contracts/contracts/pqfinality/AerePQAttestationKeyRegistry.sol`
|
||||
1. `aere-contracts/contracts/pqfinality/AerePQAttestationKeyRegistry.sol`
|
||||
- Per-validator hash-based attestation public key (XMSS / WOTS+ / leanSig / SLH-DSA / XMSS^MT),
|
||||
SEPARATE from the ECDSA consensus key. This is the PQ finality key.
|
||||
- Maps validator -> current key + monotonic keyEpoch. One-time/few-time keys rotate: registering
|
||||
@ -17,7 +17,7 @@ on-chain in ONE call, WITHOUT changing QBFT consensus and WITHOUT a re-genesis.
|
||||
- Deterministic `validatorSetRoot()` = keccak over (validator, keyEpoch, keyHash) leaves in
|
||||
enrollment order. Any rotation changes the root.
|
||||
|
||||
2. `aerenew/contracts/contracts/pqfinality/AereFinalityCertificateVerifier.sol`
|
||||
2. `aere-contracts/contracts/pqfinality/AereFinalityCertificateVerifier.sol`
|
||||
- Verifies ONE SP1 proof via the live gateway (0x9ca479C8...70628), pinned PROGRAM_VKEY.
|
||||
- Public values (192 bytes): blockHash, blockHeight, validatorSetRoot, validatorSetSize,
|
||||
quorumCount, attestationDomain.
|
||||
@ -27,7 +27,7 @@ on-chain in ONE call, WITHOUT changing QBFT consensus and WITHOUT a re-genesis.
|
||||
- `isFinalPQ(blockHash)` consumer gate + `recordCertificate` + `assertFinalizes(claimedBlock)`
|
||||
for bridges confirming a specific block.
|
||||
|
||||
3. `aerenew/contracts/test/AerePQFinalityCertificate.test.js` - 12 passing (MockSp1Verifier).
|
||||
3. `aere-contracts/test/AerePQFinalityCertificate.test.js` - 12 passing (MockSp1Verifier).
|
||||
Covers all required cases: 7-validator set registers (threshold 5); valid quorum-5 cert records +
|
||||
isFinalPQ true; below-quorum rejects; wrong root rejects; wrong block/height/zero-block rejects;
|
||||
invalid proof fail-closed; key rotation changes root and old-root cert no longer matches; empty
|
||||
|
||||
@ -143,7 +143,7 @@ The certificate reads the chain; it does not change how the chain is produced.
|
||||
be armed WITHOUT a re-genesis via a contract-anchored fork activation; the certificate needs even
|
||||
less, because it never gates a block).
|
||||
- Separation of concerns. The blocking hybrid ECDSA-plus-Falcon consensus path (formally proven
|
||||
no-worse-than-ECDSA in `aerenew/formal-consensus/falcon_hybrid_dualquorum_smt.py`, with in-place
|
||||
no-worse-than-ECDSA in `aere-research/formal-consensus/falcon_hybrid_dualquorum_smt.py`, with in-place
|
||||
activation proven in the PQ-INPLACE-ACTIVATION work) makes CONSENSUS itself refuse a block
|
||||
without a post-quantum quorum. The certificate is the READ side: it lets external parties verify
|
||||
a post-quantum finality quorum without waiting for, or depending on, the consensus flip. The two
|
||||
@ -276,7 +276,7 @@ for the [MEASURE] circuit once it is real.
|
||||
client this certificate is the post-quantum counterpart to).
|
||||
- Registry pattern: `contracts/contracts/pqc/AerePQCKeyRegistry.sol`,
|
||||
`contracts/contracts/validators/AereValidatorManifest.sol`.
|
||||
- Consensus-side backing: `aerenew/formal-consensus/falcon_hybrid_dualquorum_smt.py`
|
||||
- Consensus-side backing: `aere-research/formal-consensus/falcon_hybrid_dualquorum_smt.py`
|
||||
(hybrid dual-quorum proven no-worse-than-ECDSA), the PQ-CONSENSUS-STEP2 and
|
||||
PQ-INPLACE-ACTIVATION work (blocking hybrid consensus with in-place, no-re-genesis activation).
|
||||
- Quantum scope boundary: `aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md` (signatures and
|
||||
|
||||
@ -6,10 +6,10 @@ stack (AereZKScreen, AereCompliancePool, AereSanctionsRegistry, AerePQCKeyRegist
|
||||
any deployed contract. Three new contracts + 1 test + 1 doc.
|
||||
|
||||
### Files (all new)
|
||||
- `aerenew/contracts/contracts/compliance/AereTrustRegistry.sol`
|
||||
- `aerenew/contracts/contracts/compliance/AereVerifiableCredential.sol`
|
||||
- `aerenew/contracts/contracts/compliance/AereBitstringStatusList.sol`
|
||||
- `aerenew/contracts/test/aere-pq-screen.test.js`
|
||||
- `aere-contracts/contracts/compliance/AereTrustRegistry.sol`
|
||||
- `aere-contracts/contracts/compliance/AereVerifiableCredential.sol`
|
||||
- `aere-contracts/contracts/compliance/AereBitstringStatusList.sol`
|
||||
- `aere-contracts/test/aere-pq-screen.test.js`
|
||||
- `aerenew/docs/AERE-PQ-SCREEN.md`
|
||||
|
||||
### 1. AereTrustRegistry (federated accredited issuers, eIDAS-2.0-in-spirit)
|
||||
|
||||
@ -13,7 +13,7 @@ contracts under `aerenew/contracts/contracts/compliance/` and does not modify an
|
||||
## Honest status (read this first)
|
||||
|
||||
- CONTRACTS: built and tested. Three new Solidity 0.8.23 contracts, 12 passing Hardhat tests
|
||||
(`test/aere-pq-screen.test.js`), verified against the repo's MockPQCPrecompile at 0x0AE1 exactly as
|
||||
(`aere-contracts/test/aere-pq-screen.test.js`), verified against the repo's MockPQCPrecompile at 0x0AE1 exactly as
|
||||
the erc8004 and PQC test suites do.
|
||||
- POST-QUANTUM SIGNATURE PATH: real. Issuer attestations are Falcon-512 signatures verified on-chain
|
||||
through the live AerePQCKeyRegistry, which routes to precompile 0x0AE1 (live on chain 2800,
|
||||
@ -179,14 +179,14 @@ get elsewhere, and it is the reason this passport exists.
|
||||
|
||||
## Files
|
||||
|
||||
- `aerenew/contracts/contracts/compliance/AereTrustRegistry.sol`
|
||||
- `aerenew/contracts/contracts/compliance/AereVerifiableCredential.sol`
|
||||
- `aerenew/contracts/contracts/compliance/AereBitstringStatusList.sol`
|
||||
- `aerenew/contracts/test/aere-pq-screen.test.js` (12 passing tests)
|
||||
- `aere-contracts/contracts/compliance/AereTrustRegistry.sol`
|
||||
- `aere-contracts/contracts/compliance/AereVerifiableCredential.sol`
|
||||
- `aere-contracts/contracts/compliance/AereBitstringStatusList.sol`
|
||||
- `aere-contracts/test/aere-pq-screen.test.js` (12 passing tests)
|
||||
|
||||
## Test result
|
||||
|
||||
`npx hardhat test test/aere-pq-screen.test.js` from `aerenew/contracts`: 12 passing. Covers
|
||||
`npx hardhat test aere-contracts/test/aere-pq-screen.test.js` from `aerenew/contracts`: 12 passing. Covers
|
||||
accreditation lifecycle (append-only history, terminal revocation, fail-closed accreditation),
|
||||
credential issue and verify with a Falcon-512 signature via the 0x0AE1 mock, revocation via the
|
||||
Bitstring Status List flipping verification to false, a non-accredited (wrong-scope) issuer being
|
||||
|
||||
@ -19,7 +19,7 @@ A second implementation team should be able to take a stock Besu (or a stock Net
|
||||
**Honesty conventions used throughout.**
|
||||
|
||||
- A value that is directly sourceable from the repository, an AIP, or the live chain is stated plainly.
|
||||
- A value that could not be confirmed from a primary source in the repository at authoring time carries an explicit **[VERIFY: ...]** note for a human to close before external publication. Section 8 collects every such flag.
|
||||
- A value that could not be confirmed from a primary source in the repository at authoring time carries an explicit **[VERIFY: ...]** note. Such a note is a permanent, deliberate disclosure that the value is **NOT MEASURED**. It is published as it stands, it does not block publication, and it is closed only by a measurement, never by deletion. The consolidated [VERIFY] register near the end of this document (Section 11) collects every such flag, and the full rule is `VERIFY-POLICY.md` at the root of this repository.
|
||||
- The **post-quantum scope boundary is absolute and repeated because it is the single most common thing to get wrong about Aere**: the post-quantum precompiles are an application-layer and account-layer verification surface. Consensus on Aere is classical secp256k1 ECDSA under QBFT. The on-chain zero-knowledge verifiers are classical BN254 pairing checks. **Aere consensus is not post-quantum, and this document never claims that it is.**
|
||||
|
||||
**Typographic note.** This specification avoids em-dashes in prose. Ranges and address bands use `..` (for example `0x0AE1..0x0AE5`). Field layouts in fenced blocks and tables use their own syntax.
|
||||
@ -73,11 +73,11 @@ Anywhere this document is silent, the referenced upstream is authoritative.
|
||||
|
||||
The primary Aere sources this specification draws from, all in the repository:
|
||||
|
||||
- `aerenew/aips/AIP-3.md` (block period), `AIP-4.md` (PQC verifier suite and account layer), `AIP-7.md` (the AerePQC hard-fork activation).
|
||||
- `aerenew/research/aip-draft-pqc-precompiles.md` (the precompile mechanism specification, including the as-shipped reconciliation of malformed-input behavior).
|
||||
- `aerenew/contracts/contracts/pqc/AerePQCAttestation.sol` (the on-chain consuming contract that builds the exact precompile input; the authoritative byte-layout oracle for the live `0x0AE1..0x0AE4` precompiles, whose native source lives in the gold binary rather than the repository).
|
||||
- `aere-research/aips/AIP-3.md` (block period), `AIP-4.md` (PQC verifier suite and account layer), `AIP-7.md` (the AerePQC hard-fork activation).
|
||||
- `aere-research/research/aip-draft-pqc-precompiles.md` (the precompile mechanism specification, including the as-shipped reconciliation of malformed-input behavior).
|
||||
- `aere-contracts/contracts/pqc/AerePQCAttestation.sol` (the on-chain consuming contract that builds the exact precompile input; the authoritative byte-layout oracle for the live `0x0AE1..0x0AE4` precompiles, whose native source lives in the gold binary rather than the repository).
|
||||
- `aerenew/pqc-fork/precompiles/*.java` (the source of the non-live `0x0AE6`, `0x0AE7`, and the `0x0AE8` skeleton).
|
||||
- `aerenew/contracts/contracts/AereCoinbaseSplitterV2.sol` and `aerenew/contracts/contracts/sink/AereSink.sol` (burn and routing).
|
||||
- `aere-contracts/contracts/AereCoinbaseSplitterV2.sol` and `aere-contracts/contracts/sink/AereSink.sol` (burn and routing).
|
||||
- `aerenew/docs/AERE-EIP-COMPATIBILITY-MATRIX.md`, `AERE-ENGINEERING-SECURITY-SPEC.md`, `AERE-ARCHITECTURE-MAP.md`.
|
||||
- `aere-genesis-current.json` (the genesis config).
|
||||
|
||||
@ -120,10 +120,33 @@ Aere runs a shorter block period than Ethereum, and it changed once mid-chain vi
|
||||
|
||||
| Epoch | Block range | Target period | Mechanism |
|
||||
|---|---|---|---|
|
||||
| Genesis era | block 0 .. 2,138,450 | 1,000 ms | genesis `config.qbft.blockperiodseconds = 1` |
|
||||
| Sub-second era | block 2,138,451 onward | 500 ms | QBFT `transitions.qbft` entry `{ "block": 2138451, "xblockperiodmilliseconds": 500 }` |
|
||||
| Genesis era | block 0 .. 2,137,651 | 1,000 ms | genesis `config.qbft.blockperiodseconds = 1` |
|
||||
| Sub-second era | block 2,137,652 onward | 500 ms | `config.transitions.qbft` entry `{ "block": 2137652, "xblockperiodmilliseconds": 500 }` |
|
||||
|
||||
The transition key is `xblockperiodmilliseconds` (milliseconds), distinct from the seconds-based `blockperiodseconds` used for the initial value. State, balances, code, and the validator set were unchanged across the transition. Block intervals before 2,138,451 are approximately 1000 ms and after are approximately 500 ms, verifiable by `eth_getBlockByNumber` timestamp deltas. (Source: `AIP-3`.)
|
||||
<!-- QBFT-TRANSITION-CANONICAL path=config.transitions.qbft key=xblockperiodmilliseconds block=2137652 value=500 -->
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"qbft": { "blockperiodseconds": 1, "epochlength": 30000, "requesttimeoutseconds": 4 },
|
||||
"transitions": {
|
||||
"qbft": [
|
||||
{ "block": 2137652, "xblockperiodmilliseconds": 500 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Three details are easy to get wrong and all three are load bearing.
|
||||
|
||||
1. **Path.** The transition array lives at `config.transitions.qbft`, a sibling of `config.qbft`, not inside it. Besu reads the key `transitions` from the config root (`JsonGenesisConfigOptions.java:47`) and then the sub key `qbft` (`TransitionsConfigOptions.getQbftForks()`). A `transitions` array placed inside `config.qbft` is never read, parses without error, and is silently inert.
|
||||
2. **Key.** The key is `xblockperiodmilliseconds`, with the `x` prefix, which marks it experimental in Besu (`BftFork.java:48`). The unprefixed `blockperiodmilliseconds` is not a Besu key and is silently ignored.
|
||||
3. **Block number.** `2137652` is the first block on chain 2800 whose timestamp equals its parent's, which is only possible once the millisecond period is in force. A node whose transition is configured at any block *later* than 2,137,652 still has a one second minimum period at block 2,137,652, applies `TimestampMoreRecentThanParent` (`QbftBlockHeaderValidationRulesetFactory.java:80-83`), and **rejects that block**, halting the sync.
|
||||
|
||||
State, balances, code, and the validator set were unchanged across the transition. Block intervals before 2,137,652 are 1,000 ms and settle to approximately 500 ms shortly after, verifiable by `eth_getBlockByNumber` timestamp deltas. Full evidence, including the Besu source citations and the live measurement: `aerenew/docs/TRANZITIA-QBFT-SETTLED-2026-07-20.md`. (Source: `AIP-3`.)
|
||||
|
||||
**Erratum, 2026-07-20.** Earlier revisions of this section gave the transition block as `2,138,451`. The path and the key were right; the block number was wrong. Measurement of live block timestamps shows the one second cadence ends at 2,137,651, not 2,138,450. The value 2,138,451 is still present in the genesis file the live RPC node runs, which means that file cannot re-validate history from block zero. See the settled document for the consequence.
|
||||
|
||||
Finality is deterministic and single-slot: a committed block is final when produced (Section 3). "Sub-second finality" therefore means approximately 0.5 s worst-case inclusion-to-final latency in the sub-second era, not a probabilistic confirmation depth.
|
||||
|
||||
@ -136,7 +159,9 @@ Finality is deterministic and single-slot: a committed block is final when produ
|
||||
|
||||
**The ambiguity, stated plainly.** The genesis declares a block gas limit of 2^53 − 1, which is not a meaningful economic block target; it is an effectively unbounded ceiling. Besu adjusts the block gas limit from the parent by at most 1/1024 per block (standard Ethereum block-gas-limit dynamics), so the *operative* block gas limit on the live chain is whatever the validators have converged the header field to since genesis, not the genesis 2^53 − 1 literally. The *binding* per-transaction constraint that matters for protocol design is the EIP-7825 cap of 2^24, which is identical to Ethereum L1 and is the reason the PQC precompiles (Section 4) exist at all. A reimplementer MUST set the genesis `gasLimit` field to `0x1fffffffffffff` to match block-0 hashing, and MUST enforce EIP-7825 per-transaction. The effective per-block gas limit on the live chain head is an operational value, not a genesis constant.
|
||||
|
||||
[VERIFY: the operative block gas limit on the live chain 2800 head (the header `gasLimit` field at recent heights), since genesis declares 2^53 − 1 but Besu block-gas-limit dynamics may have moved the operative value; confirm against `eth_getBlockByNumber("latest")`.]
|
||||
**CLOSED by measurement 2026-08-01.** `eth_getBlockByNumber("latest")` on `https://rpc.aere.network` at head block 11,810,041 returns `gasLimit` = `0x1fffffffffffff` = 9,007,199,254,740,991, **identical to the genesis value**. Besu's 1/1024-per-block dynamics have not moved it in 11.8 million blocks, because nothing has ever pushed against it. So the operative block gas limit and the genesis constant are the same number today, and the paragraph above should be read as a statement about what *could* drift rather than what has.
|
||||
|
||||
One consequence is worth stating because it cuts the other way. The per-transaction EIP-7825 cap of 2^24 named above is **NOT MEASURED** and this document should not lean on it. We could not confirm it by reading: an `eth_call` carrying gas `0x2000000` (33,554,432, above the stated cap) succeeded without error, and `eth_estimateGas` does not discriminate. The only conclusive probe is a transaction above the cap, which we do not send. And because the header limit is 9.0 quadrillion, the cap cannot be inferred from the block limit either. A reimplementer MUST still enforce EIP-7825 per-transaction to match Ethereum L1 semantics; what we cannot currently do is *demonstrate* from chain reads that the live node enforces it.
|
||||
|
||||
### 2.4 QBFT consensus parameters
|
||||
|
||||
@ -161,7 +186,7 @@ Genesis QBFT config (from `aere-genesis-current.json`):
|
||||
}
|
||||
```
|
||||
|
||||
The live chain additionally carries the block-2,138,451 `xblockperiodmilliseconds: 500` transition (Section 2.2). The `aere-genesis-current.json` file in the repository is a base config that does not itself carry the block-period transition or the Cancun/Prague/Osaka/futureEips fork-time fields; those are part of the running client's chain configuration and are enumerated in Section 2.5. A reimplementer must merge the transition and fork times into the config as specified.
|
||||
The live chain additionally carries the block-2,137,652 `xblockperiodmilliseconds: 500` transition (Section 2.2). The `aere-genesis-current.json` file in the repository is a base config that does not itself carry the block-period transition or the Cancun/Prague/Osaka/futureEips fork-time fields; those are part of the running client's chain configuration and are enumerated in Section 2.5. A reimplementer must merge the transition and fork times into the config as specified.
|
||||
|
||||
[VERIFY: whether the authoritative running genesis/config on chain 2800 carries the Cancun/Prague/Osaka/futureEips time fields inline (they are absent from `aere-genesis-current.json` in the repo but are required to reproduce the fork schedule in Section 2.5).]
|
||||
|
||||
@ -172,14 +197,25 @@ Aere tracks Ethereum's hard forks so that its EVM surface matches mainnet at the
|
||||
| Ethereum fork | Aere activation | Gate | Note |
|
||||
|---|---|---|---|
|
||||
| London, Shanghai | Genesis (block 0) | `londonBlock: 0`, `shanghaiTime: 0` | Active from genesis. |
|
||||
| Cancun + Prague (Pectra) | Block 2,075,363 | `cancunTime == pragueTime == 1780189051` | Cancun and Prague share one activation instant on Aere. |
|
||||
| Osaka (Fusaka) | Block 2,106,606 | `osakaTime == 1780220351` | RIP-7951 P-256 at `0x100` active from here. |
|
||||
| AerePQC milestone | Block 9,189,161 | Besu `futureEipsTime == 1783820272` (2026-07-12 01:37:52 UTC) | PQC precompiles `0x0AE1..0x0AE5` + EIP-2935 write path + EIP-7939. |
|
||||
| Base-fee floor | Block 10,141,734 | client flag `aere.basefee.floor.forkBlock` | 1-Gwei EIP-1559 base-fee floor (Section 5.1). |
|
||||
| Cancun + Prague (Pectra) | **Block 2,075,341** *(measured)* | `cancunTime == pragueTime == 1780189051` | Cancun and Prague share one activation instant on Aere. |
|
||||
| Osaka (Fusaka) | **Block 2,106,597** *(measured)* | `osakaTime == 1780220351` | EIP-7951 P-256 at `0x100` active from here. |
|
||||
| AerePQC milestone | **Block 9,189,161** *(measured)* | Besu `futureEipsTime == 1783820272` (2026-07-12 01:37:52 UTC) | PQC precompiles `0x0AE1..0x0AE5` + EIP-2935 write path + EIP-7939. |
|
||||
| Base-fee floor | **Block 10,141,734** *(measured)* | client flag `aere.basefee.floor.forkBlock` | 1-Gwei EIP-1559 base-fee floor (Section 5.1). |
|
||||
|
||||
The Cancun/Prague/Osaka activations are gated by timestamp in the config, so the block heights 2,075,363 and 2,106,606 are the observed first-block-past-timestamp and should be confirmed against the live head history.
|
||||
The Cancun/Prague/Osaka activations are gated by timestamp, not by block number, so the block heights are an observation about when a timestamp was crossed and must be read off the chain rather than assumed.
|
||||
|
||||
[VERIFY: block heights 2,075,363 (Pectra) and 2,106,606 (Osaka) against the live chain head history; the config gates these by timestamp, not block number.]
|
||||
**Correction (2026-07-19).** This table previously read **2,075,363** (Pectra) and **2,106,606** (Osaka). Both were wrong. The correct heights were established by binary-searching the live chain for the first block whose timestamp reaches each activation instant, read-only against `https://rpc.aere.network`:
|
||||
|
||||
| Block | Timestamp | `requestsHash` / Cancun header fields |
|
||||
|---|---|---|
|
||||
| 2,075,340 | 1780189050 | **absent** |
|
||||
| **2,075,341** | **1780189051** (`pragueTime`) | **present** (`requestsHash = sha256("")`, `blobGasUsed`, `excessBlobGas`, `parentBeaconBlockRoot`) |
|
||||
| 2,106,596 | 1780220350 | present |
|
||||
| **2,106,597** | **1780220351** (`osakaTime`) | present |
|
||||
|
||||
Two independent signals agree at the Pectra boundary: 2,075,341 is both the first block whose timestamp reaches `pragueTime` and the first block to carry the Cancun/Prague header fields at all (block 2,075,340 carries none of them). The previously published 2,075,363 and 2,106,606 are 22 and 9 blocks late respectively. These heights now agree with `AERE-EIP-COMPATIBILITY-MATRIX.md`, which had already been corrected.
|
||||
|
||||
The AerePQC milestone height 9,189,161 was confirmed by the same binary search (first block with timestamp >= `futureEipsTime = 1783820272`), and the base-fee floor block 10,141,734 was confirmed directly from block base fees (7 wei at 10,141,733, 1,000,000,000 wei at 10,141,734). Block heights on this chain are not a stable API; they are recorded only because they are useful for locating a boundary in an explorer.
|
||||
|
||||
---
|
||||
|
||||
@ -236,7 +272,7 @@ These follow from the QBFT quorum math and the locking property, plus the fault-
|
||||
|
||||
### 3.5 Block-period transition as a consensus config rule
|
||||
|
||||
The only Aere-specific consensus *rule* beyond parameters is the timed block-period transition (Section 2.2), which a reimplementer must apply: from block 2,138,451 the QBFT block period is 500 ms rather than the genesis 1000 ms. This is a Besu QBFT `transitions` entry, applied automatically by any node synced from genesis against the correct config. It changes timing only and does not alter QBFT's fault tolerance.
|
||||
The only Aere-specific consensus *rule* beyond parameters is the timed block-period transition (Section 2.2), which a reimplementer must apply: from block 2,137,652 the QBFT block period is 500 ms rather than the genesis 1000 ms. This is a Besu QBFT `transitions` entry, applied automatically by any node synced from genesis against the correct config. It changes timing only and does not alter QBFT's fault tolerance.
|
||||
|
||||
### 3.6 A note on base-fee validation under QBFT
|
||||
|
||||
@ -263,7 +299,7 @@ These conventions apply to all five live verify/hash precompiles and are the *as
|
||||
- **Malformed is indistinguishable from invalid.** Because malformed input returns the same `0x00..00` word as a non-verifying signature, a consuming contract MUST validate field lengths itself and MUST NOT rely on a revert to detect malformed input. Integrating contracts treat a zero word or empty output as "not verified".
|
||||
- **Pre-activation behavior.** Before block 9,189,161 the band addresses were empty accounts; a `CALL`/`STATICCALL` to any of them succeeded with empty return data (an empty-account call). A consuming contract's length check therefore fails safely on a pre-fork or unforked node, so a stale caller can never record a false positive. Integrators SHOULD gate precompile use on chain height past the activation block, not on probing.
|
||||
- **Determinism.** Each precompile is a pure function of its input bytes. It reads no chain state, no block context, and no nondeterministic source. Verification is integer-only (Falcon verification uses the integer HashToPoint, integer NTT, and integer norm check; it never touches the floating-point Falcon signing path). All nodes run an identical client build, so all nodes compute the identical result and gas charge.
|
||||
- **Implementation boundary.** Each precompile is a thin adapter that parses the packed input, invokes the audited Bouncy Castle 1.83 (`bcprov-jdk18on-1.83.jar`) BCPQC verifier already on the client classpath (behind a dedicated classloader-isolation boundary so BC 1.83 cannot collide with the older Bouncy Castle Besu bundles), and encodes the result. There is zero new hand-rolled cryptography. The pure-Solidity verifiers in `aerenew/contracts/contracts/pqc/` are the differential oracle, not the security boundary.
|
||||
- **Implementation boundary.** Each precompile is a thin adapter that parses the packed input, invokes the Bouncy Castle 1.83 (`bcprov-jdk18on-1.83.jar`) BCPQC verifier already on the client classpath (behind a dedicated classloader-isolation boundary so BC 1.83 cannot collide with the older Bouncy Castle Besu bundles), and encodes the result. There is zero new hand-rolled cryptography. The pure-Solidity verifiers in `aerenew/contracts/contracts/pqc/` are the differential oracle, not the security boundary. Bouncy Castle here is a pinned dependency validated by us against official NIST vectors, not an audited one: see `AERE-NIST-VALIDATION-STATUS.md` section 3.4.
|
||||
|
||||
**Authoritative byte-layout source.** The native source of `0x0AE1..0x0AE5` lives in the gold binary (fork commit `c8d2ef9`, "AERE PQC fork baseline (0x0AE1-0x0AE5)"), not in the repository. The byte-exact input layout the live precompiles parse is therefore drawn from the on-chain consuming contract `AerePQCAttestation.sol` (which builds inputs the live precompiles accept, proven by a real on-chain attestation) and the committed conformance KAT vectors. The layouts in Sections 4.2 through 4.4 are as built by `AerePQCAttestation._buildInput` and are the reference a reimplementer should match, with the KAT vectors as the differential oracle.
|
||||
|
||||
@ -408,15 +444,17 @@ Live confirmation (2026-07-18):
|
||||
- `outLen = 64`, data `abc` returns 64 bytes whose first 32 bytes match the `outLen = 32` result (confirming squeezing).
|
||||
- The draft 4-byte framing `0x00000020616263` returns `0x` (empty), not parsed under the shipped encoding.
|
||||
|
||||
**Gas.** Per-word charge over the data processed plus output, matching the shape of `KECCAK256`:
|
||||
**Gas.** Per-word charge over the data processed plus output, matching the shape of `KECCAK256`. The data length and the output length are each rounded up to whole words **separately**, then added:
|
||||
|
||||
```
|
||||
words = ceil((len(data) + outLen) / 32)
|
||||
words = ceil(len(data) / 32) + ceil(outLen / 32)
|
||||
gas = SHAKE_BASE + SHAKE_WORD * words
|
||||
= 60 + 12 * words
|
||||
```
|
||||
|
||||
`SHAKE_BASE = 60` (fixed base, matching the `SHA256` precompile base at `0x02`); `SHAKE_WORD = 12` gas per 32-byte word. A standalone SHAKE256 verify-and-record transaction measured 21,470 gas (0.13% of the cap). An implementation MAY impose an `outLen` upper bound as a chain constant to bound worst-case work.
|
||||
> **Correction (2026-07-19).** This section previously specified `words = ceil((len(data) + outLen) / 32)`, adding the two lengths *before* rounding. That is not what the chain does. Besu, the canonical client that produced every block on chain 2800, rounds each length up separately. Established by measuring `0x0AE5` on live mainnet 2800 across 56 input shapes and fitting both models with no hypothesis assumed: separate-words reproduces 56/56 exactly (SSE 0); combined-words reproduces 47/56 (SSE 1296). The forms diverge exactly when `len(data) mod 32` and `outLen mod 32` are both nonzero. This is a normative specification clause, so the prior text would have put the spec in direct contradiction with the running implementation.
|
||||
|
||||
`SHAKE_BASE = 60` (fixed base, matching the `SHA256` precompile base at `0x02`); `SHAKE_WORD = 12` gas per 32-byte word. Both constants re-measured on live mainnet 2800 on 2026-07-19 and confirmed. A standalone SHAKE256 verify-and-record transaction measured 21,470 gas (0.13% of the cap) **on the isolated scratch fork, chain 28099, not on mainnet 2800; no transaction hash is recorded for it**. An implementation MAY impose an `outLen` upper bound as a chain constant to bound worst-case work.
|
||||
|
||||
[VERIFY: whether the live `0x0AE5` enforces an `outLen` upper bound, and if so its value; the design allowed an optional chain-constant bound but the shipped bound (if any) is not sourced in the repository.]
|
||||
|
||||
@ -431,13 +469,15 @@ The AerePQC fork activates the native EIP-2935 history-storage system contract.
|
||||
- **Reach.** At the 500 ms block period, 8191 blocks is approximately 68 minutes of trustless lookback, versus the approximately 128 seconds the 256-block `BLOCKHASH` opcode gives (which remains available and unchanged).
|
||||
- **Deployment provenance.** The system contract's runtime bytecode is byte-identical to Ethereum's Pectra deployment and was deployed post-genesis via the canonical keyless "Nick's method" transaction `0x67139a552b0d3fffc30c0fa7d0c20d42144138c8fe07fc5691f09c1cce632e15` (mined at block 9,182,379, status 1), so the block-0 state root is unchanged. `eth_getCode` at the address returns the canonical Pectra runtime, which encodes the 8191-block ring buffer.
|
||||
|
||||
Nominal Pectra parity lists EIP-2935 from block 2,075,363, but the system contract was not populated on mainnet until the write path shipped in the AerePQC fork at block 9,189,161; from that block the window is live.
|
||||
Nominal Pectra parity lists EIP-2935 from block 2,075,341, but the system contract was not populated on mainnet until the write path shipped in the AerePQC fork at block 9,189,161; from that block the window is live.
|
||||
|
||||
### 4.7 EIP-7939 (CLZ opcode)
|
||||
|
||||
The AerePQC milestone also activates the EIP-7939 `CLZ` (count leading zeros) opcode. It is a standard Fusaka-era opcode; on Aere it activated at the post-Osaka AerePQC milestone (block 9,189,161) rather than at the Osaka boundary, and the live EIP-2124 fork id folds this in.
|
||||
|
||||
[VERIFY: that EIP-7939 CLZ activated at the AerePQC milestone block 9,189,161 specifically, and not at Osaka (block 2,106,606); confirm against the live fork schedule. The Nethermind live-sync fork-id mirror maps it to the post-Osaka boundary.]
|
||||
The `CLZ` opcode is confirmed live at the current head: a state-override `eth_call` executing `PUSH1 0x01; CLZ` returns 255 and `PUSH0; CLZ` returns 256, both correct per EIP-7939 (measured 2026-07-19).
|
||||
|
||||
[VERIFY: the activation *height* for EIP-7939 specifically (AerePQC milestone block 9,189,161 versus Osaka block 2,106,597). CLZ is confirmed present at head, but the boundary itself is not probeable by `eth_call` because the public RPC has pruned state at that height. The Nethermind live-sync fork-id mirror maps it to the post-Osaka boundary.]
|
||||
|
||||
### 4.8 Precompiles built but NOT live on mainnet (specified for completeness)
|
||||
|
||||
@ -507,7 +547,21 @@ Aere makes two distinct, deliberately separated changes in the fee area. One is
|
||||
|
||||
Activation was clean: base fee 7 wei at block 10,141,733 becomes 1 Gwei at 10,141,734 and stays 1 Gwei; the fork-block hash was identical across the public RPC and the second RPC (no split); N = 7 held with no halt. (Source: memory `rpc_basefee_honesty_fix`; runbook `aerenew/docs/BASEFEE-FLOOR-FORK-RUNBOOK-2026-07-17.md`.)
|
||||
|
||||
[VERIFY: EIP-1559 base-fee *disposal* on chain 2800, that is whether the 1559 base fee is protocol-burned as on Ethereum or credited. The documented Aere "burn" is the separate validator-reward cut of Section 5.2, so the base-fee disposal itself should be stated precisely before publication.]
|
||||
**Exact clamp (the part a reimplementer must match).** The floor is a single helper applied at every base-fee return path of the EIP-1559 recurrence. Because the mainnet ruleset calls the same `computeBaseFee` both to *produce* and to *validate* a block's base fee, the one clamp covers both directions:
|
||||
|
||||
```java
|
||||
private Wei applyAereBaseFeeFloor(final long blockNumber, final Wei fee) {
|
||||
if (blockNumber >= AERE_BASEFEE_FLOOR_FORK_BLOCK
|
||||
&& !fee.greaterOrEqualThan(AERE_BASEFEE_FLOOR_VALUE)) {
|
||||
return AERE_BASEFEE_FLOOR_VALUE;
|
||||
}
|
||||
return fee;
|
||||
}
|
||||
```
|
||||
|
||||
with `AERE_BASEFEE_FLOOR_FORK_BLOCK = 10141734` and `AERE_BASEFEE_FLOOR_VALUE = 1000000000` (1 Gwei), applied at the three exits of `computeBaseFee(blockNumber, parentBaseFee, parentGasUsed, targetGasUsed)`. Equivalently, `baseFee(B) = max(baseFee_1559(parent), 10^9)` for `number(B) >= 10,141,734` and the unmodified `baseFee_1559(parent)` otherwise. The two driving values are client system properties whose defaults are dormant (`forkBlock = Long.MAX_VALUE`, so the floor is never active), which is why the pre-fork build is byte-identical to stock and every historical block below 10,141,734 still validates with its original sub-Gwei base fee. (Source: runbook `aerenew/basefee-floor-dryrun/basefee-floor.diff`, §2 of the runbook.)
|
||||
|
||||
[VERIFY (narrowed by measurement 2026-07-19): EIP-1559 base-fee *disposal* on chain 2800. **Ruled out: the base fee is not credited to the coinbase.** Measured on block 10,141,734+ era block 10,487,561 (1 transaction, `gasUsed` 22,474, `effectiveGasPrice` 1 Gwei == `baseFeePerGas`, so the priority tip was zero): the coinbase balance delta across that block was **exactly 0 wei**, whereas crediting the base fee would have moved 22,474,000,000,000 wei. Because the tip happened to be zero, this measurement cannot by itself separate "protocol-burned" from "routed elsewhere" -- both predict a zero coinbase delta. Completing the distinction needs a block containing a transaction with a nonzero priority tip and unpruned state; the chain is currently quiet (no logs in the last 5,000 blocks) and the one historical tipped transaction found, `0xb659...9ec1` at block 9,200,542 (tip 0.1 Gwei), sits below the public RPC's state-pruning horizon so its balances cannot be read. The documented Aere "burn" remains the separate validator-reward cut of Section 5.2 either way.]
|
||||
|
||||
### 5.2 The validator-reward-cut burn (application layer)
|
||||
|
||||
@ -532,7 +586,9 @@ Rules a reimplementer must honor:
|
||||
- No owner, no admin, no governance role; no `setBucket`, `setRecipient`, `setRouter`, or `pause`.
|
||||
- Bucket recipients (`BURN_VAULT`, `sAERE_VAULT`) set at deploy, immutable.
|
||||
- Bucket basis-point splits set at deploy, immutable, and the constructor reverts unless they sum to exactly 10000.
|
||||
- The three buckets are: (1) BURN (extra burn at the burn vault), (2) BUYBACK-AND-BURN (non-AERE fees swapped to AERE and burned), (3) STAKER-YIELD (transferred to the sAERE ERC-4626 vault, lifting the exchange rate).
|
||||
- The three buckets are: (1) BURN (extra burn at the burn vault), (2) BUYBACK-AND-BURN (non-AERE fees swapped to AERE and burned), (3) STAKER-YIELD (transferred to the sAERE ERC-4626 vault, lifting the exchange rate). Their basis-point split is set at deploy and immutable; the live split is `BURN_BPS = 1500` (15%), `BUYBACK_BPS = 4000` (40%), `STAKER_YIELD_BPS = 4500` (45%), and the constructor reverts unless `BURN_BPS + BUYBACK_BPS + STAKER_YIELD_BPS == 10000`. Because buckets (1) and (2) both destroy AERE, 55% of every amount routed through the sink is burned and 45% lifts the staking exchange rate. (Live split source: `sdk-js/src/addresses.ts` "Immutable 3-bucket router 15/40/45"; bucket semantics and the sum-to-10000 constructor guard: `aere-contracts/contracts/sink/AereSink.sol`.)
|
||||
- Combined effect (stated mechanically to avoid over-counting): the splitter burns 37.5% of the reward directly and routes 15% to the sink; 55% of that sink share is burned (15% + 40%) and 45% lifts the staking rate. The precise net burned fraction of a validator reward is therefore `0.375 + 0.15 x 0.55 = 0.45750` (about 45.75%), moving with the Foundation-settable splitter `sinkBps`/`burnBps` within their caps. Note: the `AereCoinbaseSplitterV2` source comment characterizes the net deflation more loosely as "~52.5%" by counting the entire 15% sink bucket as burn; the 45.75% figure here is the precise value once the sink's 45% staker-yield portion is excluded. Either way this is an application-layer flow, not a consensus base-fee burn.
|
||||
- When the input token is AERE, buckets (1) and (2) settle as a single transfer to the burn vault and bucket (3) transfers to the sAERE vault (with a best-effort `sync()` ping to start the anti-sandwich drip). When the input is a non-AERE token, each portion is swapped to AERE via a Uniswap-V2-style router along path `[token, AERE]` with an oracle-derived `amountOutMin` floor (sandwich-resistant); a failed swap leaves the portion as re-flushable dust rather than reverting the whole flush.
|
||||
- `AereSink` does not custody funds across calls; every `flush(token, amount)` fully dispatches into the three buckets. Residual dust (up to 2 wei per call from integer rounding) is re-flushable by a permissionless `sweepDust()`.
|
||||
|
||||
**Burn vault: `AereFeeBurnVault`.** No withdraw function and no admin escape hatch; value routed here is unrecoverable by construction.
|
||||
@ -579,11 +635,21 @@ Status vocabulary: **Supported** (matches Ethereum), **Partial** (present but ma
|
||||
6. **Validator-lifecycle requests (6110/7002/7251/7685) have no beacon consumer** (validator set is QBFT-managed).
|
||||
7. **EIP-2935 became functionally live at the AerePQC fork (block 9,189,161), not at Pectra**.
|
||||
|
||||
[VERIFY: that the AerePQC `futureEips` milestone (futureEipsTime = 1783820272, block 9,189,161) does NOT enable the EOF opcode set or EIP-3540/3670 container validation. Corroborating evidence (served genesis config, the Nethermind fork-id mirror, and the engineering spec) indicates EOF is off, but this milestone rides Besu's `futureEips` key, which in stock Besu is EOF's staging ground, so the fork build's spec definition should be inspected to close the loop.]
|
||||
**EOF is OFF, closed by measurement 2026-07-19.** This was previously an open [VERIFY] resting on indirect corroboration (served genesis, the Nethermind fork-id mirror, the engineering spec), which mattered because the milestone rides Besu's `futureEips` key -- EOF's usual staging ground in stock Besu. It has now been settled directly against the live chain at head, by executing candidate code through `eth_call` with a state override:
|
||||
|
||||
| Probe | Result at head |
|
||||
|---|---|
|
||||
| EOF v1 container magic `0xef0001...` installed as code | rejected: `Invalid opcode: 0xef` |
|
||||
| `0xef00` | rejected: `Invalid opcode: 0xef` |
|
||||
| `RJUMP` (`0xe0`) | rejected: `Invalid opcode: 0xe0` |
|
||||
| `CALLF` (`0xe3`) | rejected: `Invalid opcode: 0xe3` |
|
||||
| `EXTCALL` (`0xf8`) | rejected: `Invalid opcode: 0xf8` |
|
||||
|
||||
If EIP-3540 container validation were active the `0xef00` magic would be parsed as an EOF container rather than hitting an invalid-opcode error, and if the EOF opcode set were enabled `RJUMP`/`CALLF`/`EXTCALL` would be defined. All five probes fail closed. EOF is not activated, and the `0xEF` lead byte remains reserved by EIP-3541 legacy behavior.
|
||||
|
||||
[VERIFY: whether the validator-lifecycle request system contracts (6110/7002/7251) are actually populated on mainnet 2800 and whether mainnet block headers carry a non-empty requests hash. Regardless of the outcome, no beacon layer consumes these requests, so the "Partial" status and the no-effect-on-validator-set caveat hold.]
|
||||
|
||||
**Additions beyond Ethereum (recap).** Besides the deviations, Aere adds callable addresses not in the base Ethereum mainnet precompile set: the live PQC band `0x0AE1..0x0AE5` (Section 4), the non-live `0x0AE6..0x0AE8` (Section 4.8), and the RIP-7951 / RIP-7212 P-256 precompile at `0x100` (approximately 3,450 gas, active from the Osaka ruleset; shared with Ethereum's Osaka, so standards-aligned rather than Aere-proprietary). None of these make Aere consensus post-quantum.
|
||||
**Additions beyond Ethereum (recap).** Besides the deviations, Aere adds callable addresses not in the base Ethereum mainnet precompile set: the live PQC band `0x0AE1..0x0AE5` (Section 4), the non-live `0x0AE6..0x0AE8` (Section 4.8), and the EIP-7951 / RIP-7951 P-256 precompile at `0x100` (**6,900 gas**, measured live on chain 2800 on 2026-07-19, active from the Osaka ruleset; shared with Ethereum's Osaka, so standards-aligned rather than Aere-proprietary; **corrected from a previous "approximately 3,450 gas", which was the superseded RIP-7212 Layer-2 price**). None of these make Aere consensus post-quantum.
|
||||
|
||||
---
|
||||
|
||||
@ -595,8 +661,8 @@ This is the minimal, ordered checklist a stock Besu (or Nethermind) operator app
|
||||
|
||||
1. **Chain ID** `2800`. (Section 2.1.)
|
||||
2. **Genesis allocation**: the six balances totaling 2.8B AERE at the exact addresses in Section 2.1.
|
||||
3. **Genesis fields**: `gasLimit = 0x1fffffffffffff`, `difficulty = 0x1`, `timestamp = 0x69fbd960`, the genesis `coinbase = 0x0`, and the genesis QBFT `extraData` encoding the initial three-validator set (Section 3.2). These must be byte-exact to reproduce the block-0 hash.
|
||||
4. **QBFT config**: `blockperiodseconds = 1`, `epochlength = 30000`, `requesttimeoutseconds = 4`, plus the transition `{ "block": 2138451, "xblockperiodmilliseconds": 500 }`. (Sections 2.2, 2.4.)
|
||||
3. **Genesis fields**: `gasLimit = 0x1fffffffffffff`, `difficulty = 0x1`, `timestamp = 0x69fbd960`, `nonce = 0x0`, `mixHash = 0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365` (a 32-byte vanity value, ASCII "ctical byzantine fault tolerance"), the genesis `coinbase = 0x0`, and the genesis QBFT `extraData` encoding the initial three-validator set (Section 3.2). All of these must be byte-exact to reproduce the block-0 hash. (Source: `aere-genesis-current.json`.)
|
||||
4. **QBFT config**: `blockperiodseconds = 1`, `epochlength = 30000`, `requesttimeoutseconds = 4`, plus the transition `{ "block": 2137652, "xblockperiodmilliseconds": 500 }`. (Sections 2.2, 2.4.)
|
||||
5. **Fork schedule**: `londonBlock = 0`, `shanghaiTime = 0`, `cancunTime = pragueTime = 1780189051`, `osakaTime = 1780220351`, `futureEipsTime = 1783820272`. (Section 2.5.)
|
||||
6. **Enforce EIP-7825** (per-transaction cap 2^24), identical to Fusaka.
|
||||
|
||||
@ -624,20 +690,131 @@ A client built to this checklist validates the live chain, re-executes chain-280
|
||||
|
||||
---
|
||||
|
||||
## 8. Consolidated [VERIFY] register
|
||||
## 8. Formal state-transition delta (the delta as a set of function modifications)
|
||||
|
||||
Every flag left open for a human to confirm before external publication:
|
||||
Sections 2 through 6 specify the Aere delta descriptively. This section restates it as a precise, closed set of modifications to the Ethereum block-level state-transition function (STF) at the Pectra plus Fusaka ruleset, so a reimplementer can enumerate exactly what to change and confirm nothing else is touched. Let `Y` denote the reference Ethereum block-level transition (execution-specs / Yellow Paper) and `L` the block-acceptance (consensus) rule. Aere is `Y` and `L` with exactly the modifications M1 through M6 below and no others. Any behavior not named here is the referenced upstream, unchanged.
|
||||
|
||||
1. **[Section 2.3] Operative block gas limit** on the live head. Genesis declares `0x1fffffffffffff` (2^53 − 1), but Besu block-gas-limit dynamics may have moved the operative header `gasLimit`; confirm against `eth_getBlockByNumber("latest")`.
|
||||
Activation predicates over a block `B` with number `n(B)` and timestamp `t(B)`:
|
||||
|
||||
- `PECTRA(B) := t(B) >= 1780189051` (Cancun and Prague share this instant; observed first block 2,075,341, measured)
|
||||
- `OSAKA(B) := t(B) >= 1780220351` (observed first block 2,106,597, measured)
|
||||
- `AEREPQC(B) := t(B) >= 1783820272` (the `futureEips` milestone; observed first block 9,189,161)
|
||||
- `FLOOR(B) := n(B) >= 10141734` (client-flag gated, not config or time gated; see Section 9.2)
|
||||
|
||||
**M1. Precompile-set delta (gated by `AEREPQC`).** For every block with `AEREPQC(B)` true, extend the precompiled-contract set with the five entries at `0x0AE1..0x0AE5` specified in Sections 4.2 to 4.5. Each is a pure function from bytes to bytes with the fixed per-scheme gas of Section 4 and the fail-closed contract of Section 4.1 (a 32-byte zero word for `0x0AE1..0x0AE4`, empty output for `0x0AE5`, never a revert or fault). Addresses `0x0AE6..0x0AE8` are NOT added on mainnet (Section 4.8). The base Ethereum precompiles (`0x01..0x0A`, the EIP-2537 BLS12-381 band, and the RIP-7951 P-256 verifier at `0x100`) are inherited unchanged.
|
||||
|
||||
**M2. Opcode-set delta (gated by `AEREPQC`).** For every block with `AEREPQC(B)` true, add the EIP-7939 `CLZ` opcode (`0x1e`) with its reference semantics and gas. No other opcode differs from the ruleset: the EOF opcode set is NOT added and the `0xEF` lead byte stays reserved by EIP-3541. Note the non-standard schedule point: `CLZ` activates at `AEREPQC`, not at `OSAKA` (Section 4.7).
|
||||
|
||||
**M3. Block-start system-operation delta (gated by `AEREPQC` for population).** Aere inherits the Pectra block-start system operations as ruleset code, with two Aere-specific facts a reimplementer must reproduce. (a) The EIP-2935 history-storage contract at `0x0000F90827F1C53a10cb7A02335B175320002935` is not populated on mainnet until the write path ships at `AEREPQC`, so the parent-hash ring-buffer write (a system-address call executed before any user transaction, and a condition of block validity) is effectively live only from block 9,189,161 (Section 4.6). (b) The beacon-root buffer (EIP-4788) and the blob base fee (EIP-7516) resolve to 0 because Aere has no beacon layer and no blob market (Section 6). Aere changes the population height of (a) and the neutralized return values of (b); it does not change the system-operation machinery itself.
|
||||
|
||||
**M4. Header-validity delta (base-fee floor, gated by `FLOOR`).** Modify the EIP-1559 base-fee computation so its result is clamped once `FLOOR(B)` holds:
|
||||
|
||||
```
|
||||
baseFee(B) = max( baseFee_1559(parent), 1000000000 ) if n(B) >= 10141734
|
||||
baseFee(B) = baseFee_1559(parent) otherwise
|
||||
```
|
||||
|
||||
where `baseFee_1559` is the unmodified parent-derived base fee and `1000000000 wei = 1 Gwei`. The clamp is applied identically on the produce path and the validate path (both call `computeBaseFee`), so a floored block both produces and self-validates the floored value; the exact helper is in Section 5.1. Before block 10,141,734 the function is byte-identical to stock. This modification is deliberately NOT an EIP-2124 fork-id input and cannot halt QBFT (Section 9.2, Section 3.6).
|
||||
|
||||
**M5. Consensus-acceptance rule (`L`), fixed here for completeness.** Block sealing is QBFT with classical secp256k1 ECDSA committed seals (Section 3.3). A block is accepted only if it carries at least 5 distinct committed seals each recovering to a distinct member of the current 7-validator set (N=7, f=2, quorum 5). No post-quantum scheme participates in `L`. This is stated as a delta only against Ethereum's proof-of-stake fork-choice, which QBFT wholly replaces (upstream: Besu QBFT); it is not a modification of the execution `Y`.
|
||||
|
||||
**M6. Genesis-state delta (initial condition).** The genesis state is the six-account allocation of Section 2.1 (2,800,000,000 AERE total) under the genesis header fields of Section 7.1. This is the initial condition of the Aere STF, not a rule modification.
|
||||
|
||||
**Closure.** The account and storage trie, RLP encoding, receipt and log format, the gas schedule (except the additions in M1 and M2 and the floor in M4), transaction types 0 through 3, the EIP-155 chain-id binding (2800), the EIP-7825 per-transaction gas cap (`2^24`), and the JSON-RPC surface are all `Y` at Pectra plus Fusaka, unchanged. A reimplementer who applies M1 through M6 to a conformant Pectra-plus-Fusaka execution client and a QBFT engine obtains Aere Network on chain 2800; applying anything more, or less, does not.
|
||||
|
||||
---
|
||||
|
||||
## 9. Network-layer delta (fork identity and peering)
|
||||
|
||||
A client cannot sync chain 2800 without reproducing its network identity exactly. This section specifies the Aere-specific network parameters. The devp2p / RLPx transport, the `eth` wire protocol message set, discovery, and snap sync are inherited unchanged from the Besu 26.4.0 line and are not restated.
|
||||
|
||||
### 9.1 EIP-2124 / EIP-6122 fork identity
|
||||
|
||||
The fork id is the pair `(FORK_HASH, FORK_NEXT)`, where `FORK_HASH` is the CRC32 checksum accumulated over the genesis block hash followed by every already-passed fork-activation value in ascending order (block numbers for block-gated forks per EIP-2124, unix timestamps for time-gated forks per EIP-6122), and `FORK_NEXT` is the next not-yet-passed activation value (0 if none). The Aere delta lives entirely in the accumulation inputs:
|
||||
|
||||
| Order | Activation value | Kind | Fork |
|
||||
|---|---|---|---|
|
||||
| seed | genesis-v2 block hash | (seed) | genesis |
|
||||
| 1 | `1780189051` | timestamp | Cancun + Prague (a single point; identical timestamps collapse to one CRC update) |
|
||||
| 2 | `1780220351` | timestamp | Osaka |
|
||||
| 3 | `1783820272` | timestamp | AerePQC (`futureEips`) |
|
||||
|
||||
All pre-Cancun forks (Homestead through London at block 0, Shanghai at time 0) are active at genesis and fold into the genesis-hash seed; they contribute no separate CRC entry. A node at the current head advertises `FORK_NEXT = 0`. The network id equals the chain id, `2800`.
|
||||
|
||||
### 9.2 What is deliberately NOT a fork-id input
|
||||
|
||||
Two Aere transitions resemble forks but MUST NOT enter the fork-id accumulation, or a reimplementer will compute the wrong `FORK_HASH` and fail the peer handshake:
|
||||
|
||||
- **The block-period transition at block 2,137,652** (1000 ms to 500 ms, Sections 2.2 and 3.5) is a QBFT `transitions` config entry, not an EVM or consensus hard fork. It changes proposer timing only and is invisible to EIP-2124.
|
||||
- **The base-fee floor at block 10,141,734** (Section 5.1, M4) is gated by client system-property flags (`aere.basefee.floor.forkBlock`), not by the served chain configuration, and is not registered as a scheduled fork. It therefore does not enter the fork id. This is consistent with the observed behavior that a non-upgraded node syncs straight past the floor block with no rejection, because base-fee validation is absent from the QBFT header ruleset (Section 3.6): two clients with different floor flags share one fork id and peer normally.
|
||||
|
||||
### 9.3 Open network-layer items
|
||||
|
||||
- [VERIFY: the concrete `FORK_HASH` value(s) for chain 2800, which require the canonical genesis-v2 block hash as the CRC32 seed. The ordered activation inputs above (`1780189051`, `1780220351`, `1783820272`) are confirmed from the config; the genesis block hash itself is not reproduced in this document.]
|
||||
- [VERIFY: the maximum `eth` wire protocol version the live chain-2800 node negotiates (the Besu 26.4.0 line; `eth/68` is expected for this era). The message set and snap-sync behavior are stock and are not an Aere delta.]
|
||||
|
||||
---
|
||||
|
||||
## 10. Conformance and differential testing (acceptance procedure)
|
||||
|
||||
A reimplementation is Aere-conformant if and only if it passes all of the following against chain 2800. Each item is a differential oracle drawn from a committed artifact or a live-confirmed probe, not an assertion.
|
||||
|
||||
### 10.1 State-root re-execution
|
||||
|
||||
Re-execute canonical chain-2800 blocks from genesis and confirm byte-identical block hashes and post-state roots. A conformant client MUST reproduce block 0 exactly from the genesis fields (Section 7.1) and match every subsequent header hash. The reference second client (patched Nethermind 1.39.0) has re-validated the full chain to genesis and re-executed real blocks to identical hashes and state roots (Section 7.5), which is the existence proof that the delta in this document is complete and sufficient.
|
||||
|
||||
### 10.2 PQC precompile KAT suite (27 vectors)
|
||||
|
||||
Run the committed known-answer-test vectors and match every output byte and the gas charged. The suite: Falcon-512 and Falcon-1024 (NIST KAT), ML-DSA-44 (ACVP, 15/15), SLH-DSA-SHA2-128s (ACVP, 14/14), SHAKE256 (FIPS 202), plus the two testnet precompiles ML-KEM-768 (ACVP, 25/25, `aere-research/results/kat-results-mlkem.json`) and Falcon HashToPoint (12/12, `aere-research/results/kat-results-hashtopoint.json`). A conformant client returns byte-identical outputs and identical gas for the live band `0x0AE1..0x0AE5`.
|
||||
|
||||
### 10.3 SHAKE256 golden vectors (live-confirmed 2026-07-18)
|
||||
|
||||
`0x0AE5` with a 32-byte big-endian `outLen` word at offset 0 followed by the data to absorb at offset 32:
|
||||
|
||||
| `outLen` | data | output |
|
||||
|---|---|---|
|
||||
| 32 | `abc` | `0x483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739` |
|
||||
| 32 | (empty) | `0x46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f` |
|
||||
| 64 | `abc` | 64 bytes whose first 32 equal the `outLen = 32` row (proves true XOF squeezing) |
|
||||
|
||||
### 10.4 Fail-closed probes
|
||||
|
||||
Confirm that malformed input never faults and returns the defined not-verified value (Section 4.1), all live-confirmed 2026-07-18:
|
||||
|
||||
| Address | Probe input | Required output |
|
||||
|---|---|---|
|
||||
| `0x0AE1` | `0xdeadbeef` | `0x00..00` (32-byte zero word) |
|
||||
| `0x0AE3` | `0xdeadbeef` | `0x00..00` |
|
||||
| `0x0AE5` | draft 4-byte framing `0x00000020616263` | `0x` (empty; not parsed under the shipped encoding) |
|
||||
|
||||
A revert, or any nonzero word, on any of these is a conformance failure.
|
||||
|
||||
### 10.5 Fork-id handshake
|
||||
|
||||
Compute the EIP-2124 / EIP-6122 fork id from the ordered inputs of Section 9.1 and confirm the peer handshake with a live chain-2800 node succeeds (matching `FORK_HASH`, compatible `FORK_NEXT`). [VERIFY: the concrete `FORK_HASH`, per Section 9.3.]
|
||||
|
||||
### 10.6 Activation-boundary receipts (on-chain, real)
|
||||
|
||||
Cross-check the activation-boundary facts of Appendix A: the first Falcon-1024 attestation recorded through `0x0AE2` (tx `0xb659...9ec1`, status 1, gasUsed 692,206 at block 9,200,542) and the base-fee step at the floor fork block (7 wei at 10,141,733 becoming 1 Gwei at 10,141,734). A conformant client re-executing these blocks reproduces the same gasUsed and base-fee values.
|
||||
|
||||
---
|
||||
|
||||
## 11. Consolidated [VERIFY] register
|
||||
|
||||
Every flag still open, published as a **NOT MEASURED** disclosure. None of these blocks publication; each is closed only by a measurement, never by deletion (`VERIFY-POLICY.md`).
|
||||
|
||||
1. ~~**[Section 2.3] Operative block gas limit** on the live head~~ **CLOSED by measurement 2026-08-01.** Header `gasLimit` at head block 11,810,041 is `0x1fffffffffffff` = 9,007,199,254,740,991, identical to genesis. Besu's dynamics have not moved it. **Opened in its place:** the EIP-7825 per-transaction cap of 2^24 is **NOT MEASURED**; an `eth_call` above that cap succeeded, `eth_estimateGas` does not discriminate, and the only conclusive probe is a transaction above the cap, which we do not send.
|
||||
2. **[Section 2.4] Inline fork/transition fields in the running config.** `aere-genesis-current.json` in the repo lacks the block-period transition and the Cancun/Prague/Osaka/futureEips time fields; confirm the authoritative running config carries them.
|
||||
3. **[Section 2.5] Pectra and Osaka block heights** (2,075,363 / 2,106,606), which are timestamp-gated, against the live head history.
|
||||
4. **[Section 3.2] The seven live validator addresses** at the current head (only the three genesis validators are recoverable from the genesis `extraData`).
|
||||
3. ~~**[Section 2.5] Pectra and Osaka block heights**~~ **CLOSED by measurement 2026-07-19.** Binary-searched on the live chain: Pectra **2,075,341**, Osaka **2,106,597**. The previously published 2,075,363 / 2,106,606 were wrong and have been corrected throughout this document (Section 2.5, Appendix A).
|
||||
4. ~~**[Section 3.2] The seven live validator addresses** at the current head~~ **CLOSED as a fact 2026-08-01.** `qbft_getValidatorsByBlockNumber("latest")` returns **seven** addresses on any public AERE RPC endpoint, so the set is readable by anyone and needs no privileged confirmation: N=7, f=2, commit quorum 5 of 7, mean block interval measured 0.5175 s over the 2,000 blocks to head 11,810,041. It remains true that only the three genesis validators are recoverable from the genesis `extraData`, which is why the head must be read rather than derived.
|
||||
5. **[Section 4.2] The low-level `sm` byte order** the native `0x0AE1`/`0x0AE2` parser expects, against the gold-binary precompile source or the conformance vectors (this spec uses the order `AerePQCAttestation._buildInput` builds).
|
||||
6. **[Section 4.5] Any `outLen` upper bound** enforced by the live `0x0AE5` SHAKE256 precompile.
|
||||
7. **[Section 4.7] EIP-7939 CLZ activation height** (AerePQC milestone block 9,189,161 versus Osaka block 2,106,606).
|
||||
7. **[Section 4.7] EIP-7939 CLZ activation height** (AerePQC milestone block 9,189,161 versus Osaka block 2,106,597). The opcode itself is confirmed live at head by measurement; only the boundary height remains unprobed (state pruned).
|
||||
8. **[Section 5.1] EIP-1559 base-fee disposal** on chain 2800 (protocol-burned versus credited), stated precisely and kept distinct from the Section 5.2 burn.
|
||||
9. **[Section 6] EOF off under `futureEips`.** Confirm the AerePQC milestone does not enable the EOF opcode set or EIP-3540/3670 container validation, since it rides Besu's `futureEips` key (EOF's usual staging ground).
|
||||
10. **[Section 6] Validator-lifecycle request contracts (6110/7002/7251/7685)** populated on mainnet and whether headers carry a requests hash (status and no-beacon-consumer caveat hold regardless).
|
||||
11. **[Section 9.1] The concrete EIP-2124 / EIP-6122 `FORK_HASH`** for chain 2800, which requires the canonical genesis-v2 block hash as the CRC32 seed. The ordered activation inputs (`1780189051` / `1780220351` / `1783820272`) are confirmed; the genesis block hash seed is not reproduced in this document.
|
||||
12. **[Section 9.3] The maximum negotiated `eth` wire protocol version** on the live node (Besu 26.4.0 line; `eth/68` expected). The transport and message set are stock, not an Aere delta.
|
||||
|
||||
---
|
||||
|
||||
@ -646,9 +823,9 @@ Every flag left open for a human to confirm before external publication:
|
||||
| Event | Block | Time gate | What changed |
|
||||
|---|---|---|---|
|
||||
| Genesis-v2 | 0 | `timestamp 0x69fbd960` | Current chain genesis, 2.8B supply, 3 genesis validators, London + Shanghai from block 0. |
|
||||
| Pectra (Cancun + Prague) | 2,075,363 | `cancunTime = pragueTime = 1780189051` | EVM at Pectra parity (EIP-7702, EIP-2537, transient storage, etc.). EIP-2935 listed but not yet populated. |
|
||||
| Osaka (Fusaka) | 2,106,606 | `osakaTime = 1780220351` | EIP-7825 per-tx cap, RIP-7951 P-256 at `0x100`. |
|
||||
| Block-period transition | 2,138,451 | QBFT `xblockperiodmilliseconds` | 1000 ms to 500 ms block period. |
|
||||
| Pectra (Cancun + Prague) | **2,075,341** *(measured)* | `cancunTime = pragueTime = 1780189051` | EVM at Pectra parity (EIP-7702, EIP-2537, transient storage, etc.). EIP-2935 listed but not yet populated. |
|
||||
| Osaka (Fusaka) | **2,106,597** *(measured)* | `osakaTime = 1780220351` | EIP-7825 per-tx cap, EIP-7951 (formerly RIP-7212) P-256 at `0x100`. |
|
||||
| Block-period transition | 2,137,652 | QBFT `xblockperiodmilliseconds` | 1000 ms to 500 ms block period. |
|
||||
| EIP-2935 history contract deploy | 9,182,379 | Nick's-method keyless tx | History contract runtime populated (pre-write-path). |
|
||||
| AerePQC hard fork | 9,189,161 | `futureEipsTime = 1783820272` | PQC precompiles `0x0AE1..0x0AE5`, EIP-2935 write path, EIP-7939 CLZ. |
|
||||
| Falcon-1024 on-chain attestation | 9,200,542 | (application) | First real Falcon-1024 verify recorded through `0x0AE2` (tx `0xb659...9ec1`, status 1, gasUsed 692,206). |
|
||||
|
||||
@ -65,6 +65,16 @@ Note on the 1 pending (file 6): it is the deliberately-skipped "without EIP-2537
|
||||
|
||||
Grepped across the new AERE-*.md docs in aerenew/docs/. Findings against each invariant:
|
||||
|
||||
**SCOPE LIMIT, and it matters. This check covered DOCUMENTATION ONLY.** It did not cover Solidity
|
||||
sources, tests or comments in the `aere-contracts` repository. Read every "No contradiction" below
|
||||
as "no contradiction among the documents grepped", not as a statement about the published set as a
|
||||
whole. A separate review on 2026-07-20 checked the contract sources against these same invariants
|
||||
and **did** find contradictions there, including a burn described as a cut of transaction fees in
|
||||
`AereFeeBurnVault.sol` and a testnet-only precompile described as working on mainnet in
|
||||
`AereMLKEM768.sol`. Those contract defects were corrected on 2026-07-20; they were real, and this
|
||||
report's original wording read as though it had ruled them out when it had never looked at those
|
||||
files. The scope was always documentation; saying so explicitly is the correction.
|
||||
|
||||
1. Burn = 37.5% of the validator reward, cap 50%, NOT a base-fee burn.
|
||||
CONSISTENT. Every doc that mentions the burn describes it as a cut of the validator coinbase block reward, `burnBps` default 3750 (37.5%), hard-capped at `MAX_BURN_BPS = 5000` (50%), applied above consensus by `AereCoinbaseSplitterV2`, explicitly not an EIP-1559 protocol base-fee burn. See AERE-ENGINEERING-SECURITY-SPEC.md:205-217, AERE-PROTOCOL-SPECIFICATION.md:497-540, AERE-EIP-COMPATIBILITY-MATRIX.md:109, AERE-AIP-PROCESS-AND-INDEX.md:110/137, AERE-CERTORA-FORMAL-VERIFICATION.md:170/187-188. No contradiction. (Several docs carry an honest `[VERIFY]` marker asking that EIP-1559 base-fee DISPOSAL be stated precisely; that is an open verification item, and it is careful to keep disposal distinct from the validator-reward-cut burn, so it does not contradict the invariant.)
|
||||
|
||||
@ -80,7 +90,7 @@ Grepped across the new AERE-*.md docs in aerenew/docs/. Findings against each in
|
||||
5. 273k TPS labeled a ceiling, never a live/measured rate.
|
||||
CONSISTENT. AERE-BENCHMARK-REPORT.md:42/49/55/61/81/372 repeatedly calls it an "architectural ceiling / design maximum / theoretical maximum," explicitly states "There is no testnet measurement that validates 273,000 TPS for L1," and separates it from the Block-STM harness figure (~247k-270k at gas=80, called a coincidence not a validation). AERE-REPRODUCIBLE-BUILDS.md:244 states "273,000 TPS is a synthetic design ceiling, not a measured mainnet number." No doc presents it as a live or measured rate. No contradiction.
|
||||
|
||||
CONSISTENCY VERDICT: No contradictions found on any of the five invariants. (The docs contain a number of honest `[VERIFY]` / `[MEASURE]` markers flagging open verification items, e.g. EIP-1559 base-fee disposal, EIP-7939 CLZ activation height, EOF-off confirmation. These are self-disclosed open items, not internal contradictions.)
|
||||
CONSISTENCY VERDICT: No contradictions found on any of the five invariants **among the documentation files grepped**. This verdict does not extend to contract sources, which were outside this check's scope and which were separately found on 2026-07-20 to contradict invariants 1 and 2 (now corrected). See the scope limit at the top of this part. (The docs contain a number of honest `[VERIFY]` / `[MEASURE]` markers flagging open verification items, e.g. EIP-1559 base-fee disposal, EIP-7939 CLZ activation height, EOF-off confirmation. These are self-disclosed open items, not internal contradictions.)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ account, plus a design doc covering both that and network key rotation (gated).
|
||||
|
||||
## Deliverables
|
||||
|
||||
1. Contract: `aerenew/contracts/contracts/pqc/AereAccountMigrator.sol` (solc 0.8.23,
|
||||
1. Contract: `aere-contracts/contracts/pqc/AereAccountMigrator.sol` (solc 0.8.23,
|
||||
OZ SafeERC20 + ReentrancyGuard). New file; deployed contracts untouched.
|
||||
- `migrate(destination, tokens[], amounts[], moveNative)`: atomic sweep of ERC-20
|
||||
balances + optional native AERE from caller (old EOA) to a destination PQC
|
||||
@ -26,7 +26,7 @@ account, plus a design doc covering both that and network key rotation (gated).
|
||||
transfer reverts the WHOLE tx (SafeERC20). Emits Migrated(old, new, tokens,
|
||||
amounts, nativeAmount).
|
||||
|
||||
2. Test: `aerenew/contracts/test/account-migrator.test.js`. RAN it:
|
||||
2. Test: `aere-contracts/test/account-migrator.test.js`. RAN it:
|
||||
`npx hardhat test test/account-migrator.test.js` -> **9 passing** (2026-07-19).
|
||||
Destination in strong-path tests is a REAL AerePQCAccount deployed via the REAL
|
||||
AerePQCAccountFactory (Falcon verify mocked; CREATE2 + asset moves fully real).
|
||||
|
||||
@ -82,7 +82,7 @@ later via `createAccount`, which is permissionless and idempotent.
|
||||
|
||||
### A.3 The contract: `AereAccountMigrator`
|
||||
|
||||
File: `aerenew/contracts/contracts/pqc/AereAccountMigrator.sol` (solc 0.8.23,
|
||||
File: `aere-contracts/contracts/pqc/AereAccountMigrator.sol` (solc 0.8.23,
|
||||
OpenZeppelin SafeERC20 + ReentrancyGuard).
|
||||
|
||||
It is a pure conduit that atomically moves a caller-specified set of ERC-20
|
||||
@ -180,7 +180,7 @@ on-chain executor for step 4.
|
||||
|
||||
### A.5 Test result (real)
|
||||
|
||||
Suite: `aerenew/contracts/test/account-migrator.test.js`. Run from
|
||||
Suite: `aere-contracts/test/account-migrator.test.js`. Run from
|
||||
`aerenew/contracts` with `npx hardhat test test/account-migrator.test.js`.
|
||||
|
||||
Result on 2026-07-19: 9 passing.
|
||||
@ -294,12 +294,226 @@ layer, and it is largely gated, not a switch to flip tonight.
|
||||
|
||||
---
|
||||
|
||||
## Part C. Authority residue: why moving the assets is not finishing the job
|
||||
|
||||
Added 2026-07-19. Part A moves an account's ASSETS. This part addresses what Part A
|
||||
leaves behind, which is the more dangerous half.
|
||||
|
||||
### C.1 The gap
|
||||
|
||||
After a perfect Part A migration, the old classical EOA is empty. It is not
|
||||
harmless. It still carries:
|
||||
|
||||
1. Every ERC-20 allowance it ever granted. `approve` state lives on the token
|
||||
contract keyed by owner, and sweeping a balance does not touch it. Any token
|
||||
that later arrives at the old EOA is immediately drainable by every spender
|
||||
still holding a non-zero allowance.
|
||||
2. Any role, ownership, or membership granted to it on other contracts. Sweeping
|
||||
an ERC-20 balance does not transfer an `onlyOwner` role.
|
||||
3. Its status as a valid payment destination. Airdrops, refunds, vesting unlocks,
|
||||
exchange withdrawals, and counterparties working from an address book keep
|
||||
sending to it. The account keeps re-accruing value under a Shor-breakable key.
|
||||
4. Its status as a valid signer for any EIP-712 or EIP-1271 flow that checks only
|
||||
ECDSA.
|
||||
|
||||
So an account that has "migrated" can be empty today and hold a meaningful balance
|
||||
again in six months, under exactly the key the migration was meant to retire. The
|
||||
adversary in the model does not need to act now. Harvest-now-decrypt-later means
|
||||
they break the key years later and then collect whatever has pooled there since.
|
||||
|
||||
### C.2 Which accounts are actually exposed, precisely
|
||||
|
||||
The exposure that matters is exposure of the PUBLIC KEY, not of the address. An
|
||||
Aere address is `keccak(pubkey)[12:]`, a hash, and a hash is not Shor-breakable.
|
||||
The public key itself is what Shor's algorithm needs.
|
||||
|
||||
| Account state | Public key on chain? | Exposed to a future quantum adversary? |
|
||||
|---|---|---|
|
||||
| Never sent a transaction (receive-only) | No. Only the address hash is public | NOT exposed today. The preimage has never been published |
|
||||
| Has sent at least one transaction | Yes. The pubkey is recoverable from the signature | EXPOSED. The material an adversary needs is already public and already archived |
|
||||
| Has signed any off-chain message that was published (EIP-191, EIP-712, a permit) | Yes, same recovery applies | EXPOSED, even with zero on-chain transactions |
|
||||
| Deployed contract / smart account | No secp256k1 key of its own | Not exposed as a key. Exposure is whatever its OWNER key is |
|
||||
|
||||
The practical reading: any address that has ever spent anything is already exposed,
|
||||
and that is the overwhelming majority of active accounts. Nothing can un-expose
|
||||
them. The only remaining lever is to stop keeping value there, and to stop the old
|
||||
key from carrying authority. That is what Part A and this part do respectively.
|
||||
|
||||
A receive-only account is genuinely in a better position, and it has a strictly
|
||||
better migration: move the funds in a single transaction to a post-quantum account.
|
||||
That first spend does expose the key, but it exposes it at the moment the value is
|
||||
already leaving, which is the one moment exposure costs nothing.
|
||||
|
||||
This document does NOT claim a count or percentage of exposed accounts on chain
|
||||
2800. That would require indexing the full chain history and it was not measured.
|
||||
|
||||
### C.3 What is a contract, and what deliberately is not
|
||||
|
||||
Two things are needed. Only one of them should be a contract, and saying so plainly
|
||||
is the point.
|
||||
|
||||
Allowance revocation is NOT a new contract. `approve` can only be called by the
|
||||
token owner, so no third-party contract can revoke on an EOA's behalf. The
|
||||
revocation has to be executed BY the account. Aere Network already ships the tool:
|
||||
`AereDelegate7702V2.executeBatch` in `aerenew/contracts/contracts/delegation`
|
||||
batches the `approve(spender, 0)` calls into one EIP-7702 transaction from the EOA
|
||||
itself. Writing a second contract for this would add a security surface and buy
|
||||
nothing, so none was written. Enumerating the live spender set per token is an
|
||||
indexer job and belongs in the migration toolkit, not in Solidity.
|
||||
|
||||
Retirement declaration IS a contract, because it needs to be permanent, public, and
|
||||
machine-readable, and no existing primitive provides that.
|
||||
|
||||
#### C.3.1 Evidence that no account-level retirement registry already existed
|
||||
|
||||
"Nothing existing provides it" is the kind of claim that has to be auditable rather
|
||||
than asserted, so here is the full search and the full result. Run from
|
||||
`aerenew/contracts/contracts`:
|
||||
|
||||
```
|
||||
grep -rnE "[Rr]etire|RETIRE" --include=*.sol .
|
||||
```
|
||||
|
||||
Result on 2026-07-20: **68 matching lines across 9 files**. 46 of those lines are in
|
||||
the new `pqc/AereAccountRetirement.sol` itself, leaving **22 pre-existing lines
|
||||
across 8 files**. An earlier build note cited only four hits, which was a filtered
|
||||
subset presented as the whole result. That was wrong and this section replaces it.
|
||||
The conclusion is unchanged, but it is now checkable. Every pre-existing hit:
|
||||
|
||||
| File | Lines | What it actually is | Account-level retirement registry? |
|
||||
|---|---|---|---|
|
||||
| `AereCoinbaseSplitterV2.sol` | 1 | Prose comment saying the V1 contract was retired | No. English usage in a comment, no code |
|
||||
| `aere-contracts/contracts/faucet/AereFaucetV2.sol` | 1 | Comment: the faucet can be "retired" by setting `dripAmount` to 0 | No. Describes a parameter, not a registry |
|
||||
| `aere-contracts/contracts/modular/AerePQCEncryptedIntent.sol` | 5 | `retireEncapKey()`, `EncapKeyRetired`, an `active` flag | No. Retires one advertised ML-KEM encapsulation key so no NEW intent targets it. Scoped to a key, not to the account, and the account stays fully active |
|
||||
| `aere-contracts/contracts/modular/AerePQCKeyExchange.sol` | 7 | `retireKemKey()`, `KemKeyRetired`, `active` flag, "register / rotate / retire" | No. Same shape: retires one advertised ML-KEM key for handshake targeting. The account keeps transacting |
|
||||
| `aere-contracts/contracts/mpc/AereThresholdRegistry.sol` | 3 | `Status.RETIRED` enum member, `CommitteeRetired` event, one comment | No, and weaker than it looks. The subject is a threshold COMMITTEE, not an EOA. Also, `Status.RETIRED` is never assigned and `CommitteeRetired` is never emitted anywhere in the file: the only status writes are `ACTIVE` (line 174, 358) and `PAUSED` (line 350). The state is declared and unreachable |
|
||||
| `aere-contracts/contracts/pqc/AereHybridAuthorizer.sol` | 1 | Comment: the Foundation "retires a scheme" on the registry | No. Subject is a signature SCHEME, protocol-wide |
|
||||
| `aere-contracts/contracts/pqc/AerePQCOrderAuthorizer.sol` | 1 | Same scheme-retirement comment | No. Same, subject is a scheme |
|
||||
| `aere-contracts/contracts/pqc/AerePQCKeyRegistry.sol` | 3 | Rotation "retires the old one", plus append-only key lists that include retired keys | No. Subject is a PQC KEY belonging to an identity. Retiring a key is the opposite direction of travel: it presumes the identity continues, under a new key. There is no way to mark the classical account itself as retired, and no successor pointer |
|
||||
|
||||
The pattern across all 22 is the same and it is the reason the gap was real. Every
|
||||
pre-existing use retires a KEY, a SCHEME or a COMMITTEE, always as a rotation step
|
||||
that presumes the subject carries on under new material. None of them takes an EOA
|
||||
as the subject, none of them is a one-way latch, and none of them publishes a
|
||||
successor account. `AerePQCKeyRegistry` is the closest and still does not fit: it
|
||||
would let an identity mark a Falcon key stale, never the secp256k1 account.
|
||||
|
||||
Search limits, stated: this is a text search over `*.sol` under
|
||||
`aerenew/contracts/contracts` only. It would not catch a registry that implements
|
||||
the same semantics without ever using the word "retire" (for example one built
|
||||
around "deprecate", "sunset" or "revoke" on an account subject), and it does not
|
||||
cover non-Solidity sources or deployed-but-unsourced contracts. Those are the
|
||||
conditions under which the conclusion could still be wrong.
|
||||
|
||||
### C.4 `AereAccountRetirement`, the one-way latch
|
||||
|
||||
File: `aerenew/contracts/contracts/pqc/AereAccountRetirement.sol` (solc 0.8.23, no
|
||||
dependencies, no admin, no payable function, holds nothing).
|
||||
|
||||
An account calls `retire(successor)` and irreversibly declares its classical key
|
||||
retired, optionally naming the post-quantum account that replaces it.
|
||||
`retireToPqcAccount(factory, falconPubKey, salt, expectedSuccessor)` derives the
|
||||
successor from a Falcon-512 key through an `AerePQCAccountFactory` rather than
|
||||
taking a literal address. Passing the zero successor is legitimate and supported,
|
||||
for an owner who does not want to publicly link the old address to the new one.
|
||||
|
||||
**What deriving the successor does and does not guarantee.** Because the pointer can
|
||||
never be corrected, it is worth being exact about which mistakes this removes.
|
||||
|
||||
It removes the transcription class: a mistyped, truncated, wrong-checksum or
|
||||
clipboard-swapped successor address. The caller never supplies the successor at all,
|
||||
so there is nothing to mistype; the address is CREATE2 math over the Falcon public
|
||||
key the caller holds. That is a real and worthwhile guarantee, and it is why the
|
||||
entrypoint exists.
|
||||
|
||||
It does NOT remove the wrong-successor class in general. `factory` is a
|
||||
caller-supplied address and the contract does not validate it. There is no
|
||||
allowlist, no code check and no interface assertion, so a wrong or hostile factory
|
||||
returns a wrong successor and that successor is latched permanently. A hostile
|
||||
factory can return an address it controls. What the design does is move the trust
|
||||
from "did I type twenty bytes correctly" to "do I trust this factory", which is a
|
||||
better question to have to answer, not the absence of one.
|
||||
|
||||
The caller must therefore supply a factory they trust. Verify the factory address
|
||||
out of band against the published deployment record before calling, and prefer
|
||||
passing a non-zero `expectedSuccessor` so the derived address must additionally
|
||||
match one reviewed off chain. Those two checks together, not the function alone, are
|
||||
what make the permanent statement safe.
|
||||
|
||||
An earlier revision of this section and of the contract NatSpec said this made the
|
||||
wrong-successor mistake "impossible". That was an overstatement of a narrower true
|
||||
guarantee and has been corrected here and in
|
||||
`aerenew/contracts/contracts/pqc/AereAccountRetirement.sol`.
|
||||
|
||||
Why the latch is one-way. The adversary is someone who breaks the secp256k1 key
|
||||
LATER and can then sign anything the original owner could. If retirement were
|
||||
revocable that adversary would un-retire the account and continue. If the successor
|
||||
were mutable they would repoint it at themselves and harvest anyone honoring the
|
||||
pointer. Immutability is what lets the declaration survive the compromise it exists
|
||||
to outlive. The honest owner acts once, while the key is still safe, and the
|
||||
statement outlives the key. This is the property the test suite targets directly.
|
||||
|
||||
Integrators read `isRetired(account)`, `successorOf(account)`, or call the
|
||||
reverting guard `requireActive(account)` at the top of a sensitive function.
|
||||
|
||||
### C.5 What this honestly cannot do
|
||||
|
||||
Stated plainly, because a registry is easy to oversell:
|
||||
|
||||
- It cannot stop native AERE or a non-integrating ERC-20 from being sent to a
|
||||
retired address. Base-protocol transfers consult no registry, and making them do
|
||||
so would be a consensus change. Aere is not making one. Consensus on chain 2800
|
||||
is and remains classical secp256k1 ECDSA QBFT.
|
||||
- It cannot revoke an allowance. See C.3.
|
||||
- It cannot help an account whose key is ALREADY broken. An adversary holding the
|
||||
key can retire it too, or simply move the assets. This works only in the window
|
||||
where the honest owner acts first, which is the entire argument for migrating
|
||||
early rather than waiting for a quantum event.
|
||||
- It binds only the contracts, wallets, indexers and counterparties that CHOOSE to
|
||||
read it. It is an opt-in enforcement surface and an advisory signal, not a
|
||||
protocol rule.
|
||||
|
||||
Its value is being a permanent, checkable, machine-readable statement of intent
|
||||
that an attacker who later owns the key cannot retract.
|
||||
|
||||
### C.6 Test result (real)
|
||||
|
||||
Suite: `aerenew/contracts/test/account-retirement.test.js`. Run from
|
||||
`aerenew/contracts`:
|
||||
|
||||
`npx hardhat test test/account-migrator.test.js test/account-retirement.test.js`
|
||||
|
||||
Result on 2026-07-19: 20 passing (9 pre-existing migrator tests, 11 new retirement
|
||||
tests). Covered by the new tests: retirement with and without a published
|
||||
successor; Falcon-derived successor through the real factory; mismatch guard; the
|
||||
latch holds against an attacker who has the key (cannot un-retire, cannot repoint,
|
||||
via either entrypoint); retirement is strictly self-scoped so no third party or
|
||||
admin can retire another account; no admin surface and no payable function; the
|
||||
self-referential successor is rejected; `requireActive` guards correctly; a
|
||||
never-retired account reads as a clean zero record.
|
||||
|
||||
The "no payable function" assertion was checked against a positive control: the
|
||||
same ABI inspection reports 2 payable functions on `AereAccountMigrator` and 0 on
|
||||
`AereAccountRetirement`, so the assertion is not passing vacuously.
|
||||
|
||||
Deployment status: NOT DEPLOYED. This contract exists in the repository and passes
|
||||
its suite. It is not on mainnet 2800 and no transaction was sent. Deploying it is
|
||||
founder-gated.
|
||||
|
||||
---
|
||||
|
||||
## Files
|
||||
|
||||
- `aerenew/contracts/contracts/pqc/AereAccountMigrator.sol` (contract)
|
||||
- `aerenew/contracts/test/account-migrator.test.js` (Hardhat suite, 9 passing)
|
||||
- `aere-contracts/contracts/pqc/AereAccountMigrator.sol` (contract)
|
||||
- `aere-contracts/test/account-migrator.test.js` (Hardhat suite, 9 passing)
|
||||
- `aerenew/contracts/contracts/pqc/AereAccountRetirement.sol` (contract, Part C,
|
||||
NOT deployed)
|
||||
- `aerenew/contracts/test/account-retirement.test.js` (Hardhat suite, 11 passing)
|
||||
- `aere-contracts/contracts/delegation/AereDelegate7702V2.sol` (`executeBatch`,
|
||||
the existing tool for batch allowance revocation; no new contract was written
|
||||
for revocation)
|
||||
- `aerenew/pqc-migration-toolkit/` (scanner + derivation + cost simulator)
|
||||
- `aerenew/contracts/contracts/pqc/AerePQCAccount.sol`,
|
||||
- `aere-contracts/contracts/pqc/AerePQCAccount.sol`,
|
||||
`AerePQCAccountFactory.sol`, `AereHybridAuth.sol` (destinations)
|
||||
- `aerenew/docs/AERE-POST-QUANTUM-GOVERNANCE.md` (Timelock role grant to a PQC
|
||||
threshold account, the governance path for operator authority)
|
||||
|
||||
@ -199,8 +199,8 @@ build hashes; they are not yet wired into the manifest the verify script fetches
|
||||
|
||||
### 2.6 The on-chain binary-commitment registry
|
||||
|
||||
**`aerenew/contracts/contracts/validators/AereValidatorManifest.sol`** [REAL] (with
|
||||
`aerenew/contracts/test/validator-manifest.test.js`). A no-admin Solidity contract where each
|
||||
**`aere-contracts/contracts/validators/AereValidatorManifest.sol`** [REAL] (with
|
||||
`aere-contracts/test/validator-manifest.test.js`). A no-admin Solidity contract where each
|
||||
validator's own QBFT signer key declares the SHA256 `binaryDigest` of the Besu image it runs plus a
|
||||
`manifestUri` (typically the published `.well-known/besu-image-digest`), an operator label, and a
|
||||
region. Commitments are keyed by signer with a monotonic serial and full event history; there is no
|
||||
@ -296,7 +296,7 @@ result matches what is deployed on chain 2800 via `eth_getCode`.
|
||||
- Global compiler `solc 0.8.23`, `optimizer.enabled = true`, `optimizer.runs = 1` (runs=1 chosen for
|
||||
contract-size headroom, documented in-file), `viaIR = true`. Default EVM version is shanghai for
|
||||
0.8.23.
|
||||
- One per-file override: `contracts/AereCancunCanary.sol` compiles with `solc 0.8.24`,
|
||||
- One per-file override: `aere-contracts/contracts/AereCancunCanary.sol` compiles with `solc 0.8.24`,
|
||||
`optimizer.runs = 200`, `evmVersion = "cancun"`. Every other contract stays on 0.8.23 so its
|
||||
bytecode is untouched by the canary.
|
||||
|
||||
@ -472,7 +472,7 @@ bash setup-fork.sh # clones besu@d2032017, overlays fork EVM, adds 0x0AE6/0x
|
||||
bash build-dist.sh # ./gradlew :besu:installDist -x test (one full build)
|
||||
```
|
||||
|
||||
[MEASURE: heavy Linux-only build, targets `$BESU_HOME` on a scratch box. Not run here, and never on
|
||||
[MEASURE: heavy Linux-only build, targets a Besu build tree on a scratch box. Not run here, and never on
|
||||
the live infra box, which runs production services. Publish the resulting `bin/besu` and jar SHA256
|
||||
values and compare against `combined-fork-binary/BUILD_INFO.txt`.]
|
||||
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
|
||||
Source review: `aerenew/docs/AERE-SECURITY-REVIEW-NEW-CONTRACTS.md`
|
||||
Repo: `aerenew/contracts` (solc 0.8.23, OpenZeppelin v4.9.x). All contracts founder-gated, not deployed.
|
||||
Guard pattern for L1 copied from `contracts/pqfinality/AereFinalityCertificateVerifier.sol` (`gateway.code.length == 0` revert).
|
||||
Guard pattern for L1 copied from `aere-contracts/contracts/pqfinality/AereFinalityCertificateVerifier.sol` (`gateway.code.length == 0` revert).
|
||||
|
||||
## Per-finding status
|
||||
|
||||
### M1 (MEDIUM) FIXED, with proof
|
||||
File: `contracts/erc8004/AereReputationRegistry8004.sol`
|
||||
File: `aere-contracts/contracts/erc8004/AereReputationRegistry8004.sol`
|
||||
- Made the adapter `Ownable` (OZ v4, `@openzeppelin/contracts/access/Ownable.sol`, matching the repo).
|
||||
- Added `mapping(address => bool) public isAuthorizedFeedbackAuthor`, owner functions `addFeedbackAuthor` / `removeFeedbackAuthor` (with `FeedbackAuthorSet` event and a zero-address guard on add), and a new error `NotAuthorizedFeedbackAuthor(address)`.
|
||||
- Gated `giveFeedback`: first line now reverts `NotAuthorizedFeedbackAuthor` unless `isAuthorizedFeedbackAuthor[msg.sender]`. The rest of the flow (agent-registered, delta clamp, adapter-is-attestor) is unchanged.
|
||||
@ -15,35 +15,35 @@ File: `contracts/erc8004/AereReputationRegistry8004.sol`
|
||||
|
||||
### L1 (LOW) FIXED (x3), with proof
|
||||
Added the sibling's codeless-gateway guard to each verify path. New error `VerifierHasNoCode()` in each.
|
||||
- `contracts/mpc/AerePQAggregateVerifier.sol` constructor: reverts if `gateway.code.length == 0` (after the existing `ZeroGateway` check).
|
||||
- `contracts/depin/AereComputeMarketV3.sol` constructor: reverts if `zkVerifier.code.length == 0` (after the existing `ZeroAddress` check).
|
||||
- `contracts/compliance/AereBitstringStatusList.sol` constructor: reverts if `nonRevocationVerifier_ != address(0) && nonRevocationVerifier_.code.length == 0`. The zero address is still allowed (keeps the zk non-revocation path fail-closed OFF until configured), which preserves existing behavior. Verifier is immutable, so the constructor is the correct place.
|
||||
- `aere-contracts/contracts/mpc/AerePQAggregateVerifier.sol` constructor: reverts if `gateway.code.length == 0` (after the existing `ZeroGateway` check).
|
||||
- `aere-contracts/contracts/depin/AereComputeMarketV3.sol` constructor: reverts if `zkVerifier.code.length == 0` (after the existing `ZeroAddress` check).
|
||||
- `aere-contracts/contracts/compliance/AereBitstringStatusList.sol` constructor: reverts if `nonRevocationVerifier_ != address(0) && nonRevocationVerifier_.code.length == 0`. The zero address is still allowed (keeps the zk non-revocation path fail-closed OFF until configured), which preserves existing behavior. Verifier is immutable, so the constructor is the correct place.
|
||||
|
||||
### L2 (LOW) FIXED, with proof
|
||||
File: `contracts/agentic/AereVectorStore.sol`
|
||||
File: `aere-contracts/contracts/agentic/AereVectorStore.sol`
|
||||
- Bound each paid-query receipt to an intended provider. Added `address provider` to the `QueryReceipt` struct.
|
||||
- `paidQuery` now takes `address provider` (validated non-zero via existing `ZeroAddress`) and records it in the receipt. Signature is now `paidQuery(storeId, queryHash, provider, agentId, amount, nonce, deadline, authSig)`. The settlement/forwarding flow (AERE402 rail, fee to sink, delta-measured forward to recipient) is unchanged; `receiptId` formula unchanged.
|
||||
- `attestRetrieval` priced branch now reverts new error `NotReceiptProvider()` unless `msg.sender == receipt.provider`, so a third party (or the payer) cannot front-run the honest provider and burn the receipt with a junk resultRoot. `getReceipt` view extended to also return `provider`.
|
||||
|
||||
### L3 (LOW) DOCUMENTED (accepted risk), not code-changed
|
||||
File: `contracts/erc8004/AereAP2MandateVerifier.sol`
|
||||
File: `aere-contracts/contracts/erc8004/AereAP2MandateVerifier.sol`
|
||||
- Chose DOCUMENT over CODE-CHANGE, per the task's guidance, because the two candidate code fixes are unsuitable: (a) a per-authorization nonce would break the intended standing-mandate ("sign once, spend repeatedly up to the cap") semantics that the design and tests rely on; (b) "bind consumption to the executor" is already the built-in `SETTLEMENT_EXECUTOR` gate.
|
||||
- Strengthened the contract-level and `authorizeSpend` NatSpec: the open accounting path (`SETTLEMENT_EXECUTOR == address(0)`) is verification/test-only and MUST NOT be used in production; production MUST set `SETTLEMENT_EXECUTOR` to the AERE402 facilitator so a mandate's cap is only ever consumed alongside a real settlement. No funds at risk (this contract holds none); the vector is cap-exhaustion griefing only.
|
||||
- The existing test "enforces the settlement-executor gate when one is configured" already proves the mitigation works (a non-executor is rejected, the configured executor succeeds). No new test needed.
|
||||
|
||||
## Tests added / changed
|
||||
- `test/erc8004-adapters.test.js`: `deployRep` now authorizes `other` as a feedback author (both branches). Two pre-existing tests that relied on the ungated `giveFeedback` were updated to call as the authorized `other` (legitimate behavior change from the M1 gate). Added new test "gates giveFeedback to owner-authorized feedback authors (M1)": unauthorized caller reverts `NotAuthorizedFeedbackAuthor` and writes nothing, owner authorizes -> same call succeeds and moves the live score to 10, owner revokes -> re-blocked, and only the owner may manage the allowlist.
|
||||
- `test/AerePQAggregate.test.js`: added "rejects a code-less SP1 gateway at construction (L1 fail-open guard)" (EOA gateway reverts `VerifierHasNoCode`, zero reverts `ZeroGateway`, real mock deploys).
|
||||
- `test/AereComputeMarketV3.test.js`: added "construction guards" > "rejects a code-less ZK verifier at construction (L1)" (EOA reverts `VerifierHasNoCode`, zero reverts `ZeroAddress`, real mock deploys).
|
||||
- `test/aere-pq-screen.test.js`: added "rejects a non-zero code-less non-revocation verifier at construction, but allows zero (L1)" (EOA reverts `VerifierHasNoCode`; zero deploys and `nonRevocationConfigured()==false`; real mock deploys).
|
||||
- `test/aere-vector-store.test.js`: the two `paidQuery` calls updated to pass `provider.address`; the paid-query test extended to assert the receipt is bound to the provider and that a third party (`operator`) and even the payer (`consumer`) are rejected `NotReceiptProvider` with the receipt left unconsumed, then the bound provider consumes it successfully (L2 proof).
|
||||
- `aere-contracts/test/erc8004-adapters.test.js`: `deployRep` now authorizes `other` as a feedback author (both branches). Two pre-existing tests that relied on the ungated `giveFeedback` were updated to call as the authorized `other` (legitimate behavior change from the M1 gate). Added new test "gates giveFeedback to owner-authorized feedback authors (M1)": unauthorized caller reverts `NotAuthorizedFeedbackAuthor` and writes nothing, owner authorizes -> same call succeeds and moves the live score to 10, owner revokes -> re-blocked, and only the owner may manage the allowlist.
|
||||
- `aere-contracts/test/AerePQAggregate.test.js`: added "rejects a code-less SP1 gateway at construction (L1 fail-open guard)" (EOA gateway reverts `VerifierHasNoCode`, zero reverts `ZeroGateway`, real mock deploys).
|
||||
- `aere-contracts/test/AereComputeMarketV3.test.js`: added "construction guards" > "rejects a code-less ZK verifier at construction (L1)" (EOA reverts `VerifierHasNoCode`, zero reverts `ZeroAddress`, real mock deploys).
|
||||
- `aere-contracts/test/aere-pq-screen.test.js`: added "rejects a non-zero code-less non-revocation verifier at construction, but allows zero (L1)" (EOA reverts `VerifierHasNoCode`; zero deploys and `nonRevocationConfigured()==false`; real mock deploys).
|
||||
- `aere-contracts/test/aere-vector-store.test.js`: the two `paidQuery` calls updated to pass `provider.address`; the paid-query test extended to assert the receipt is bound to the provider and that a third party (`operator`) and even the payer (`consumer`) are rejected `NotReceiptProvider` with the receipt left unconsumed, then the bound provider consumes it successfully (L2 proof).
|
||||
|
||||
## Real re-run results (npx hardhat test <file>, from aerenew/contracts)
|
||||
- test/erc8004-adapters.test.js .... 19 passing
|
||||
- test/aere-vector-store.test.js ... 8 passing
|
||||
- test/AerePQAggregate.test.js ..... 18 passing
|
||||
- test/AereComputeMarketV3.test.js . 14 passing
|
||||
- test/aere-pq-screen.test.js ...... 13 passing
|
||||
- aere-contracts/test/erc8004-adapters.test.js .... 19 passing
|
||||
- aere-contracts/test/aere-vector-store.test.js ... 8 passing
|
||||
- aere-contracts/test/AerePQAggregate.test.js ..... 18 passing
|
||||
- aere-contracts/test/AereComputeMarketV3.test.js . 14 passing
|
||||
- aere-contracts/test/aere-pq-screen.test.js ...... 13 passing
|
||||
|
||||
`npx hardhat compile`: green (compiled successfully, then "Nothing to compile" on re-run).
|
||||
|
||||
|
||||
@ -24,11 +24,11 @@ No CRITICAL and no HIGH issue was found. The fund-flow contracts (AereComputeMar
|
||||
|
||||
## Per-finding detail
|
||||
|
||||
### M1 (MEDIUM) — AereReputationRegistry8004.giveFeedback: permissionless reputation writes / sybil
|
||||
### M1 (MEDIUM), AereReputationRegistry8004.giveFeedback: permissionless reputation writes / sybil
|
||||
|
||||
`giveFeedback(uint256 agentId, int8 delta, bytes32 evidenceHash, string evidenceURI)` (lines 103-114) has no `msg.sender` restriction. It checks only: agent registered, `delta in {-1,0,1}`, and that the adapter itself is an attestor on the live `AereAIReputation`. It then forwards `REPUTATION.attest(operator, agentKey, delta, evidenceHash, evidenceURI)` with the adapter as the on-chain attestor.
|
||||
|
||||
The live `AereAIReputation` (read at `agentic/AereAIReputation.sol`) deliberately gates `attest` to a curated, immutable attestor set and adds anti-abuse: no self-attest and dedup by `(attestor, evidenceHash)`. Routing through the adapter collapses all callers into ONE attestor identity, so:
|
||||
The live `AereAIReputation` (read at `aere-contracts/contracts/agentic/AereAIReputation.sol`) deliberately gates `attest` to a curated, immutable attestor set and adds anti-abuse: no self-attest and dedup by `(attestor, evidenceHash)`. Routing through the adapter collapses all callers into ONE attestor identity, so:
|
||||
- the `(attestor, evidenceHash)` dedup is defeated because an attacker supplies a fresh `evidenceHash` per call;
|
||||
- `positiveCount` / `disputeCount` can be driven arbitrarily by any address.
|
||||
|
||||
@ -40,9 +40,9 @@ Condition / mitigation: this bites only when the adapter is registered as an att
|
||||
|
||||
Fix direction: gate `giveFeedback` to an authorized feedback-submitter set (or a per-interaction proof, e.g. an AERE402 settlement receipt binding the caller to a real interaction), so the adapter cannot act as an open reputation firehose. If permissionless feedback is intended, the score must not be treated as sybil-resistant by any downstream gate.
|
||||
|
||||
### L1 (LOW) — Verifier constructors do not assert the gateway has code (fail-open if misdeployed)
|
||||
### L1 (LOW), Verifier constructors do not assert the gateway has code (fail-open if misdeployed)
|
||||
|
||||
`ISP1Verifier.verifyProof(...)` is declared `external view` with NO return value (`zkverify/ISP1Verifier.sol`). For an external call to a void-returning function, Solidity omits the `extcodesize` check, so a call to a codeless address SUCCEEDS silently. A verifier that relies on "verifyProof reverts on an invalid proof" therefore fails OPEN if its gateway address has no code.
|
||||
`ISP1Verifier.verifyProof(...)` is declared `external view` with NO return value (`aere-contracts/contracts/zkverify/ISP1Verifier.sol`). For an external call to a void-returning function, Solidity omits the `extcodesize` check, so a call to a codeless address SUCCEEDS silently. A verifier that relies on "verifyProof reverts on an invalid proof" therefore fails OPEN if its gateway address has no code.
|
||||
|
||||
`AereFinalityCertificateVerifier` guards exactly this: its constructor reverts `VerifierHasNoCode` when `gateway.code.length == 0` (line 199, with a NatSpec comment naming the silent-accept risk). The following do NOT:
|
||||
- `AerePQAggregateVerifier` constructor (lines 187-192): checks only `gateway != 0` and `vkey != 0`. A codeless gateway makes `verifyAggregate` accept every committee authorization = post-quantum auth bypass for any account bound via `AerePQAggregateModule`.
|
||||
@ -53,7 +53,7 @@ Severity is LOW because the gateway is an IMMUTABLE constructor argument set by
|
||||
|
||||
Fix direction: add the same `if (gateway.code.length == 0) revert` guard used by `AereFinalityCertificateVerifier` to `AerePQAggregateVerifier`, `AereComputeMarketV3`, and `AereBitstringStatusList` (or require a successful known-answer call at construction).
|
||||
|
||||
### L2 (LOW) — AereVectorStore: paid-query receipt not bound to the attesting provider
|
||||
### L2 (LOW), AereVectorStore: paid-query receipt not bound to the attesting provider
|
||||
|
||||
`paidQuery` mints a receipt keyed by `keccak(this, storeId, queryHash, agentId, nonce)` and forwards the net payment to `paymentRecipient`. `attestRetrieval` (lines 344-381) then consumes the receipt with only these checks: exists, not consumed, `storeId`/`queryHash` match, `amount >= queryPrice`. There is NO check that `msg.sender` is any particular provider.
|
||||
|
||||
@ -61,7 +61,7 @@ Because `receiptId`, `storeId` and `queryHash` are all public (derivable from th
|
||||
|
||||
No funds are stolen (the payment already reached `paymentRecipient`), so this is griefing / service-denial, LOW. Fix direction: bind the receipt to an intended provider (recorded at paidQuery or asserted via signature), or record attestations per-provider rather than one-shot per receipt.
|
||||
|
||||
### L3 (LOW) — AereAP2MandateVerifier: replayable cap-consumption in the open path
|
||||
### L3 (LOW), AereAP2MandateVerifier: replayable cap-consumption in the open path
|
||||
|
||||
`authorizeSpend` records cumulative spend under `mandateHash` and enforces the cap. The `mandateHash` does NOT include `amount`, so a valid `falconSig` is a standing authorization: each `authorizeSpend` call consumes `amount` from the cap. When `SETTLEMENT_EXECUTOR == address(0)` (the "open accounting path", used in the test at lines 160-163 and 491-492 where one `sig` authorizes two spends), the call is permissionless. An attacker who observes the public `falconSig` can replay `authorizeSpend` to exhaust the mandate's remaining cap without any real settlement, blocking the agent's legitimate spends under that mandate.
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ Technical specification. Chain 2800 (Aere Network mainnet).
|
||||
|
||||
Grounding and consistency: this document describes a live compliance monitor that
|
||||
generalizes the offline determinism proofs already in the repository. It is
|
||||
consistent by construction with `aerenew/parallel-executor/README.md` (the
|
||||
consistent by construction with `aere-research/parallel-executor/README.md` (the
|
||||
Block-STM correctness guarantee), `aerenew/parallel/combined-fork-binary/VALIDATION_REPORT.md`
|
||||
(the forked-Besu commit path, 253 real blocks re-imported with zero state-root
|
||||
mismatch), and `aerenew/docs/AERE-CROSS-CLIENT-DETERMINISM.md` (two independent
|
||||
|
||||
@ -19,7 +19,7 @@ in the Java precompile). The SP1 guest side is Rust/Plonky3, but the port TARGET
|
||||
Java Besu precompile and the direct sibling sub-component is Python/Node/Java, so I matched that.
|
||||
|
||||
Production side (Java precompile, behind the still-fail-closed top level):
|
||||
`aerenew/pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java`
|
||||
`aere-research/precompiles/Sp1StarkVerifierPrecompiledContract.java`
|
||||
- `BabyBear` (was: add/sub/mul/pow/inv): ADDED `neg`, `GENERATOR = 31`, `TWO_ADICITY = 27`,
|
||||
`twoAdicGenerator(bits)`.
|
||||
- `BabyBearExt4` (was: add/mul with W as `W_UNSET`/`TODO(port)`): PINNED `W = 11`, removed the
|
||||
@ -81,5 +81,5 @@ is real, audited, and founder-activated. This remains a multi-week port: compone
|
||||
- `aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md`: section 2 (component (a) status -> IMPLEMENTED +
|
||||
TESTED, with the remaining [VERIFY]/[MEASURE] items), the section 9 effort-table row (a), the
|
||||
top-level status line (ONE -> TWO validated sub-components), and the section 10 file list.
|
||||
- `aerenew/pqc-fork/pq-stark/README.md`: status bullets, layout table, reproduce commands, and a new
|
||||
- `aere-research/pq-stark/README.md`: status bullets, layout table, reproduce commands, and a new
|
||||
component-(a) section.
|
||||
|
||||
@ -36,11 +36,11 @@ detailed porting spec plus ONE genuinely-tractable, independently-tested sub-com
|
||||
`walk(index, logMaxHeight, logFinalPolyLen)` (per-layer folding-index walk: index, sibling=index^1,
|
||||
index_pair=index>>1, parity; terminating in the final-poly domain).
|
||||
Files:
|
||||
- `aerenew/pqc-fork/pq-stark/fri_query_index_reference.py` (Python reference)
|
||||
- `aerenew/pqc-fork/pq-stark/fri_query_index_reference.mjs` (Node, independent second language)
|
||||
- `aerenew/pqc-fork/pq-stark/FriQueryIndexSelfTest.java` (standalone Java, no Besu classpath)
|
||||
- `aerenew/pqc-fork/pq-stark/test_fri_query_index.py` (harness: goldens + invariants + alt-algo
|
||||
+ cross-language agreement) -> `aerenew/pqc-fork/results/kat-results-fri-query-index.json`
|
||||
- `aere-research/pq-stark/fri_query_index_reference.py` (Python reference)
|
||||
- `aere-research/pq-stark/fri_query_index_reference.mjs` (Node, independent second language)
|
||||
- `aere-research/pq-stark/FriQueryIndexSelfTest.java` (standalone Java, no Besu classpath)
|
||||
- `aere-research/pq-stark/test_fri_query_index.py` (harness: goldens + invariants + alt-algo
|
||||
+ cross-language agreement) -> `aere-research/results/kat-results-fri-query-index.json`
|
||||
- `FriQueryIndex` helper added to `Sp1StarkVerifierPrecompiledContract.java`, wired into
|
||||
`Fri.checkQuery` (still returns UNAVAILABLE) behind the fail-closed top level.
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ retarget (a founder decision). The real achievement is kept stated; only the sco
|
||||
- `AERE-STARK-CORE-ADVANCE-SUMMARY.md`
|
||||
- Overclaim in each: framed as a component of the "SP1/Plonky3 inner STARK-verify port."
|
||||
|
||||
4. `aerenew/pqc-fork/pq-stark/README.md`
|
||||
4. `aere-research/pq-stark/README.md`
|
||||
- Overclaim: title + opening claimed it "verifies SP1's INNER hash-based Plonky3/FRI STARK
|
||||
directly ... removes the one quantum-vulnerable link in the SP1 proof chain."
|
||||
- Fix: prominent SCOPE CAVEAT block at top; retitled to "BabyBear/Plonky3 FRI/STARK verify
|
||||
@ -132,22 +132,22 @@ retarget (a founder decision). The real achievement is kept stated; only the sco
|
||||
|
||||
### Sweep: pqc-fork tree
|
||||
|
||||
17. `aerenew/pqc-fork/pq-stark/spec-mmcs-babybear.md`
|
||||
17. `aere-research/pq-stark/spec-mmcs-babybear.md`
|
||||
- Overclaim: "the exact SP1 inner config" / "which MMCS Plonky3/SP1 use."
|
||||
- Fix: top scope caveat ("Plonky3/SP1" means Plonky3 `0.4.3-succinct`, Aere's own BabyBear+FRI
|
||||
stack, not SP1 6.1.0 Hypercube; confirmed for a BabyBear+FRI verifier, not an SP1 6.1.0 one).
|
||||
|
||||
18. `aerenew/pqc-fork/pq-stark/spec-fri-babybear.md`
|
||||
18. `aere-research/pq-stark/spec-fri-babybear.md`
|
||||
- Overclaim: "the exact FRI low-degree test Plonky3/SP1 use."
|
||||
- Fix: top scope caveat (SP1 6.1.0's inner recursion uses BaseFold not FRI; FRI does not apply to
|
||||
SP1 6.1.0; confirmed for Aere's own Plonky3 circuits).
|
||||
|
||||
19. `aerenew/pqc-fork/pq-stark/spec-poseidon2-constants.md`
|
||||
19. `aere-research/pq-stark/spec-poseidon2-constants.md`
|
||||
- Overclaim: constants framed as those "Plonky3/SP1 use."
|
||||
- Fix: top scope caveat (these are BabyBear constants; SP1 6.1.0 is KoalaBear/Hypercube and uses
|
||||
different constants; confirmed for a BabyBear+FRI verifier).
|
||||
|
||||
20. `aerenew/pqc-fork/pq-stark/export-inner-stark-vector.md`
|
||||
20. `aere-research/pq-stark/export-inner-stark-vector.md`
|
||||
- Overclaim: whole premise "export the SP1 inner hash-based FRI/STARK proof (the shrink/compress
|
||||
Plonky3 shard proof over BabyBear + Poseidon2 + FRI) from the pinned SP1 v6.1.0 toolchain."
|
||||
- Fix: prominent SCOPE CORRECTION banner (SP1 6.1.0 exports a Hypercube/KoalaBear ShardProof, not
|
||||
|
||||
@ -45,7 +45,7 @@ two checksums, byte-identical to the AERE pin). Corroborating source pages:
|
||||
- https://github.com/Plonky3/Plonky3 poseidon2/src/{round_numbers.rs, external.rs}
|
||||
- https://github.com/rust-random/rngs rand_xoshiro (SplitMix64 seed, next_u32 = next_u64>>32)
|
||||
|
||||
Full provenance + the KAT vectors: `aerenew/pqc-fork/pq-stark/spec-poseidon2-constants.md`.
|
||||
Full provenance + the KAT vectors: `aere-research/pq-stark/spec-poseidon2-constants.md`.
|
||||
|
||||
## Conformance KAT (executed from the pinned library, reproduced by all references)
|
||||
|
||||
@ -58,15 +58,15 @@ Results: `python test_poseidon2_babybear.py` -> PASS=47017 FAIL=0 (Python/Node/J
|
||||
|
||||
## Files changed
|
||||
|
||||
- `aerenew/pqc-fork/pq-stark/poseidon2_babybear_reference.py` / `.mjs` — real constants, R_INV
|
||||
- `aere-research/pq-stark/poseidon2_babybear_reference.py` / `.mjs`, real constants, R_INV
|
||||
internal layer, conformance KATs.
|
||||
- `aerenew/pqc-fork/pq-stark/Poseidon2BabyBearSelfTest.java` — same; self-test PASS=13536.
|
||||
- `aerenew/pqc-fork/pq-stark/test_poseidon2_babybear.py` — added conformance stage; honest status.
|
||||
- `aerenew/pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java` — real constants, R_INV
|
||||
- `aere-research/pq-stark/Poseidon2BabyBearSelfTest.java`, same; self-test PASS=13536.
|
||||
- `aere-research/pq-stark/test_poseidon2_babybear.py`, added conformance stage; honest status.
|
||||
- `aere-research/precompiles/Sp1StarkVerifierPrecompiledContract.java`, real constants, R_INV
|
||||
internal layer, `Poseidon2Bb.available = true`; decoupled challenger gate
|
||||
(`Challenger.spongePorted = false`) so the top level stays fail-closed.
|
||||
- `aerenew/pqc-fork/pq-stark/README.md`, `aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md` — real status.
|
||||
- New: `aerenew/pqc-fork/pq-stark/spec-poseidon2-constants.md` (provenance/citation doc).
|
||||
- `aere-research/pq-stark/README.md`, `aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md`, real status.
|
||||
- New: `aere-research/pq-stark/spec-poseidon2-constants.md` (provenance/citation doc).
|
||||
|
||||
## Fail-closed confirmation
|
||||
|
||||
|
||||
@ -25,15 +25,15 @@ The Poseidon2 permutation over BabyBear (p = 2^31 - 2^27 + 1) at the standard SP
|
||||
- A `compress2to1` truncated-permutation 2-to-1 compression for the Merkle layer (shape [VERIFY]).
|
||||
|
||||
Files (mirrors the field sub-component's Python + Node + standalone-Java + precompile convention):
|
||||
- `aerenew/pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java` - `Poseidon2Bb.permute`
|
||||
- `aere-research/precompiles/Sp1StarkVerifierPrecompiledContract.java` - `Poseidon2Bb.permute`
|
||||
implemented; `Poseidon2Bb.available` STAYS false (gates everything above it).
|
||||
- `aerenew/pqc-fork/pq-stark/poseidon2_babybear_reference.py` (Python reference).
|
||||
- `aerenew/pqc-fork/pq-stark/poseidon2_babybear_reference.mjs` (Node reference).
|
||||
- `aerenew/pqc-fork/pq-stark/Poseidon2BabyBearSelfTest.java` (standalone Java, no Besu classpath).
|
||||
- `aerenew/pqc-fork/pq-stark/test_poseidon2_babybear.py` (harness).
|
||||
- `aerenew/pqc-fork/results/kat-results-poseidon2-babybear.json` (machine-readable result).
|
||||
- `aere-research/pq-stark/poseidon2_babybear_reference.py` (Python reference).
|
||||
- `aere-research/pq-stark/poseidon2_babybear_reference.mjs` (Node reference).
|
||||
- `aere-research/pq-stark/Poseidon2BabyBearSelfTest.java` (standalone Java, no Besu classpath).
|
||||
- `aere-research/pq-stark/test_poseidon2_babybear.py` (harness).
|
||||
- `aere-research/results/kat-results-poseidon2-babybear.json` (machine-readable result).
|
||||
- Docs updated: `aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md` (intro, section 3, section 9 table,
|
||||
section 10 files) and `aerenew/pqc-fork/pq-stark/README.md`.
|
||||
section 10 files) and `aere-research/pq-stark/README.md`.
|
||||
|
||||
## Self-consistency result (REAL, ran 2026-07-19)
|
||||
|
||||
|
||||
@ -42,13 +42,35 @@ query indices / grinding IN-CIRCUIT from the transcript, and that closes the loo
|
||||
the derived betas/indices, fed into the confirmed (d) verify_query, accept the real FRI ground-truth
|
||||
proof and reject a tampered beta (pq-stark/test_challenger.py, PASS=44). Component (e)'s generic quotient
|
||||
check reproduces the pinned p3-uni-stark verifier's ACCEPT on two known example AIRs (Fibonacci +
|
||||
degree-3 mul) and rejects tampered openings/quotient/alpha (pq-stark/test_air_quotient.py, PASS=18). The
|
||||
degree-3 mul) and rejects tampered openings/quotient/alpha (aere-research/pq-stark/test_air_quotient.py, PASS=18). The
|
||||
remaining un-ported crypto-core piece is the SP1-recursion-SPECIFIC AIR + vkey binding (part of component
|
||||
(e), section 6.2), so the top level STAYS FAIL-CLOSED for real SP1 proofs: with
|
||||
StarkConstraints.SP1_RECURSION_AIR_PORTED = false, StarkConstraints.evaluateAtZeta returns UNAVAILABLE at
|
||||
the constraint stage, before the query loop and before the single return ACCEPT, so verify() returns
|
||||
EMPTY for every real input.
|
||||
|
||||
END-TO-END ASSEMBLY (2026-07-19, new): the six confirmed components have now been ASSEMBLED into ONE full
|
||||
BabyBear+FRI verify pipeline and run END TO END against a REAL proof, PASS=15/15
|
||||
(pq-stark/stark_e2e_reference.py kat). The pipeline (transcript -> observe(trace) -> constraint alpha ->
|
||||
observe(quotient) -> zeta -> PCS.verify [FRI batch alpha, verify_shape_and_sample_challenges,
|
||||
reduced-opening combination over the input-batch MMCS openings, verify_query, folded==final_poly] -> AIR
|
||||
quotient identity) is traced verbatim from the pinned p3-uni-stark verifier.rs + p3-fri two_adic_pcs.rs +
|
||||
p3-fri verifier.rs, and it REUSES the six confirmed reference modules (no reimplementation). It ACCEPTS
|
||||
two genuine proofs that the pinned p3-uni-stark verifier also accepts (Fibonacci n=8, one quotient chunk;
|
||||
degree-3 multiply n=16, two chunks -> multi-matrix input batch + multi-chunk zps), emitted by the new
|
||||
pinned extractor pq-stark/e2e-extractor (which asserts the library ACCEPT), and REJECTS every tamper
|
||||
(a trace opening, a FRI layer, an input-batch opening, the public values, the final polynomial), plus a
|
||||
commitment-swap negative control. The one piece not previously among the six components, the PCS
|
||||
reduced-opening combination + top-level transcript threading, is implemented directly from pinned source
|
||||
over the confirmed primitives. HONEST SCOPE: the proof verified is a p3-uni-stark EXAMPLE AIR under an
|
||||
EXAMPLE FRI config (log_blowup=2, num_queries=28, pow_bits=8), NOT an Aere production circuit and NOT SP1
|
||||
6.1.0. STEP-1 finding: Aere has NO standalone BabyBear+FRI STARK circuit (all zk-circuits/* are SP1 guest
|
||||
programs on SP1 6.3.1 = Hypercube; p3-uni-stark is only a transitive dep of that stack), so no
|
||||
Aere-own-AIR end-to-end KAT is available to run; that (and the SP1 6.1.0 Hypercube retarget) remain
|
||||
open, see AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md. This end-to-end assembly does NOT change the
|
||||
fail-closed contract: it is offline tooling, does not run in the EVM, and SP1_RECURSION_AIR_PORTED stays
|
||||
false, so 0x0AE8 still returns EMPTY for every real input. DO NOT ACTIVATE.
|
||||
|
||||
Companion documents (read together):
|
||||
- `docs/PQ-STARK-VERIFIER-PRECOMPILE-2026-07-18.md` (design, encoding, soundness, gas).
|
||||
- `docs/PQ-STARK-VERIFIER-ACTIVATION-2026-07-18.md` (gated activation plan).
|
||||
@ -471,7 +493,7 @@ Interface (implemented).
|
||||
- Still NOT on the real path: `bind_vk(vkey_digest, preprocessed_commitment)` and the SP1 recursion
|
||||
AIR constraint evaluator (part 2 below).
|
||||
|
||||
CONFORMANCE CONFIRMED (`pq-stark/test_air_quotient.py`, ran 2026-07-19, PASS=18 FAIL=0, Python + Node +
|
||||
CONFORMANCE CONFIRMED (`aere-research/pq-stark/test_air_quotient.py`, ran 2026-07-19, PASS=18 FAIL=0, Python + Node +
|
||||
standalone Java byte-identical). The pinned crates `p3-uni-stark` / `p3-air` / `p3-baby-bear` /
|
||||
`p3-commit` 0.4.3-succinct (checksums `fc3dfdeb...` / `d3a5de20...` / `d69e6e9a...` / `50acacc7...`, the
|
||||
last two byte-identical to the Poseidon2/MMCS components) were executed via cargo
|
||||
@ -485,7 +507,7 @@ by replaying the verifier's exact transcript prefix:
|
||||
quotient chunks (log_quotient_degree = 1), so it exercises the split-domain `zps` product.
|
||||
The generic reference reproduces the library ACCEPT on both (the identity holds) and REJECTS three tamper
|
||||
variants per case: a corrupted trace opening, a wrong quotient chunk, a wrong alpha. Full vectors are in
|
||||
`pq-stark/air_quotient_ground_truth.json` and `../results/kat-results-air-quotient.json`. The extractor's
|
||||
`aere-research/pq-stark/air_quotient_ground_truth.json` and `../results/kat-results-air-quotient.json`. The extractor's
|
||||
`perm_zeros` equals the confirmed Poseidon2 "zeros" vector and its `val_generator` equals 31, tying the
|
||||
ground truth to the confirmed sub-components.
|
||||
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
# Spec 12: Aere VSM (Verifiable Semantic Memory) — DONE
|
||||
# Spec 12: Aere VSM (Verifiable Semantic Memory), DONE
|
||||
|
||||
On-chain attestation for an AI agent's vector-store memory: clear owner, verifiable
|
||||
append-only history, PQC-authenticated commits, and paid attested retrieval on the AERE402 rail.
|
||||
|
||||
## Deliverables (all real, tested)
|
||||
|
||||
1. Contract: `aerenew/contracts/contracts/agentic/AereVectorStore.sol` (solc 0.8.23, new file, no deployed contract modified)
|
||||
2. Test: `aerenew/contracts/test/aere-vector-store.test.js` — 8 passing
|
||||
1. Contract: `aere-contracts/contracts/agentic/AereVectorStore.sol` (solc 0.8.23, new file, no deployed contract modified)
|
||||
2. Test: `aere-contracts/test/aere-vector-store.test.js`, 8 passing
|
||||
3. Doc: `aerenew/docs/AERE-VSM.md`
|
||||
|
||||
## Contract surface
|
||||
@ -52,9 +52,9 @@ separately vs LIVE mainnet precompile by AerePQCAttestation path.
|
||||
## Honesty flags
|
||||
|
||||
- [VERIFY]: on-chain commit registry, PQC-authenticated commits (0x0AE1), retrieval attestation,
|
||||
inclusion proofs, AERE402 paid-query gate — built + tested.
|
||||
inclusion proofs, AERE402 paid-query gate, built + tested.
|
||||
- [MEASURE]: embedding model, vector similarity search / index, raw vector data, and semantic
|
||||
quality/relevance — all OFF-CHAIN. On-chain attestation proves PROVENANCE + OWNERSHIP + that a
|
||||
quality/relevance, all OFF-CHAIN. On-chain attestation proves PROVENANCE + OWNERSHIP + that a
|
||||
retrieval named a committed version, NOT semantic quality/relevance.
|
||||
- Scope boundary preserved: PQC-authenticated memory commits do NOT make consensus post-quantum
|
||||
(blocks still Besu QBFT + classical ECDSA). No new token (AERE402 uses existing rails).
|
||||
|
||||
10
AERE-VSM.md
10
AERE-VSM.md
@ -3,8 +3,8 @@
|
||||
Status: on-chain registry, attested retrieval, and AERE402 paid query are BUILT and TESTED [VERIFY].
|
||||
The embedding model, the vector similarity search, and the raw vector data are OFF-CHAIN [MEASURE].
|
||||
|
||||
Contract: `aerenew/contracts/contracts/agentic/AereVectorStore.sol` (solc 0.8.23).
|
||||
Tests: `aerenew/contracts/test/aere-vector-store.test.js` (8 passing, Falcon mocked in test).
|
||||
Contract: `aere-contracts/contracts/agentic/AereVectorStore.sol` (solc 0.8.23).
|
||||
Tests: `aere-contracts/test/aere-vector-store.test.js` (8 passing, Falcon mocked in test).
|
||||
|
||||
---
|
||||
|
||||
@ -204,7 +204,9 @@ on-chain settlement on the AERE402 rail.
|
||||
does NOT prove RELEVANCE. Semantic quality is an off-chain property, measured off-chain
|
||||
[MEASURE].
|
||||
- Inclusion in `resultRoot` proves the provider committed to returning that result; it does not
|
||||
prove the result was the best or the correct nearest neighbour for the query.
|
||||
prove the result was the best or the correct nearest neighbour for the query. That gap is
|
||||
addressed (made falsifiable and bonded, NOT proven) by `AereVSMAttestor.sol`. See
|
||||
`AERE-VSM-ATTESTED-RETRIEVAL.md`, in particular its section "What Aere VSM does NOT prove".
|
||||
|
||||
### Scope boundary
|
||||
|
||||
@ -237,7 +239,7 @@ proven on-chain.
|
||||
|
||||
## 8. Test result
|
||||
|
||||
`npx hardhat test test/aere-vector-store.test.js`, run from `aerenew/contracts`, reports
|
||||
`npx hardhat test aere-contracts/test/aere-vector-store.test.js`, run from `aerenew/contracts`, reports
|
||||
8 passing:
|
||||
|
||||
1. commits a PQC store version 1, then version 2, preserving history append-only
|
||||
|
||||
@ -321,17 +321,17 @@ keccak precompile configuration, the prover hardware, and the proof mode):
|
||||
|
||||
Built at `aerenew/pqc-fork/pq-finality-circuit/xmss-verify-core/`:
|
||||
|
||||
- `src/sha256.rs`: a dependency-free `no_std` SHA-256 (self-checked against FIPS 180-4
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/src/sha256.rs`: a dependency-free `no_std` SHA-256 (self-checked against FIPS 180-4
|
||||
`SHA256("abc")` and `SHA256("")`). A production SP1 guest swaps this for the
|
||||
SP1-patched `sha2` precompile crate; the bytes are identical.
|
||||
- `src/xmss.rs`: the RFC 8391 XMSS-SHA2_10_256 verification core (`chain_lengths`,
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/src/xmss.rs`: the RFC 8391 XMSS-SHA2_10_256 verification core (`chain_lengths`,
|
||||
`wots_pk_from_sig`, `l_tree`, `compute_root`, `xmss_recover_root`, `xmss_verify`),
|
||||
`no_std`, allocation-free, float-free, hash-only.
|
||||
- `src/vectors.rs`: the official vector, GENERATED by `scripts/gen_vectors.mjs` from the
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/src/vectors.rs`: the official vector, GENERATED by `aere-research/pq-finality-circuit/scripts/gen_vectors.mjs` from the
|
||||
committed `contracts/test/fixtures/xmss-sha2_10_256-kat.json`
|
||||
(github.com/XMSS/xmss-reference, oid=1, idx=512, msg=0x25), so the Rust vector is
|
||||
provably derived from the official fixture with no hand transcription.
|
||||
- `tests/kat.rs`: the known-answer validation.
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/tests/kat.rs`: the known-answer validation.
|
||||
|
||||
Real result of `cargo test --offline` (run, not asserted from memory): 12 tests
|
||||
passed, 0 failed. The genuine official signature recovers the official root
|
||||
|
||||
@ -13,7 +13,7 @@ Never claim the aggregation proof works end to end.
|
||||
## What was found (grounding)
|
||||
|
||||
- OFFICIAL RFC 8391 XMSS-SHA2_10_256 known-answer vector already committed at
|
||||
`aerenew/contracts/test/fixtures/xmss-sha2_10_256-kat.json`
|
||||
`aere-contracts/test/fixtures/xmss-sha2_10_256-kat.json`
|
||||
(github.com/XMSS/xmss-reference, oid=1, idx=512, msg=0x25, pubRoot 0x9d898033...c3483).
|
||||
- Deployed on-chain XMSS verifier + independent JS oracle:
|
||||
`contracts/contracts/pqc/AereXmssVerifier.sol`, `contracts/test/xmssVerifier.test.js`.
|
||||
@ -36,15 +36,15 @@ Dir: `aerenew/pqc-fork/pq-finality-circuit/`
|
||||
- `xmss-verify-core/` Rust crate, ZERO external deps, `no_std`, allocation-free,
|
||||
float-free, hash-only, deterministic (models the aggregation guest's per-validator
|
||||
inner logic):
|
||||
- `src/sha256.rs` dependency-free SHA-256 (FIPS 180-4). Note: production SP1 guest
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/src/sha256.rs` dependency-free SHA-256 (FIPS 180-4). Note: production SP1 guest
|
||||
swaps in the SP1-patched `sha2` precompile; identical bytes.
|
||||
- `src/xmss.rs` RFC 8391 XMSS-SHA2_10_256 verify core: chain_lengths, WOTS_PKFromSig,
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/src/xmss.rs` RFC 8391 XMSS-SHA2_10_256 verify core: chain_lengths, WOTS_PKFromSig,
|
||||
L-tree, compute_root, xmss_recover_root, xmss_verify. Byte-for-byte model of the
|
||||
on-chain AereXmssVerifier.sol / JS oracle.
|
||||
- `src/vectors.rs` official vector, GENERATED from the committed KAT (provenance,
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/src/vectors.rs` official vector, GENERATED from the committed KAT (provenance,
|
||||
no hand transcription).
|
||||
- `tests/kat.rs` known-answer validation.
|
||||
- `scripts/gen_vectors.mjs` regenerates vectors.rs from the committed JSON.
|
||||
- `aere-research/pq-finality-circuit/xmss-verify-core/tests/kat.rs` known-answer validation.
|
||||
- `aere-research/pq-finality-circuit/scripts/gen_vectors.mjs` regenerates vectors.rs from the committed JSON.
|
||||
- `README.md`.
|
||||
|
||||
## REAL vector-test result (run, not asserted from memory)
|
||||
|
||||
@ -6,13 +6,15 @@
|
||||
| --- | --- |
|
||||
| AIP | 8 |
|
||||
| Title | Post-Quantum-Authorized Transaction Envelope (EIP-2718 Type 0x2A) |
|
||||
| Author | AERE Foundation |
|
||||
| Author | Aere Network Foundation |
|
||||
| Type | Standards Track |
|
||||
| Category | Core |
|
||||
| Status | Draft |
|
||||
| Created | 2026-07-18 |
|
||||
| Requires | 7 |
|
||||
| Ratification | Foundation-ratified (pre-decentralization) |
|
||||
| Supersedes | None |
|
||||
| Superseded-By | None |
|
||||
| Ratification | Not ratified; Draft. Ratifier is the founder (pre-decentralization). |
|
||||
|
||||
## Abstract
|
||||
|
||||
@ -156,7 +158,7 @@ accept the transaction only if the corresponding precompile returns the 32-byte
|
||||
sig_hash(32) || esig` and `sigLen == esig.length`; call `0x0AE1`.
|
||||
- ML-DSA-44: `input = pk(1312) || sig(2420) || sig_hash(32)`; call `0x0AE3`.
|
||||
|
||||
The client MUST use the same audited Bouncy Castle 1.83 verify path the precompile wraps, so
|
||||
The client MUST use the same Bouncy Castle 1.83 verify path the precompile wraps, so
|
||||
that transaction validation and an in-EVM `STATICCALL` to the precompile agree bit-for-bit
|
||||
on every `(pq_public_key, sig_hash, pq_signature)` triple. A transaction whose signature
|
||||
does not verify has no valid sender and is invalid: it MUST be rejected from the mempool and
|
||||
|
||||
276
CITATIONS-UNRESOLVED.md
Normal file
276
CITATIONS-UNRESOLVED.md
Normal file
@ -0,0 +1,276 @@
|
||||
# Citations in this repository that you cannot open
|
||||
|
||||
This file is generated by the legaturi-repara.cjs script in the Aere working tree and
|
||||
enforced by legaturi.cjs. It is the complete list, measured on 2026-08-11, of every
|
||||
path cited in this repository that does not resolve to a published file.
|
||||
|
||||
A citation is a promise that a claim is checkable. Where the target is not published,
|
||||
the claim is traceable but **not independently verifiable by you**, and it should be
|
||||
read as our assertion. Nothing was deleted to produce this list: every path below is
|
||||
still cited in the text exactly as our authors wrote it.
|
||||
|
||||
Paths that DO resolve are written relative to a side-by-side checkout of the Aere
|
||||
repositories, so they begin with a repository name, for example
|
||||
`aere-contracts/contracts/pqc/AereCryptoRegistry.sol`.
|
||||
|
||||
Unresolvable distinct paths in this repository: **259**.
|
||||
|
||||
- `06-mev-interop.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `07-compliance.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `AERE-COVERAGE-README.md` cited in: aere-docs/REPRODUCE.md
|
||||
- `aere-coverage-summary.json` cited in: aere-docs/REPRODUCE.md
|
||||
- `AERE-ERC8004-X402-CONFORMANCE-RESULT-2026-07-20.md` cited in: aere-docs/AERE-ERC8004-X402-CONFORMANCE.md
|
||||
- `aere-genesis-current.json` cited in: aere-docs/AERE-BENCHMARK-REPORT.md, aere-docs/AERE-EIP-COMPATIBILITY-MATRIX.md, aere-docs/AERE-PROTOCOL-SPECIFICATION.md
|
||||
- `aere-genesis-fusaka.json` cited in: aere-docs/AERE-EIP-COMPATIBILITY-MATRIX.md
|
||||
- `aere-genesis-pectra.json` cited in: aere-docs/AERE-EIP-COMPATIBILITY-MATRIX.md
|
||||
- `AERE-VSM-ATTESTED-RETRIEVAL.md` cited in: aere-docs/AERE-VSM.md
|
||||
- `aerenew/.github/workflows/reproducible-besu-build.yml` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/aips/AIP-N.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md
|
||||
- `aerenew/aips/CONTRIBUTING.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md
|
||||
- `aerenew/audit-package-pq-consensus/REPRODUCE.md` cited in: aere-docs/AERE-BENCHMARK-REPORT.md
|
||||
- `aerenew/basefee-floor-dryrun/basefee-floor.diff` cited in: aere-docs/AERE-PROTOCOL-SPECIFICATION.md
|
||||
- `aerenew/build-tracker/control.json` cited in: aere-docs/AERE-QUANTUM-MIGRATION.md, aere-docs/AERE-QUANTUM-SAFE-NETWORKING.md
|
||||
- `aerenew/chaos/WATCHTOWER-DESIGN.md` cited in: aere-docs/AERE-FAULT-INJECTION-HARNESS.md
|
||||
- `aerenew/conformance/conformance-vectors.json` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/conformance/lib.mjs` cited in: aere-docs/AERE-SHADOW-PRODUCER.md
|
||||
- `aerenew/conformance/README.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/contracts/contracts/pqc/AereAccountRetirement.sol` cited in: aere-docs/AERE-QUANTUM-MIGRATION.md
|
||||
- `aerenew/contracts/deployments/wave-a-identity-compliance-2026-07-19.json` cited in: aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md
|
||||
- `aerenew/contracts/foundry.toml` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/contracts/hardhat.config.js` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/contracts/hardhat.config.prague.js` cited in: aere-docs/AERE-ENTROPY-BEACON-FIX.md
|
||||
- `aerenew/contracts/reports/sharded-test-run/results.json` cited in: aere-docs/REPRODUCE.md
|
||||
- `aerenew/contracts/scripts/test-mldsa-local.js` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `aerenew/contracts/test/account-retirement.test.js` cited in: aere-docs/AERE-QUANTUM-MIGRATION.md
|
||||
- `aerenew/contracts/test/AereComputeMarketV3.liveness.test.js` cited in: aere-docs/AERE-COMPUTE-MARKET-V3-SUMMARY.md, aere-docs/AERE-COMPUTE-MARKET-V3.md
|
||||
- `aerenew/contracts/test/erc8004-x402-conformance.live.test.js` cited in: aere-docs/AERE-ERC8004-X402-CONFORMANCE.md
|
||||
- `aerenew/cross-client-determinism/LIVE-BESU-VS-NETHERMIND-2026-07-19.md` cited in: aere-docs/AERE-EIP-COMPATIBILITY-MATRIX.md
|
||||
- `aerenew/docs/AERE-AIP-PROCESS-AND-INDEX.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-ARCHITECTURE-MAP.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md, aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-BENCHMARK-REPORT.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md, aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-BUILD-LOOP-SUMMARY-2026-07-19.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-COMPUTE-MARKET-V3.md` cited in: aere-docs/AERE-COMPUTE-MARKET-V3-SUMMARY.md
|
||||
- `aerenew/docs/AERE-CROSS-CLIENT-DETERMINISM.md` cited in: aere-docs/AERE-SHADOW-PRODUCER.md
|
||||
- `aerenew/docs/AERE-EIP-COMPATIBILITY-MATRIX.md` cited in: aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md, aere-docs/AERE-PROTOCOL-SPECIFICATION.md, aere-docs/AERE-QUANTUM-MIGRATION.md, aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-ENGINEERING-SECURITY-SPEC.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md, aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md, aere-docs/AERE-POST-QUANTUM-GOVERNANCE.md, aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md, aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-ERC7683-DESTINATION.md` cited in: aere-docs/AERE-ERC7683-DESTINATION-SUMMARY.md
|
||||
- `aerenew/docs/AERE-ERC8004-X402-CONFORMANCE.md` cited in: aere-docs/AERE-ERC8004-SUMMARY.md
|
||||
- `aerenew/docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md` cited in: aere-docs/AERE-DEPLOY-RUNBOOK-SUMMARY.md
|
||||
- `aerenew/docs/AERE-POST-QUANTUM-GOVERNANCE.md` cited in: aere-docs/AERE-QUANTUM-MIGRATION.md
|
||||
- `aerenew/docs/AERE-PQ-AGGREGATE.md` cited in: aere-docs/AERE-PQ-AGGREGATE-SUMMARY.md
|
||||
- `aerenew/docs/AERE-PQ-FINALITY-CERTIFICATE.md` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE-SUMMARY.md, aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md, aere-docs/AERE-XMSS-AGGREGATION-CIRCUIT.md
|
||||
- `aerenew/docs/AERE-PQ-SCREEN.md` cited in: aere-docs/AERE-PQ-SCREEN-SUMMARY.md
|
||||
- `aerenew/docs/AERE-PROTOCOL-SPECIFICATION.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-QA-CONSOLIDATION-REPORT.md` cited in: aere-docs/AERE-BUILD-LOOP-SUMMARY-2026-07-19.md, aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-QUANTUM-MIGRATION.md` cited in: aere-docs/AERE-QUANTUM-MIGRATION-SUMMARY.md
|
||||
- `aerenew/docs/AERE-QUANTUM-SAFE-NETWORKING.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-SECURITY-FIXES.md` cited in: aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md
|
||||
- `aerenew/docs/AERE-SECURITY-REVIEW-NEW-CONTRACTS.md` cited in: aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md, aere-docs/AERE-SECURITY-FIXES.md
|
||||
- `aerenew/docs/AERE-SHADOW-PRODUCER.md` cited in: aere-docs/AERE-SHADOW-PRODUCER-SUMMARY.md
|
||||
- `aerenew/docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md
|
||||
- `aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md` cited in: aere-docs/AERE-STARK-BABYBEAR-FIELD-SUMMARY.md, aere-docs/AERE-STARK-CORE-ADVANCE-SUMMARY.md, aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md, aere-docs/AERE-STARK-POSEIDON2-CONSTANTS-CONFIRMED.md, aere-docs/AERE-STARK-POSEIDON2-SUMMARY.md
|
||||
- `aerenew/docs/AERE-VSM.md` cited in: aere-docs/AERE-VSM-SUMMARY.md
|
||||
- `aerenew/docs/AERE-WHITEPAPER-AIP-LINKAGE.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md
|
||||
- `aerenew/docs/AERE-XMSS-AGGREGATION-CIRCUIT.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md, aere-docs/AERE-XMSS-CIRCUIT-CORE-SUMMARY.md
|
||||
- `aerenew/docs/aerecore/AERECORE_PLAN.md` cited in: aere-docs/REPRODUCE.md
|
||||
- `aerenew/docs/AUDIT-FINDING-THRESHOLD-DUPLICATE-KEYS-2026-07-15.md` cited in: aere-docs/AERE-POST-QUANTUM-GOVERNANCE.md
|
||||
- `aerenew/docs/BASEFEE-FLOOR-FORK-RUNBOOK-2026-07-17.md` cited in: aere-docs/AERE-PROTOCOL-SPECIFICATION.md
|
||||
- `aerenew/docs/DECENTRALIZATION-2ND-CLIENT-RUNBOOK.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/docs/GOVERNANCE.md` cited in: aere-docs/AERE-POST-QUANTUM-GOVERNANCE.md
|
||||
- `aerenew/docs/NETHERMIND-2ND-CLIENT-LIVE-2026-07-17.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/docs/PQ-STARK-VERIFIER-ACTIVATION-2026-07-18.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/PQ-STARK-VERIFIER-PRECOMPILE-2026-07-18.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `aerenew/docs/RPC2-NODE-2026-07-17.md` cited in: aere-docs/AERE-QUANTUM-SAFE-NETWORKING.md
|
||||
- `aerenew/docs/THRESHOLD-PQC-2026-07-12.md` cited in: aere-docs/AERE-POST-QUANTUM-GOVERNANCE.md
|
||||
- `aerenew/docs/TRANZITIA-QBFT-SETTLED-2026-07-20.md` cited in: aere-docs/AERE-BENCHMARK-REPORT.md, aere-docs/AERE-PROTOCOL-SPECIFICATION.md
|
||||
- `aerenew/dryrun-results/dryrun/phase_postfork_kat.sh` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `aerenew/eips/eip-draft-pqc-account-authorization.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md
|
||||
- `aerenew/eips/eip-draft-pqc-signature-precompiles.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md
|
||||
- `aerenew/eips/eip-draft-shake256-precompile.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md, aere-docs/AERE-EIP-COMPATIBILITY-MATRIX.md
|
||||
- `aerenew/eips/README.md` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md
|
||||
- `aerenew/formal-contracts/specs/AereSink.symbolic.t.sol` cited in: aere-docs/AERE-CERTORA-FORMAL-VERIFICATION.md
|
||||
- `aerenew/formal-tla/MCliveness.cfg` cited in: aere-docs/AERE-TLA-FORMAL-SPEC.md
|
||||
- `aerenew/formal-tla/MCliveness.tla` cited in: aere-docs/AERE-TLA-FORMAL-SPEC.md
|
||||
- `aerenew/formal-tla/MCsafety.cfg` cited in: aere-docs/AERE-TLA-FORMAL-SPEC.md
|
||||
- `aerenew/formal-tla/MCsafety.tla` cited in: aere-docs/AERE-TLA-FORMAL-SPEC.md
|
||||
- `aerenew/formal-tla/MCsafety7.cfg` cited in: aere-docs/AERE-TLA-FORMAL-SPEC.md
|
||||
- `aerenew/formal-tla/QBFT.tla` cited in: aere-docs/AERE-TLA-FORMAL-SPEC.md
|
||||
- `aerenew/formal-tla/README.md` cited in: aere-docs/AERE-TLA-FORMAL-SPEC.md
|
||||
- `aerenew/genesis.json` cited in: aere-docs/AERE-BENCHMARK-REPORT.md, aere-docs/AERE-EIP-COMPATIBILITY-MATRIX.md
|
||||
- `aerenew/GITHUB_DEPLOYMENT_CHECKLIST.md` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/nethermind-pqc/proofs/mixed-client/proposer/01-onchain-alternation-hashmatch.txt` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/nethermind-pqc/QBFT-FOLLOWER-2026-07-12.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/nethermind-pqc/QBFT-GENESIS-SYNC-FIX-2026-07-13.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/nethermind-pqc/QBFT-PRODUCER-2ND-CLIENT-2026-07-13.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/nethermind-pqc/QBFT-VALIDATION-2026-07-12.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/nethermind-pqc/REAL-NETHERMIND-PQC-2026-07-12.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/nethermind-pqc/test/AerePqc.Tests/qbft-vectors.json` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `aerenew/node/REPRODUCIBLE.md` cited in: aere-docs/AERE-BENCHMARK-REPORT.md, aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/parallel/combined-fork-binary/BUILD_INFO.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md, aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/parallel/combined-fork-binary/logs/nist_kat_bc183.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `aerenew/parallel/combined-fork-binary/scripts/check5_precompiles.py` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `aerenew/parallel/combined-fork-binary/scripts/run_kat.sh` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `aerenew/parallel/combined-fork-binary/VALIDATION_REPORT.md` cited in: aere-docs/AERE-SHADOW-PRODUCER.md
|
||||
- `aerenew/pqc-fork/build-dist.sh` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/pqc-fork/probe-precompile-liveness.js` cited in: aere-docs/AERE-BENCHMARK-REPORT.md
|
||||
- `aerenew/pqc-fork/README.md` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `aerenew/pqc-fork/run-kats.sh` cited in: aere-docs/AERE-BENCHMARK-REPORT.md
|
||||
- `aerenew/pqc-fork/setup-fork.sh` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/REPRODUCE.md` cited in: aere-docs/AERE-BUILD-LOOP-SUMMARY-2026-07-19.md, aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/research-stage/formal-consensus/REPRODUCE.md` cited in: aere-docs/AERE-BENCHMARK-REPORT.md
|
||||
- `aerenew/scripts/deschise/flaguri-verify.cjs` cited in: aere-docs/VERIFY-POLICY.md
|
||||
- `aerenew/scripts/verify-besu-image.sh` cited in: aere-docs/AERE-BENCHMARK-REPORT.md, aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `aerenew/sdk-js/README.md` cited in: aere-docs/REPRODUCE.md
|
||||
- `aerenew/sdk-js/src/addresses.ts` cited in: aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md, aere-docs/AERE-POST-QUANTUM-GOVERNANCE.md
|
||||
- `aerenew/shadow-producer/blockstm-adapter.mjs` cited in: aere-docs/AERE-SHADOW-PRODUCER-SUMMARY.md
|
||||
- `aerenew/shadow-producer/package.json` cited in: aere-docs/AERE-SHADOW-PRODUCER-SUMMARY.md
|
||||
- `aerenew/shadow-producer/README.md` cited in: aere-docs/AERE-SHADOW-PRODUCER-SUMMARY.md
|
||||
- `aerenew/shadow-producer/shadow-producer.mjs` cited in: aere-docs/AERE-SHADOW-PRODUCER-SUMMARY.md
|
||||
- `aerenew/tools/create-aere-pqc/README.md` cited in: aere-docs/REPRODUCE.md
|
||||
- `AereVSMAttestor.sol` cited in: aere-docs/AERE-VSM.md
|
||||
- `air.rs` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `artifacts/besu-image-digest.json` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `AUDIT-REPORT-2026-07-14.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `batch-prover-recovered/bin/aere-prover/Cargo.toml` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `besu-image-digest.json` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `blockstm-adapter.mjs` cited in: aere-docs/AERE-SHADOW-PRODUCER.md
|
||||
- `chips/alu_base.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `chips/alu_ext.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `chips/prefix_sum_checks.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `chips/public_values.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `chips/select.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `combined-fork-binary/BUILD_INFO.txt` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `config/config.toml` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `config/genesis.json` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `contracts/contracts/interop/AereZkQbftLightClient.sol` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md
|
||||
- `contracts/contracts/modular/AerePQAggregateModule.sol` cited in: aere-docs/AERE-PQ-AGGREGATE.md
|
||||
- `contracts/contracts/mpc/AerePQAggregateVerifier.sol` cited in: aere-docs/AERE-PQ-AGGREGATE.md, aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md
|
||||
- `contracts/contracts/pqc/AerePQCKeyRegistry.sol` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md
|
||||
- `contracts/contracts/pqc/AerePQCTxAccount.sol` cited in: aere-docs/AIP-PQ-TX-2026-07-18.md
|
||||
- `contracts/contracts/pqc/AereXmssVerifier.sol` cited in: aere-docs/AERE-XMSS-AGGREGATION-CIRCUIT.md, aere-docs/AERE-XMSS-CIRCUIT-CORE-SUMMARY.md
|
||||
- `contracts/contracts/pqfinality/AereFinalityCertificateVerifier.sol` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md, aere-docs/AERE-XMSS-AGGREGATION-CIRCUIT.md, aere-docs/AERE-XMSS-CIRCUIT-CORE-SUMMARY.md
|
||||
- `contracts/contracts/pqfinality/AerePQAttestationKeyRegistry.sol` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md, aere-docs/AERE-XMSS-AGGREGATION-CIRCUIT.md
|
||||
- `contracts/contracts/validators/AereValidatorManifest.sol` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md
|
||||
- `contracts/contracts/zkverify/AerePQStarkVerifier.sol` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md, aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `contracts/test/AerePQAggregate.test.js` cited in: aere-docs/AERE-PQ-AGGREGATE.md
|
||||
- `contracts/test/AerePQCTxAccount.test.js` cited in: aere-docs/AIP-PQ-TX-2026-07-18.md
|
||||
- `contracts/test/AerePQFinalityCertificate.test.js` cited in: aere-docs/AERE-PQ-FINALITY-CERTIFICATE.md, aere-docs/AERE-XMSS-AGGREGATION-CIRCUIT.md
|
||||
- `contracts/test/fixtures/xmss-sha2_10_256-kat.json` cited in: aere-docs/AERE-XMSS-AGGREGATION-CIRCUIT.md
|
||||
- `contracts/test/xmssVerifier.test.js` cited in: aere-docs/AERE-XMSS-AGGREGATION-CIRCUIT.md, aere-docs/AERE-XMSS-CIRCUIT-CORE-SUMMARY.md
|
||||
- `crates/hypercube/src/verifier/hashable_key.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `crates/hypercube/src/verifier/shard.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `crates/primitives/src/lib.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `crates/prover/src/recursion.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `crates/recursion/executor/src/public_values.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `DECENTRALIZATION-2ND-CLIENT-RUNBOOK.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `deployments/compute-market-e2e.json` cited in: aere-docs/AERE-COMPUTE-MARKET-V3.md
|
||||
- `docs/AERE-EIP-COMPATIBILITY-MATRIX.md` cited in: aere-docs/AERE-DEPLOY-RUNBOOK-SUMMARY.md, aere-docs/AERE-ENTROPY-BEACON-FIX.md
|
||||
- `docs/AERE-PQ-AGGREGATE.md` cited in: aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md
|
||||
- `docs/AERE-PQ-FINALITY-CERTIFICATE.md` cited in: aere-docs/AERE-NEW-CONTRACTS-DEPLOY-RUNBOOK.md
|
||||
- `docs/AERE-SECURITY-REVIEW-NEW-CONTRACTS.md` cited in: aere-docs/AERE-DEPLOY-RUNBOOK-SUMMARY.md
|
||||
- `docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `docs/AERE-STARK-VERIFIER-PORT-SPEC.md` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-MMCS-SUMMARY.md, aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md, aere-docs/AERE-STARK-TRANSCRIPT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `docs/PQ-STARK-VERIFIER-ACTIVATION-2026-07-18.md` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `docs/PQ-STARK-VERIFIER-PRECOMPILE-2026-07-18.md` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `domain.rs` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `duplex_challenger.rs` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `ethers.js` cited in: aere-docs/AERE-QUANTUM-SAFE-NETWORKING.md
|
||||
- `falcon1024.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `falcon512.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `FAULT-TOLERANCE-CHARACTERIZATION-2026-07-14.md` cited in: aere-docs/AERE-ENGINEERING-SECURITY-SPEC.md
|
||||
- `folder.rs` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `foundry.toml` cited in: aere-docs/REPRODUCE.md
|
||||
- `FRONTIER-PROGRAM-2026-07-12.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `genesis-subsecond.json` cited in: aere-docs/AERE-BENCHMARK-REPORT.md
|
||||
- `GITHUB_DEPLOYMENT_CHECKLIST.md` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `GOVERNANCE.md` cited in: aere-docs/AERE-POST-QUANTUM-GOVERNANCE.md
|
||||
- `grinding_challenger.rs` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `harness/DummyERC20A.sol` cited in: aere-docs/AERE-CERTORA-FORMAL-VERIFICATION.md
|
||||
- `hypercube-verifier/crates/stark/folder.rs` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `interfaces/draft-IERC7579.sol` cited in: aere-docs/AERE-PQ-AGGREGATE.md
|
||||
- `LAST-SHARD-ONLY-NOT-THE-COVERAGE-NUMBER.json` cited in: aere-docs/REPRODUCE.md
|
||||
- `lib/attest-recovery.js` cited in: aere-docs/AERE-FAULT-INJECTION-HARNESS.md
|
||||
- `lib/migrate.js` cited in: aere-docs/AERE-MIGRATION-TOOLKIT.md
|
||||
- `lib/partition.sh` cited in: aere-docs/AERE-FAULT-INJECTION-HARNESS.md
|
||||
- `LondonFeeMarket.java` cited in: aere-docs/AERE-PROTOCOL-SPECIFICATION.md
|
||||
- `matrix.json` cited in: aere-docs/AERE-FAULT-INJECTION-HARNESS.md
|
||||
- `merge-shards.js` cited in: aere-docs/REPRODUCE.md
|
||||
- `mldsa44.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `mmcs.rs` cited in: aere-docs/AERE-STARK-MMCS-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `NETHERMIND-2ND-CLIENT-LIVE-2026-07-17.md` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `nist_kat_bc183.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `node_modules/hardhat/internal/hardhat-network/provider/provider.js` cited in: aere-docs/REPRODUCE.md
|
||||
- `plan.js` cited in: aere-docs/AERE-MIGRATION-TOOLKIT.md
|
||||
- `PQ-CONSENSUS-LIVE-READINESS-2026-07-18.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `pqc-fork/pq-stark/air_quotient_ground_truth.json` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/air_quotient_reference.py` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/babybear_field_reference.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/challenger_ground_truth.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/challenger_reference.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/export-inner-stark-vector.md` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/fri_ground_truth.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/fri_query_index_reference.mjs` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/fri_query_index_reference.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/fri_verify_reference.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/FriQueryIndexSelfTest.java` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/mmcs_babybear_reference.py` cited in: aere-docs/AERE-STARK-MMCS-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/poseidon2_babybear_reference.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/README.md` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-MMCS-SUMMARY.md, aere-docs/AERE-STARK-TRANSCRIPT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/spec-fri-babybear.md` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/spec-mmcs-babybear.md` cited in: aere-docs/AERE-STARK-MMCS-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/spec-poseidon2-constants.md` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/test_air_quotient.py` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md
|
||||
- `pqc-fork/pq-stark/test_babybear_field.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/test_challenger.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/test_fri_query_index.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/test_fri_verify.py` cited in: aere-docs/AERE-STARK-TRANSCRIPT-SUMMARY.md
|
||||
- `pqc-fork/pq-stark/test_mmcs_babybear.py` cited in: aere-docs/AERE-STARK-MMCS-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/pq-stark/test_poseidon2_babybear.py` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-MMCS-SUMMARY.md, aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md, aere-docs/AERE-STARK-TRANSCRIPT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/results/kat-results-air-quotient.json` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/results/kat-results-babybear-field.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/results/kat-results-challenger.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/results/kat-results-fri-query-index.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/results/kat-results-fri-verify.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/results/kat-results-mmcs-babybear.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc-fork/results/kat-results-poseidon2-babybear.json` cited in: aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `pqc/AereAccountRetirement.sol` cited in: aere-docs/AERE-QUANTUM-MIGRATION.md
|
||||
- `precompile` cited in: aere-docs/REPRODUCE.md
|
||||
- `Probe.java` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `proofs/mixed-client/follower-sync/REGRESSION-n4.txt` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `proofs/qbft-producer-besu-import-proof-2026-07-13.txt` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `proofs/qbft-producer-manifest-2026-07-13.json` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `reproducible-besu-build.yml` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `REPRODUCIBLE.md` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `rollup-evm-validity/guest/Cargo.toml` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `rollup-evm-validity/host/Cargo.lock` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `rollup-evm-validity/host/Cargo.toml` cited in: aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
|
||||
- `run_kat.sh` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `run-chaos-matrix.sh` cited in: aere-docs/AERE-FAULT-INJECTION-HARNESS.md
|
||||
- `run-kats.sh` cited in: aere-docs/REPRODUCE.md
|
||||
- `runner.mjs` cited in: aere-docs/AERE-CROSS-CLIENT-DETERMINISM.md
|
||||
- `scan.js` cited in: aere-docs/AERE-MIGRATION-TOOLKIT.md
|
||||
- `scripts/coverage/list-test-cases.js` cited in: aere-docs/REPRODUCE.md
|
||||
- `scripts/coverage/tree-fingerprint.js` cited in: aere-docs/REPRODUCE.md
|
||||
- `scripts/run-tests-sharded.js` cited in: aere-docs/REPRODUCE.md
|
||||
- `sdk-js/src/addresses.ts` cited in: aere-docs/AERE-AIP-PROCESS-AND-INDEX.md, aere-docs/AERE-DEPLOY-RUNBOOK-SUMMARY.md, aere-docs/AERE-POST-QUANTUM-GOVERNANCE.md, aere-docs/AERE-PROTOCOL-SPECIFICATION.md, aere-docs/AERE-REPRODUCIBLE-BUILDS.md, aere-docs/AIP-PQ-TX-2026-07-18.md
|
||||
- `SECURITY-POSTURE-VERIFICATION-2026-07-15.md` cited in: aere-docs/AERE-CERTORA-FORMAL-VERIFICATION.md
|
||||
- `shadow-producer.mjs` cited in: aere-docs/AERE-SHADOW-PRODUCER.md
|
||||
- `shake256.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `shards/shard-NNN.partial-istanbul.json` cited in: aere-docs/REPRODUCE.md
|
||||
- `simulate.js` cited in: aere-docs/AERE-MIGRATION-TOOLKIT.md
|
||||
- `slhdsa128s.txt` cited in: aere-docs/AERE-NIST-VALIDATION-STATUS.md
|
||||
- `test/AereComputeMarketV3.liveness.test.js` cited in: aere-docs/AERE-COMPUTE-MARKET-V3.md
|
||||
- `test/formal/ForgePropertyFuzz.t.sol` cited in: aere-docs/REPRODUCE.md
|
||||
- `tests/fib_air.rs` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `tests/mul_air.rs` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `unmeasurable.txt` cited in: aere-docs/REPRODUCE.md
|
||||
- `VALIDITY-ROLLUP-SEQUENCER-PLAN.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `verifier.rs` cited in: aere-docs/AERE-STARK-AIR-QUOTIENT-SUMMARY.md, aere-docs/AERE-STARK-VERIFIER-PORT-SPEC.md
|
||||
- `verify-besu-image.sh` cited in: aere-docs/AERE-REPRODUCIBLE-BUILDS.md
|
||||
- `WHITEPAPER-V2.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `wp2-sections/02-architecture.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `wp2-sections/04-zk.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `ZK-ANCHOR-FIXES-2026-07-17.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
- `ZK-PQ-FINALITY-2026-07-18.md` cited in: aere-docs/AERE-STARK-DOC-CAVEAT-SWEEP.md
|
||||
440
DOVADA-PQC-VERIFICABILA-2026-07-20.md
Normal file
440
DOVADA-PQC-VERIFICABILA-2026-07-20.md
Normal file
@ -0,0 +1,440 @@
|
||||
# Dovada PQC verificabila. Tested commands and real output
|
||||
|
||||
**Date:** 2026-07-20
|
||||
**Chain:** AERE mainnet, chain ID 2800 (`0xaf0`)
|
||||
**Endpoints used:** `https://rpc.aere.network` and `https://rpc2.aere.network`
|
||||
**Head at time of measurement:** 10,615,742 rising to 10,617,158 during the run
|
||||
|
||||
Every command below was executed against the live public RPC before being written down. Output is
|
||||
pasted verbatim. Where something did not verify, this document says so explicitly.
|
||||
|
||||
---
|
||||
|
||||
## 0. The problem this document fixes
|
||||
|
||||
We publish "the post-quantum precompiles activated at block 9,189,161" and invite the reader to check
|
||||
it. A stranger who follows that pointer finds an **empty block**. The activation is real, the number
|
||||
is correct, but the pointer is useless as evidence, because the activation was a fork configuration
|
||||
change and not a transaction. There is no artifact in that block to look at.
|
||||
|
||||
The number stays. The evidence changes.
|
||||
|
||||
---
|
||||
|
||||
## 1. Confirmed: block 9,189,161 is empty, on both endpoints
|
||||
|
||||
```bash
|
||||
curl -s -X POST https://rpc.aere.network -H 'content-type: application/json' \
|
||||
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["0x8c3729",false]}'
|
||||
```
|
||||
|
||||
`0x8c3729` is 9,189,161. Measured, both endpoints, identical:
|
||||
|
||||
| Block | Timestamp | Tx count | gasUsed | Hash |
|
||||
|---|---|---|---|---|
|
||||
| 9,189,160 | 1783820271 | 0 | `0x0` | `0x6ecfa50257f2de5953d22baa27843ce55fd09a3f26adbc060264b97f09ee804a` |
|
||||
| **9,189,161** | **1783820272** | **0** | `0x0` | `0x3cb61a23dfc7065cce44fb62108a36bb3f4147bb851ddd9bdec374eba4a337cf` |
|
||||
| 9,189,162 | 1783820272 | 0 | `0x0` | `0x999acabe0c2add28977ab78ccf2f8f16b245a2e110d5934ddedabe14d11a0aa4` |
|
||||
|
||||
`rpc.aere.network` and `rpc2.aere.network` returned byte-identical hashes for all three blocks.
|
||||
|
||||
**The finding is confirmed.** Block 9,189,161 contains zero transactions. Pointing a reader at
|
||||
`explorer.aere.network/block/9189161` as proof of the activation hands a critic a working
|
||||
counterexample.
|
||||
|
||||
---
|
||||
|
||||
## 2. What survives as evidence. Four candidates, all tested
|
||||
|
||||
### 2.1 `eth_config`. SOLID, and the single best artifact
|
||||
|
||||
This was not used anywhere in our public copy. It is the strongest and simplest proof, because the
|
||||
live node states the activation time and the active precompile set in one call, at `latest`, with no
|
||||
historical state involved.
|
||||
|
||||
```bash
|
||||
curl -s -X POST https://rpc.aere.network -H 'content-type: application/json' \
|
||||
-d '{"jsonrpc":"2.0","id":1,"method":"eth_config","params":[]}'
|
||||
```
|
||||
|
||||
Real output, abbreviated to the relevant fields, **identical on both endpoints**:
|
||||
|
||||
```json
|
||||
{ "result": { "current": {
|
||||
"activationTime": 1783820272,
|
||||
"chainId": "0xaf0",
|
||||
"forkId": "0xce69e400",
|
||||
"precompiles": {
|
||||
"AereFalcon512": "0x0000000000000000000000000000000000000ae1",
|
||||
"AereFalcon1024": "0x0000000000000000000000000000000000000ae2",
|
||||
"AereMLDSA44": "0x0000000000000000000000000000000000000ae3",
|
||||
"AereSLHDSA128s": "0x0000000000000000000000000000000000000ae4",
|
||||
"AereSHAKE256": "0x0000000000000000000000000000000000000ae5",
|
||||
"P256VERIFY": "0x0000000000000000000000000000000000000100",
|
||||
"ECREC": "0x...01", "SHA256": "0x...02", "RIPEMD160": "0x...03", "ID": "0x...04",
|
||||
"MODEXP": "0x...05", "BN254_ADD": "0x...06", "BN254_MUL": "0x...07",
|
||||
"BN254_PAIRING": "0x...08", "BLAKE2F": "0x...09", "KZG_POINT_EVALUATION": "0x...0a",
|
||||
"BLS12_G1ADD": "0x...0b", "BLS12_G1MSM": "0x...0c", "BLS12_G2ADD": "0x...0d",
|
||||
"BLS12_G2MSM": "0x...0e", "BLS12_PAIRING_CHECK": "0x...0f",
|
||||
"BLS12_MAP_FP_TO_G1": "0x...10", "BLS12_MAP_FP2_TO_G2": "0x...11"
|
||||
},
|
||||
"systemContracts": {
|
||||
"BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02",
|
||||
"HISTORY_STORAGE_ADDRESS":"0x0000f90827f1c53a10cb7a02335b175320002935"
|
||||
}
|
||||
}, "next": null, "last": null } }
|
||||
```
|
||||
|
||||
Two things this proves at once:
|
||||
|
||||
1. `activationTime` is **1783820272**, which is exactly the timestamp of block 9,189,161 in section 1.
|
||||
2. The active precompile set contains **exactly five** Aere entries, `0x0AE1` through `0x0AE5`.
|
||||
**`0x0AE6` and `0x0AE7` are not in the list.** The live node itself confirms they are not on
|
||||
mainnet.
|
||||
|
||||
### 2.2 First block at or after `activationTime`. SOLID
|
||||
|
||||
The link from the timestamp to the block number is a binary search over header timestamps. Headers
|
||||
are full history, so this works at any depth and needs no state.
|
||||
|
||||
```bash
|
||||
# 23 eth_getBlockByNumber calls, binary search for the first block with timestamp >= 1783820272
|
||||
```
|
||||
|
||||
Real output:
|
||||
|
||||
```
|
||||
binary search for first block with timestamp >= 1783820272
|
||||
result block : 9189161 (23 rpc calls)
|
||||
ts(block) : 1783820272
|
||||
ts(block-1) : 1783820271
|
||||
matches claim 9189161: True
|
||||
```
|
||||
|
||||
**This is what makes the published number defensible.** 9,189,161 is not an assertion taken from a
|
||||
config file that the reader must trust. It is the block the reader derives themselves from
|
||||
`activationTime`, which the node publishes. The block is empty, and that is expected and fine, because
|
||||
its significance is its **timestamp**, not its contents.
|
||||
|
||||
### 2.3 Attestation receipt at block 9,200,532. SOLID
|
||||
|
||||
Receipts and logs are full history and are unaffected by the 512-block state window.
|
||||
|
||||
```bash
|
||||
curl -s -X POST https://rpc.aere.network -H 'content-type: application/json' \
|
||||
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionReceipt","params":["0xcd1350372f0a61e26e8a3228da599be9211839f378eef0ea49f2025a20920660"],"id":1}'
|
||||
```
|
||||
|
||||
Measured:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Status | `0x1` (success) |
|
||||
| Block | 9,200,532 |
|
||||
| Block hash | `0x719402887c204b4e6674a34911259ead10986efa744b550b209ea571d986a88a` |
|
||||
| To | `0x465d9e3b476bf98aa1393079e240db5d2a9bea6a` (`AerePQCAttestation`) |
|
||||
| Gas used | 1,386,367 |
|
||||
| Logs | 1, topic0 `0x8cf3c7a52148b21f2af90768d73b55c8115c55af53d5d36f5c14b39108789648` |
|
||||
|
||||
Why a successful receipt is proof. `AerePQCAttestation.attest()` reverts unless the precompile
|
||||
returns a 32-byte word ending in `0x01`. A `staticcall` to an address with **no** precompile succeeds
|
||||
with **empty** return data, which fails the `ret.length >= 32` check, which reverts the transaction.
|
||||
A recorded status `0x1` therefore cannot happen on a chain where the precompile is absent.
|
||||
|
||||
Corroboration, measured at `latest`: the contract runtime bytecode is 4,402 bytes and contains
|
||||
references to `0x0AE1`, `0x0AE2`, `0x0AE3` and `0x0AE4`.
|
||||
|
||||
### 2.4 Live gas differential at `latest`. SOLID, and the strongest live proof
|
||||
|
||||
Full method and results in section 3.
|
||||
|
||||
### 2.5 What did NOT work, stated explicitly
|
||||
|
||||
- `eth_call` to `0x0AE1` **at block 9,189,161** returns `-32603 Internal error`. Historical state is
|
||||
pruned. Do not put this in any instruction.
|
||||
- `eth_getCode` / `eth_getBalance` / `eth_getStorageAt` at that height return `null`. Same reason.
|
||||
- The **return-value test** ("live returns a 32-byte word, absent returns `0x`") is **not sound** and
|
||||
must not be published as the liveness proof. See section 3.1.
|
||||
|
||||
---
|
||||
|
||||
## 3. The gas differential, done correctly
|
||||
|
||||
### 3.1 Why the previous attempt recorded a bad proof
|
||||
|
||||
A previous run concluded `0x0AE6` and `0x0AE7` were "not live" because they "returned empty `0x`".
|
||||
That reasoning is invalid. A live precompile that rejects malformed input can also return empty, and
|
||||
a **codeless address returns empty while reporting success**, so the two cases are indistinguishable
|
||||
from the return value alone.
|
||||
|
||||
Measured demonstration:
|
||||
|
||||
```
|
||||
0x0AE1 (LIVE, garbage input) -> 0x0000...0000 (32-byte zero word)
|
||||
0x0AE6 (ABSENT) -> 0x
|
||||
0xdead (codeless control) -> 0x
|
||||
```
|
||||
|
||||
In this particular instance `0x0AE1` happens to return a zero word rather than empty, so the test
|
||||
appears to work. That is incidental to how this one precompile handles malformed input. It is not a
|
||||
general discriminator, and the conclusion must not rest on it. **Gas is the sound discriminator**,
|
||||
because a codeless address consumes zero execution gas and a live precompile cannot.
|
||||
|
||||
### 3.2 The method
|
||||
|
||||
Deploy a probe via `eth_call` state override. The probe reads `GAS`, performs a `CALL` to the target,
|
||||
reads `GAS` again, and returns the difference. Two corrections matter and were both applied:
|
||||
|
||||
1. **Pre-expand memory** before the first `GAS` reading, with `MSTORE(0xA000, 0)`. Without this, the
|
||||
`CALL`'s memory expansion charge (about 7,040 gas) lands inside the measurement and varies with
|
||||
input length, which swamps the signal.
|
||||
2. **Pre-warm the target address** with a throwaway `CALL` before the first `GAS` reading. Without
|
||||
this, EIP-2929 charges 2,600 for a cold address and 100 for a warm one. Standard precompiles are
|
||||
pre-warmed and an arbitrary control address is not, which produces a false **negative** delta.
|
||||
|
||||
The measured value is then `target_cost - control_cost`, which is pure execution gas.
|
||||
|
||||
Probe bytecode, for target `T` (20 bytes, no `0x`):
|
||||
|
||||
```
|
||||
0x366000600037 6000 61a000 52 6000600060006000600073<T>612710f150
|
||||
5a 612000 618000 36 6000 6000 73<T> 6305f5e100 f1 50 5a 90 03 600052 60206000f3
|
||||
```
|
||||
|
||||
Copy-pasteable form, Falcon-512 at `0x0AE1`:
|
||||
|
||||
```bash
|
||||
curl -s -X POST https://rpc.aere.network -H 'content-type: application/json' -d '{
|
||||
"jsonrpc":"2.0","id":1,"method":"eth_call","params":[
|
||||
{"to":"0x000000000000000000000000000000000000b0b0",
|
||||
"data":"0x3333333333333333333333333333333333333333333333333333333333333333",
|
||||
"gas":"0x1c9c380"},
|
||||
"latest",
|
||||
{"0x000000000000000000000000000000000000b0b0":{"code":"0x366000600037600061a0005260006000600060006000730000000000000000000000000000000000000ae1612710f1505a6120006180003660006000730000000000000000000000000000000000000ae16305f5e100f1505a900360005260206000f3"}}]}'
|
||||
```
|
||||
|
||||
Swap the two occurrences of `0000000000000000000000000000000000000ae1` for any other address to
|
||||
measure that address. Use `000000000000000000000000000000000000dead` as the codeless control.
|
||||
|
||||
### 3.3 Calibration. Run this FIRST, before trusting any number
|
||||
|
||||
The IDENTITY precompile at `0x04` costs exactly `15 + 3*ceil(len/32)`. If the probe does not
|
||||
reproduce that formula, the probe is wrong and every other number from it is worthless.
|
||||
|
||||
Real output:
|
||||
|
||||
```
|
||||
CALIBRATION: IDENTITY 0x04, expected = 15 + 3*ceil(len/32)
|
||||
len raw(0x04) raw(ctrl) measured expected
|
||||
32 142 124 18 18 MATCH
|
||||
320 169 124 45 45 MATCH
|
||||
1024 235 124 111 111 MATCH
|
||||
4096 523 124 399 399 MATCH
|
||||
|
||||
calibration PASSED
|
||||
```
|
||||
|
||||
Second calibration on SHA256 at `0x02`, which costs `60 + 12*ceil(len/32)`:
|
||||
|
||||
```
|
||||
len=32 measured=72 expected=72
|
||||
len=320 measured=180 expected=180
|
||||
```
|
||||
|
||||
Both calibrations are exact at every length tested. The probe is trustworthy.
|
||||
|
||||
### 3.4 Results, measured at block 10,615,742 at `latest`
|
||||
|
||||
Input `0x33` repeated, at three lengths, on `rpc.aere.network`:
|
||||
|
||||
| Precompile | len=32 | len=1024 | len=2048 | Verdict |
|
||||
|---|---|---|---|---|
|
||||
| `0x0AE1` Falcon-512 | 40,000 | 40,000 | 40,000 | **LIVE** |
|
||||
| `0x0AE2` Falcon-1024 | 75,000 | 75,000 | 75,000 | **LIVE** |
|
||||
| `0x0AE3` ML-DSA-44 | 55,000 | 55,000 | 55,000 | **LIVE** |
|
||||
| `0x0AE4` SLH-DSA-128s | 350,000 | 350,000 | 350,000 | **LIVE** |
|
||||
| `0x0AE5` SHAKE256 | 24,636 | 25,008 | 25,392 | **LIVE** (length dependent) |
|
||||
| `0x0AE6` ML-KEM-768 | 0 | 0 | 0 | **ABSENT**, identical to codeless control |
|
||||
| `0x0AE7` Falcon HashToPoint | 0 | 0 | 0 | **ABSENT**, identical to codeless control |
|
||||
|
||||
Independently reproduced on `rpc2.aere.network`, identical values: 40,000 / 75,000 / 55,000 /
|
||||
350,000 / 24,636 / 0 / 0.
|
||||
|
||||
### 3.5 Cross-check against the node source. Independent corroboration
|
||||
|
||||
The measured constants match the gas schedule in
|
||||
`aere-node/patches/0001-aere-pqc-precompiles-mainnet.patch`:
|
||||
|
||||
```
|
||||
line 279: private static final long GAS = 40_000L; // Falcon-512 0x0AE1
|
||||
line 211: private static final long GAS = 75_000L; // Falcon-1024 0x0AE2
|
||||
line 352: private static final long GAS = 55_000L; // ML-DSA-44 0x0AE3
|
||||
line 562: private static final long GAS = 350_000L; // SLH-DSA-128s 0x0AE4
|
||||
line 460: static final int MAX_OUTPUT = 1 << 16; // SHAKE256 0x0AE5
|
||||
line 462: private static final int BASE_GAS = 60;
|
||||
line 463: private static final int GAS_PER_WORD = 12;
|
||||
```
|
||||
|
||||
SHAKE256 is `BASE_GAS + GAS_PER_WORD * (ceil(dataLen/32) + ceil(outLen/32))`. The `0x33`-filled input
|
||||
above encodes a huge output length, which the contract caps at `MAX_OUTPUT` = 65,536 = 2,048 words,
|
||||
giving `60 + 12*2048 = 24,636`, exactly the measured value.
|
||||
|
||||
Verified with well-formed inputs, `outLen` as a 32-byte big-endian prefix:
|
||||
|
||||
```
|
||||
outLen=32 dataLen=32 measured=84 expected=84 MATCH
|
||||
outLen=32 dataLen=1024 measured=456 expected=456 MATCH
|
||||
outLen=64 dataLen=0 measured=84 expected=84 MATCH
|
||||
outLen=256 dataLen=256 measured=252 expected=252 MATCH
|
||||
```
|
||||
|
||||
**On-chain measured gas equals the published source constants.** This is the corroboration that makes
|
||||
the live proof self-contained: a stranger measures the gas, reads the source, and the two agree.
|
||||
|
||||
### 3.6 Correction to the previously recorded numbers
|
||||
|
||||
Prior record: control 23,897; `0x0AE1` 62,853; `0x0AE2` 97,992; `0x0AE3` 77,913; `0x0AE4` 376,144;
|
||||
`0x0AE5` 47,055; `0x0AE6` and `0x0AE7` both 23,897.
|
||||
|
||||
Those absolutes were **whole-call totals**, including the 21,000 intrinsic transaction cost, calldata
|
||||
cost and probe overhead. They are not precompile execution costs. A separate review recorded a
|
||||
control of 61,825, different again, for the same reason. Subtracting each run's own control gets
|
||||
close to the true values but not exactly, because the overhead does not cancel cleanly.
|
||||
|
||||
**Corrected:** the execution costs are 40,000 / 75,000 / 55,000 / 350,000 and
|
||||
`60 + 12*words` for SHAKE256. These are round numbers because they are literal constants in the
|
||||
client, and they now match the source line for line.
|
||||
|
||||
**Confirmed unchanged:** the conclusion that `0x0AE6` and `0x0AE7` are absent on mainnet. They
|
||||
measure exactly the codeless control in both the old run and this one, and `eth_config` independently
|
||||
omits them from the precompile list. Two independent methods agree.
|
||||
|
||||
---
|
||||
|
||||
## 4. Why this document does not reconstruct block hashes
|
||||
|
||||
A proposed replacement wording instructed the reader to re-encode `extraData` with the seals list
|
||||
emptied and the round set to zero, and to recover each committed seal by ECDSA. As written it would
|
||||
fail at block 1, and it is not needed for the PQC claim. Measured header field sets:
|
||||
|
||||
| Block | Optional header fields present |
|
||||
|---|---|
|
||||
| 1 | `baseFeePerGas`, `withdrawalsRoot` (**2 fields**) |
|
||||
| 9,189,161 | `baseFeePerGas`, `withdrawalsRoot`, `blobGasUsed`, `excessBlobGas`, `parentBeaconBlockRoot`, `requestsHash` (**6 fields**) |
|
||||
| latest | same 6 fields |
|
||||
|
||||
`extraData` is also 238 bytes at blocks 1 and 9,189,161 but 525 bytes at `latest`, because the
|
||||
validator set grew and the seal list with it. Any instruction that hardcodes one field set or one
|
||||
`extraData` layout breaks on the other era.
|
||||
|
||||
**Header reconstruction is a real capability and it does work**, at 2 fields for pre-Pectra blocks and
|
||||
6 for post-Pectra blocks. It is simply the wrong tool for proving precompile activation, and it adds
|
||||
a large failure surface to an instruction that does not need it. It is out of scope here and should
|
||||
be documented separately, with the field count stated per era and tested at both eras.
|
||||
|
||||
---
|
||||
|
||||
## 5. The corrected instruction, for publication
|
||||
|
||||
> ### Verify the post-quantum precompiles yourself
|
||||
>
|
||||
> No wallet, no gas, no account. Two commands.
|
||||
>
|
||||
> **1. Ask the network what is active.**
|
||||
>
|
||||
> ```bash
|
||||
> curl -s -X POST https://rpc.aere.network -H 'content-type: application/json' \
|
||||
> -d '{"jsonrpc":"2.0","id":1,"method":"eth_config","params":[]}'
|
||||
> ```
|
||||
>
|
||||
> The response lists `activationTime: 1783820272` and the five Aere precompiles at `0x0AE1` through
|
||||
> `0x0AE5`. Block 9,189,161 is the first block whose timestamp is at or after that activation time,
|
||||
> which you can confirm by binary search over `eth_getBlockByNumber` timestamps. That block contains
|
||||
> no transactions, because the activation was a fork configuration change and not a transaction. Its
|
||||
> significance is its timestamp, not its contents. Repeat against `https://rpc2.aere.network` for an
|
||||
> independent second endpoint.
|
||||
>
|
||||
> **2. Prove they are executing right now, by measuring gas.**
|
||||
>
|
||||
> A live precompile consumes gas. An address with nothing at it consumes none. Return values do not
|
||||
> settle this, because an empty address returns empty data and reports success. Gas does.
|
||||
>
|
||||
> The command in section 3.2 deploys a throwaway measuring probe via `eth_call` state override and
|
||||
> returns the gas consumed by one call to the target. Calibrate it first against the IDENTITY
|
||||
> precompile at `0x04`, whose cost is fixed by the EVM specification at `15 + 3*ceil(len/32)`. For a
|
||||
> 32-byte input it must read exactly 18 more than the codeless control. Then measure:
|
||||
>
|
||||
> | Address | Measured gas above control | Meaning |
|
||||
> |---|---|---|
|
||||
> | `0x04` IDENTITY | 18 | calibration, matches the EVM spec |
|
||||
> | `0x0AE1` Falcon-512 | 40,000 | live |
|
||||
> | `0x0AE2` Falcon-1024 | 75,000 | live |
|
||||
> | `0x0AE3` ML-DSA-44 | 55,000 | live |
|
||||
> | `0x0AE4` SLH-DSA-128s | 350,000 | live |
|
||||
> | `0x0AE5` SHAKE256 | 60 + 12 per word | live |
|
||||
> | `0x0AE6`, `0x0AE7` | 0 | **not on mainnet**, testnet only |
|
||||
>
|
||||
> Those constants are in the client source, so your measurement and our published code can be
|
||||
> compared directly.
|
||||
>
|
||||
> **Optional, to check the past.** Historical account state is pruned after 512 blocks, so a
|
||||
> historical `eth_call` will not work. Receipts are kept in full. Receipt
|
||||
> `0xcd1350372f0a61e26e8a3228da599be9211839f378eef0ea49f2025a20920660` is a successful post-quantum
|
||||
> attestation at block 9,200,532, status `0x1`, 1,386,367 gas. That contract reverts unless the
|
||||
> precompile returns a valid result, so a successful receipt could not exist on a chain without the
|
||||
> precompile.
|
||||
>
|
||||
> **Scope, stated plainly.** Post-quantum **signature verification** is live on mainnet at the
|
||||
> execution layer, and any contract can require it. AERE **consensus remains classical secp256k1
|
||||
> ECDSA under QBFT** and is not post-quantum. Hybrid post-quantum consensus exists only on an
|
||||
> isolated testnet and is audit-gated. `0x0AE6` and `0x0AE7` are testnet only.
|
||||
|
||||
---
|
||||
|
||||
## 6. Provable and not provable
|
||||
|
||||
**Provable today, by a stranger, measured above:**
|
||||
|
||||
- Five NIST post-quantum precompiles execute on mainnet right now, at `0x0AE1` to `0x0AE5`, with gas
|
||||
costs matching published source constants.
|
||||
- The fork activation time is 1783820272 and block 9,189,161 is the first block at or after it.
|
||||
- Post-quantum signature verification recorded successfully on-chain at block 9,200,532.
|
||||
- `0x0AE6` and `0x0AE7` are **not** active on mainnet, by two independent methods.
|
||||
- Both public endpoints agree on every value in this document.
|
||||
|
||||
**Not provable, and must never be claimed:**
|
||||
|
||||
- **Consensus is not post-quantum.** It is classical secp256k1 ECDSA under Hyperledger Besu QBFT.
|
||||
- The activation height cannot be proven from block *contents*, only from the activation timestamp
|
||||
plus header timestamps. The block is empty and always will be.
|
||||
- Historical account state before the 512-block window cannot be queried. `eth_getBalance` returns
|
||||
`null` and `eth_getTransactionCount` returns a false `0x0` rather than erroring.
|
||||
|
||||
**Not verified in this pass, stated so it is not mistaken for verified:**
|
||||
|
||||
- I did not read the live QBFT `transitions` configuration on the validators. `activationTime` came
|
||||
from the `eth_config` RPC response, not from a node config file.
|
||||
- I did not re-verify the NIST KAT vector replay on `quantum.html`. A prior review recorded 27/27
|
||||
passing; I did not independently rerun it.
|
||||
- I did not verify the sub-second transition block number. That is a separate open finding.
|
||||
|
||||
---
|
||||
|
||||
## 7. Infrastructure safety
|
||||
|
||||
No transaction was sent, no contract deployed, no node touched, no configuration changed. All calls
|
||||
were read-only JSON-RPC (`eth_blockNumber`, `eth_chainId`, `eth_getBlockByNumber`,
|
||||
`eth_getTransactionReceipt`, `eth_getCode`, `eth_call`, `eth_config`). The `eth_call` state overrides
|
||||
are simulation-only and write nothing.
|
||||
|
||||
RPC health measured after all activity:
|
||||
|
||||
```
|
||||
rpc.aere.network attempt 1: 381 ms {"result":"0xa1fd42"}
|
||||
rpc.aere.network attempt 2: 371 ms {"result":"0xa1fd43"}
|
||||
rpc.aere.network attempt 3: 437 ms {"result":"0xa1fd44"}
|
||||
rpc2.aere.network attempt 1: 459 ms {"result":"0xa1fd45"}
|
||||
rpc2.aere.network attempt 2: 444 ms {"result":"0xa1fd46"}
|
||||
```
|
||||
|
||||
All responses well under one second, block height advancing normally.
|
||||
9
LICENSE
9
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 AERE Network
|
||||
Copyright (c) 2026 AERE Network
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -19,3 +19,10 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
PER-FILE EXCEPTIONS
|
||||
|
||||
The grant above is the default for this repository. Individual files that carry
|
||||
their own SPDX-License-Identifier header are governed by that header, not by the
|
||||
grant above. Every exception in this repository is listed in LICENSING.md.
|
||||
|
||||
21
LICENSING.md
Normal file
21
LICENSING.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Licensing
|
||||
|
||||
Default for this repository: **MIT**, `Copyright (c) 2026 AERE Network`. See `LICENSE`.
|
||||
|
||||
This repository is documentation. No file in it carries an `SPDX-License-Identifier` header, so the
|
||||
default covers everything, with one recorded exception.
|
||||
|
||||
## Improvement proposals — CC0
|
||||
|
||||
Two documents end with:
|
||||
|
||||
> Released to the public domain (CC0). No rights reserved.
|
||||
|
||||
| File |
|
||||
| --- |
|
||||
| `AERE-AIP-PROCESS-AND-INDEX.md` |
|
||||
| `AIP-PQ-TX-2026-07-18.md` |
|
||||
|
||||
That dedication stands. It follows the convention Ethereum uses for EIPs. CC0 is a wider grant than
|
||||
MIT, so it takes nothing away from a reader of `LICENSE`; it is recorded here so that a reader who
|
||||
sees only `LICENSE` knows these two documents are freer than the rest.
|
||||
52
README.md
52
README.md
@ -12,8 +12,14 @@ cross-client determinism documents, and the reproducibility manifest.
|
||||
|
||||
Aere Network runs post-quantum signature verification natively on mainnet: Falcon-512 (`0x0AE1`),
|
||||
Falcon-1024 (`0x0AE2`), ML-DSA-44 (`0x0AE3`), SLH-DSA-128s (`0x0AE4`) and SHAKE256 (`0x0AE5`)
|
||||
have been live as precompiles since block 9,189,161. You can call them yourself against
|
||||
`https://rpc.aere.network` without asking us for anything.
|
||||
have been live as precompiles since the AerePQC fork, `activationTime` 1783820272, whose first
|
||||
block at or after that timestamp is 9,189,161. You can call them yourself against
|
||||
`https://rpc.aere.network` without asking us for anything. Start with
|
||||
`{"jsonrpc":"2.0","id":1,"method":"eth_config","params":[]}`, which returns that activation time and
|
||||
the live precompile list straight from the node. Note that block 9,189,161 itself contains no
|
||||
transactions, because a fork activation is a configuration change and not a transaction, so it is
|
||||
not the place to look for evidence. The proof that the precompiles are running is a gas measurement
|
||||
at `latest`, set out in `DOVADA-PQC-VERIFICABILA-2026-07-20.md`.
|
||||
|
||||
**Consensus on chain 2800 is classical secp256k1 ECDSA QBFT.** The post-quantum work lives at the
|
||||
signature, precompile, account and transport layers. Nothing in this repository makes the consensus
|
||||
@ -32,6 +38,48 @@ The network is operated by seven Foundation-run validators, so its Nakamoto coef
|
||||
effectively one today. That is a real limitation, it is on the roadmap, and it is not fixed by any
|
||||
code in this repository.
|
||||
|
||||
## Which citations you can follow, and which you cannot
|
||||
|
||||
Read this before you try to follow a citation, because it limits the "verify yourself" promise and
|
||||
you should hear it from us rather than discover it.
|
||||
|
||||
**How a citation resolves.** Paths are written relative to a side-by-side checkout of the published
|
||||
Aere repositories, so a resolvable path begins with a repository name, for example
|
||||
`aere-contracts/contracts/pqc/AereCryptoRegistry.sol`. Paths written relative to the document you
|
||||
are reading also resolve. Nothing else does.
|
||||
|
||||
**What was wrong until 2026-08-03.** Many documents supported a claim with a path beginning
|
||||
`aerenew/`, which is the larger private working tree these repositories were split out of. An
|
||||
earlier version of this section stated that there were 270 such paths and that none of them resolved
|
||||
in any public repository. The second half of that was wrong, and wrong in the direction that
|
||||
understated us: MEASURED on 2026-08-03, 228 of those citations named a file that **is** published,
|
||||
merely under its private path. They have been rewritten to the published path and you can now open
|
||||
them. No citation was deleted.
|
||||
|
||||
**What remains.** MEASURED on 2026-08-11, 365 distinct cited paths across the four repositories
|
||||
still do not resolve to any published file, 259 of them in this repository. Every one of them is
|
||||
listed, with the documents that cite it, in `CITATIONS-UNRESOLVED.md`. That file is generated and
|
||||
enforced: a citation that stops resolving and is not listed there fails our check, and a listed path
|
||||
that is no longer cited fails it too, so the list cannot quietly rot.
|
||||
|
||||
This paragraph said 344 and 244 until 2026-08-11, measured on 2026-08-03. It was left behind by
|
||||
documents added after that date, and the check caught it: seven newly cited paths did not resolve
|
||||
and were not declared. The count is written here by hand, so it can drift from the generated file;
|
||||
when the two disagree, `CITATIONS-UNRESOLVED.md` is the measurement and this sentence is the stale
|
||||
copy.
|
||||
|
||||
A citation is a promise that a claim is checkable. Where the target is not published, the claim is
|
||||
**traceable but not independently verifiable**, and it should be read as our assertion rather than
|
||||
as something you can confirm. Triaging the remaining 365 into "publish the source", "mark
|
||||
permanently private" and "withdraw the claim" is outstanding work.
|
||||
|
||||
What IS independently checkable, with no reference to the private tree: everything served by the
|
||||
public RPC (precompile behaviour, contract bytecode, balances, block data), everything in the
|
||||
published contract and node sources, and every test in `aere-contracts`. The
|
||||
`AERE-NIST-VALIDATION-STATUS.md:87` disclosure, which states plainly that the KAT harness source
|
||||
and vector files are not committed and that the NIST validation is therefore not reproducible from
|
||||
the repository alone, is the pattern we intend to apply consistently.
|
||||
|
||||
## Start here
|
||||
|
||||
- `REPRODUCE.md` the single reproducibility manifest. It lists real paths, real commands, and
|
||||
|
||||
275
REPRODUCE.md
275
REPRODUCE.md
@ -108,39 +108,105 @@ Foundry. It lives at `aerenew/contracts/test/*.test.js`.
|
||||
```bash
|
||||
cd aerenew/contracts
|
||||
npm ci # installs the pinned toolchain (hardhat, OZ 4.9.x)
|
||||
npx hardhat test # SEE THE WARNING BELOW: this currently crashes partway
|
||||
node scripts/run-tests-sharded.js --jobs 3 # the documented command, see below
|
||||
```
|
||||
|
||||
> **KNOWN DEFECT, measured 2026-07-20, published here rather than left for you to discover.**
|
||||
> **THE SUITE NOW RUNS TO COMPLETION, AND IT IS NOT GREEN. Measured 2026-07-20.**
|
||||
>
|
||||
> `npx hardhat test` does **not** currently run to completion on this repository. It exits with a
|
||||
> segmentation fault partway through, and it does so non-deterministically: two runs on the same
|
||||
> machine on the same day died at different points, one after about 49 minutes having reported 1,447
|
||||
> passing across 128 suites, the other after about 5 minutes at 846 passing across 44 suites. Because
|
||||
> the crash point moves, neither partial count is a valid test result and we do not quote either as
|
||||
> one.
|
||||
> The previous version of this file warned that `npx hardhat test` died with a segmentation fault at
|
||||
> a point that moved between runs, and that we had not isolated it. We have now isolated it, and the
|
||||
> honest result is below. It is not the result we would have chosen.
|
||||
>
|
||||
> A crash whose location moves under identical input points at resource exhaustion rather than a
|
||||
> failing test. We have not yet isolated it, and we are not going to claim we have.
|
||||
> **Diagnosis [FRESH].** The crash is native memory exhaustion, not a failing test and not the Node
|
||||
> heap. Hardhat runs all 175 files under `test/` inside one process hosting one long-lived in-process
|
||||
> EVM (EDR, a native Rust addon), and that EVM materialises a per-opcode execution trace for every
|
||||
> transaction. The pure-Solidity post-quantum verifiers are enormously expensive to execute: about
|
||||
> 9.14 million gas per Falcon-512 verify [CITED: aerenew/pqc-fork/results/bench-results.json, the
|
||||
> same figure quoted in section 3d], and about 10.7 million gas per recovery leg
|
||||
> [CITED: the comment at aerenew/contracts/test/AerePQCSocialRecoveryModule.test.js line 513]. That
|
||||
> is tens of millions of opcodes, so a single such transaction commits multiple GB of trace. Within
|
||||
> one process those peaks are not returned to the OS, so the high-water mark only
|
||||
> ratchets upward across the run until the OS kills the process. Three independent confirmations:
|
||||
>
|
||||
> **What works today:** running suites individually, which is how every per-file command elsewhere in
|
||||
> this document is written. Those commands are real and they pass. For example:
|
||||
> - A single `npx hardhat test` process was observed reaching **43,248 MB of private bytes** before
|
||||
> dying; a second, concurrent one died at **31,560 MB**. The machine has 15.78 GB of RAM and a
|
||||
> 55.5 GB commit limit, which is why the death point depends on what else is running, and therefore
|
||||
> moves.
|
||||
> - `aere-contracts/test/mldsa44Verifier.test.js` prints `memory allocation of 3623878656 bytes failed` and aborts.
|
||||
> That is a single failed 3.6 GB native allocation, which is a Rust allocator abort, not a V8 heap
|
||||
> error.
|
||||
> - Run entirely alone on an otherwise idle machine, that same file still dies:
|
||||
> `npx hardhat test aere-contracts/test/mldsa44Verifier.test.js` exits **139, "Segmentation fault"** [FRESH]. The
|
||||
> segfault therefore reproduces on one file and is not an artefact of suite length.
|
||||
>
|
||||
> ```bash
|
||||
> npx hardhat test test/AereFalcon512Verifier.test.js
|
||||
> There is no supported switch that turns the tracing off. Hardhat 2.28.6 defines
|
||||
> `_setVerboseTracing` but never calls it, and the EDR provider returns `responseObject.traces` on
|
||||
> every request whether or not anything consumes it (see
|
||||
> `node_modules/hardhat/internal/hardhat-network/provider/provider.js` lines 234 to 238).
|
||||
>
|
||||
> **The fix is a workaround and we label it as one.** `scripts/run-tests-sharded.js` gives every test
|
||||
> file its own process, so peak memory becomes the worst single file instead of the accumulated
|
||||
> high-water mark of all of them. It reproduces hardhat's own file selection exactly (every `.js`
|
||||
> under `config.paths.tests`, recursively). It does **not** eliminate the per-transaction cost, which
|
||||
> is inherent to running post-quantum verifiers in-EVM under a tracing provider. Put these files back
|
||||
> into one process and the crash returns.
|
||||
>
|
||||
> **Measured result [FRESH], `node scripts/run-tests-sharded.js --jobs 3`, 2026-07-20:**
|
||||
>
|
||||
> ```
|
||||
> FILES: 175 OK=171 FAILING=3 CRASH=1
|
||||
> AGGREGATE: 2055 passing, 8 failing, 23 pending
|
||||
> WALL: 25.4 min at jobs=3
|
||||
> ```
|
||||
>
|
||||
> **What this means for the coverage figure below:** it is a genuine lower bound, not a target we are
|
||||
> hedging. Fourteen test files cannot be instrumented at all on a 16 GB machine, and they are
|
||||
> disproportionately the post-quantum verifier suites, whose contracts therefore read as 0 percent
|
||||
> covered even though their tests pass when run outside the coverage harness.
|
||||
> Per-file peak private bytes were sampled at 3 second intervals during that run. The median file
|
||||
> peaks at **857 MB**, 162 of the 175 files stay under 1 GB, and only 8 exceed 4 GB. The cost is
|
||||
> concentrated in a handful of suites: `mldsa44Verifier` 28,384 MB, `AerePQCSocialRecoveryModule`
|
||||
> 12,138 MB, `interop/AereEthLightClient` 11,208 MB, `AereFalcon1024Verifier` 10,243 MB,
|
||||
> `pqc-intents` 6,642 MB, `AereFalcon512Verifier` 5,982 MB. Caveat on that attribution: peaks are
|
||||
> matched to files by process id, and Windows reuses process ids, so a per-file figure is reliable
|
||||
> only for the long-running heavy files listed here, which is why no full per-file memory table is
|
||||
> published.
|
||||
>
|
||||
> We would rather you learn this from us, in the file that invites you to check us, than from a
|
||||
> terminal.
|
||||
> **The four files that are not clean, with their actual messages [FRESH]:**
|
||||
>
|
||||
> 1. `aere-contracts/test/mldsa44Verifier.test.js`, exit 139 (0xC0000409 when spawned directly on Windows). Native
|
||||
> OOM as described above. It cannot complete on a 16 GB machine. Its first assertion, the official
|
||||
> ACVP valid vector tc108, does pass before the process dies.
|
||||
> 2. `aere-contracts/test/interop/AereEthLightClient.test.js`, 6 passing, 6 failing under the default config. The
|
||||
> default `hardhat` network pins `hardfork: "cancun"`, but this suite needs the EIP-2537 BLS12-381
|
||||
> precompiles, which arrive in Prague. Under cancun those precompiles are absent, `hashToG2`
|
||||
> returns all zeros, and every signature check fails with `LC:bad signature`. Re-run under the
|
||||
> config that exists for exactly this reason,
|
||||
> `npx hardhat test aere-contracts/test/interop/AereEthLightClient.test.js --config hardhat.config.prague.js`,
|
||||
> and it becomes **7 passing, 5 failing** [FRESH]: the BLS cross-check against noble now passes,
|
||||
> and the 5 remaining failures are a single different defect, `SSZ:branch len`, a finality branch
|
||||
> depth mismatch between the fixture and the contract. That is a real open bug, not a memory
|
||||
> problem.
|
||||
> 3. `aere-contracts/test/compliance-pool.fuzz.test.js`, 0 passing, 1 failing. `Timeout of 600000ms exceeded` on
|
||||
> "survives 1500 randomized actions with all invariants intact". The fuzz does not finish inside
|
||||
> its own 10 minute budget on this hardware. No invariant was reported violated; it ran out of
|
||||
> time.
|
||||
> 4. `aere-contracts/test/invariant-lending-market-property.test.js`, 0 passing, 1 failing.
|
||||
> `Transaction reverted without a reason string` raised inside `AereLendingMarket.liquidate` via
|
||||
> `_healthyAtLiqThreshold` (`contracts/lending/AereLendingMarket.sol:464`). A reasonless revert at
|
||||
> that line is consistent with an arithmetic overflow panic in
|
||||
> `_scaleUp(col, ...) * _priceLiq(...)` under the collateral and price magnitudes the property
|
||||
> test drives. **This is the one finding here that touches fund logic**, because a liquidation that
|
||||
> reverts contradicts the "liquidations never pause" invariant the contract's own comments claim.
|
||||
> It is reported, not fixed, and it is not deployed-state advice: it is an open item.
|
||||
>
|
||||
> `npx hardhat test` with no arguments is still the upstream command and it still dies. Use the
|
||||
> sharded runner. If you want to confirm the defect yourself rather than take our word for it, run
|
||||
> the single file in item 1 and watch the process size.
|
||||
|
||||
|
||||
- Test file count: **137** files matching `test/*.test.js` [FRESH]
|
||||
(`find test -name '*.test.js' | wc -l` = 137).
|
||||
- Test file count: **170** files named `*.test.js`, and **175** `.js` files in total under `test/`
|
||||
[FRESH] (`find test -name '*.test.js' | wc -l` = 170; `find test -name '*.js' | wc -l` = 175).
|
||||
The earlier figure of 137 in this file counted only the top level of `test/` and was wrong for the
|
||||
purpose it was used for: hardhat globs `config.paths.tests` **recursively** and loads every `.js`
|
||||
file it finds, including the 5 non-test helpers, so 175 is the set actually executed. Those files
|
||||
hold **496** `describe` blocks and **2,046** `it` blocks [FRESH].
|
||||
- Of those, **22** are invariant-property fuzz suites over burn, economics, and custody contracts
|
||||
[FRESH] (19 named `*-invariant-property.test.js` plus 3 named `invariant-*-property.test.js`;
|
||||
this matches the "22 invariant-property fuzz suites" figure in
|
||||
@ -149,28 +215,65 @@ npx hardhat test # SEE THE WARNING BELOW: this currently crashes partw
|
||||
**42 passing (3s)**, exit 0 [FRESH] (artifacts were already compiled in `contracts/artifacts`,
|
||||
so no solc download was needed). This confirms the harness runs and a representative file is
|
||||
green on this machine.
|
||||
- Full-suite pass count: [MEASURE: run `npx hardhat test` and publish the "N passing" line. Do
|
||||
not restate an aggregate here until the whole suite has been run in one invocation. An earlier
|
||||
memory note cites "161/161" from a specific historical milestone; that number is NOT re-verified
|
||||
by this document and must not be presented as the current full-suite result without a fresh run.]
|
||||
- Full-suite result: **2,055 passing, 8 failing, 23 pending** across all 175 files, 25.4 minutes at
|
||||
`--jobs 3` [FRESH, `node scripts/run-tests-sharded.js --jobs 3`, 2026-07-20]. This is the first
|
||||
time the whole suite has been observed finishing. It is an aggregate over 175 separate processes,
|
||||
not one invocation, because one invocation cannot complete; that distinction is stated in the
|
||||
defect block above and must not be dropped when this number is quoted. The 8 failures and the 1
|
||||
crashed file are enumerated there. The suite is **not green**, and no summary of this repository
|
||||
should say that it is. The older "161/161" figure from a historical milestone is superseded and
|
||||
must not be used.
|
||||
- Machine-readable per-file results, including exit code and duration for every file, are written to
|
||||
`aerenew/contracts/reports/sharded-test-run/results.json`, with full stdout per file under
|
||||
`reports/sharded-test-run/logs/`.
|
||||
|
||||
**Symbolic layer: Foundry plus Halmos.** A `foundry.toml` sits beside the Hardhat project,
|
||||
deliberately scoped (its own `out-forge`/`cache-forge`, `src = contracts/pqc`, `test =
|
||||
test/formal`) so it does not disturb Hardhat. It exists for symbolic execution over three PQC
|
||||
contracts: `test/formal/AereCryptoRegistry.symbolic.t.sol`,
|
||||
contracts: `aere-contracts/test/formal/AereCryptoRegistry.symbolic.t.sol`,
|
||||
`AerePQCAttestation.symbolic.t.sol`, and `AereSpokePool.symbolic.t.sol`.
|
||||
|
||||
```bash
|
||||
cd aerenew/contracts
|
||||
forge test # compiles contracts/pqc against out-forge
|
||||
# DO NOT use a bare `forge test` as a verdict. Measured on forge 1.7.1 in an isolated
|
||||
# project: no tests at all exits 0, one passing test exits 0, one failing test exits 1.
|
||||
# The exit code does not distinguish "everything passed" from "nothing ran", so a typo,
|
||||
# a renamed function or a non-matching --match-path hands you a green tick for zero work.
|
||||
# This wrapper runs the same command and then REFUSES unless at least PODEA_TESTE tests
|
||||
# actually ran, reading the count out of forge's own summary.
|
||||
PODEA_TESTE=9 bash ../scripts/forge-test-cu-podea.sh
|
||||
halmos # symbolic execution of the *.symbolic.t.sol properties
|
||||
```
|
||||
|
||||
[MEASURE: `forge` and `halmos` are not installed on the machine that produced this document. Run
|
||||
the two commands above and publish (a) the forge pass/fail summary and (b) the halmos per-property
|
||||
result. The security spec references "15 symbolic-execution proofs over the core contracts"
|
||||
[CITED: aerenew/docs/drafts/PRESS-RELEASE-DRAFT-2026-07-18.md]; treat 15 as a documented claim to
|
||||
be reconfirmed by a fresh halmos run, not as a freshly measured number.]
|
||||
`forge test` MEASURED, forge 1.7.1 on Windows, 2026-07-20:
|
||||
|
||||
```
|
||||
Ran 3 test suites in 120.12ms: 9 tests passed, 0 failed, 0 skipped (9 total tests)
|
||||
```
|
||||
|
||||
Two things had to be fixed before that command produced anything, and both are worth stating
|
||||
plainly because the honest previous status was "never run here":
|
||||
|
||||
- `forge test` did not COMPILE. `contracts/intents/AereSpokePool.sol:586` hits "Stack too deep" in
|
||||
the legacy pipeline. `via_ir = true` is now set in `foundry.toml`, which is also the pipeline
|
||||
halmos is invoked with, so the two agree.
|
||||
- `forge test` then found NO TESTS. The three `*.symbolic.t.sol` suites name their properties
|
||||
`check_*`, the halmos convention, and Foundry only collects functions beginning with `test`. The
|
||||
nine properties had therefore never been exercised by anything except halmos, and halmos is not
|
||||
installed here. `test/formal/ForgePropertyFuzz.t.sol` now wraps each one as a Foundry fuzz test,
|
||||
256 runs each.
|
||||
|
||||
That is FUZZING, not proof. Foundry samples inputs; halmos explores them symbolically. Nine green
|
||||
fuzz properties mean no counterexample was found in 2,304 sampled executions. They do not establish
|
||||
the properties for all inputs and must never be described as formal verification. The symbolic
|
||||
obligation still belongs to halmos.
|
||||
|
||||
[MEASURE: `halmos` is still NOT installed on this machine (checked: `halmos` is absent from PATH,
|
||||
and there is no halmos in `~/.cargo/bin` or any project venv). Install it and publish the
|
||||
per-property symbolic result. The security spec references "15 symbolic-execution proofs over the
|
||||
core contracts" [CITED: aerenew/docs/drafts/PRESS-RELEASE-DRAFT-2026-07-18.md]; the repository
|
||||
currently contains 9 `check_*` properties across 3 files, so 15 is a documented claim that does not
|
||||
match a fresh count and must not be repeated until reconciled.]
|
||||
|
||||
### 3b. Formal verification (z3 SMT, plus Halmos and Solidity SMTChecker)
|
||||
|
||||
@ -209,7 +312,7 @@ falcon_logonly_noop, falcon_blocking, qbft_pqc_activation, falcon_hybrid_dualquo
|
||||
threshold_account.
|
||||
|
||||
**Consensus + contract suite, canonical in-tree (19 models: 8 consensus + 11 contract).** The
|
||||
non-staging copy at `aerenew/formal-consensus/run_consensus_verification.py` now wires the 8 QBFT /
|
||||
non-staging copy at `aere-research/formal-consensus/run_consensus_verification.py` now wires the 8 QBFT /
|
||||
Falcon consensus models AND 11 contract SMT models (fund-flow, registry, and PQC-verifier
|
||||
invariants), so a single canonical run covers them and prints a verdict-line tally. The 11 contract
|
||||
models are `computemarket_smt`, `destinationsettler_smt`, `migrator_smt` (escrow / filler / no-custody
|
||||
@ -314,11 +417,11 @@ reject crafted-invalid inputs, so "NIST-conformant" is a checkable statement rat
|
||||
|
||||
| Scheme | Vector file | Committed conformance |
|
||||
|---|---|---|
|
||||
| Falcon-512 | `test/falcon512_kat0.json` | official NIST round-3 KAT, vector 0 [CITED: test/AereFalcon512Verifier.test.js] |
|
||||
| Falcon-1024 | `test/falcon1024_kat0.json` | official round-3 KAT |
|
||||
| ML-DSA-44 (Dilithium2, FIPS 204) | `test/fixtures/mldsa44-acvp-tg8.json` | 15/15 NIST ACVP sigVer cases [CITED: aerenew/aips/AIP-4.md] |
|
||||
| SLH-DSA / SPHINCS+-SHA2-128s (FIPS 205) | `test/fixtures/sphincs-sha2-128s-acvp-tg31.json` | 14/14 NIST ACVP sigVer cases [CITED: aerenew/aips/AIP-4.md] |
|
||||
| XMSS-SHA2_10_256 (RFC 8391) | `test/fixtures/xmss-sha2_10_256-kat.json` | RFC 8391 KAT |
|
||||
| Falcon-512 | `aere-contracts/test/falcon512_kat0.json` | official NIST round-3 KAT, vector 0 [CITED: test/AereFalcon512Verifier.test.js] |
|
||||
| Falcon-1024 | `aere-contracts/test/falcon1024_kat0.json` | official round-3 KAT |
|
||||
| ML-DSA-44 (Dilithium2, FIPS 204) | `aere-contracts/test/fixtures/mldsa44-acvp-tg8.json` | 15/15 NIST ACVP sigVer cases [CITED: aerenew/aips/AIP-4.md] |
|
||||
| SLH-DSA / SPHINCS+-SHA2-128s (FIPS 205) | `aere-contracts/test/fixtures/sphincs-sha2-128s-acvp-tg31.json` | 14/14 NIST ACVP sigVer cases [CITED: aerenew/aips/AIP-4.md] |
|
||||
| XMSS-SHA2_10_256 (RFC 8391) | `aere-contracts/test/fixtures/xmss-sha2_10_256-kat.json` | RFC 8391 KAT |
|
||||
|
||||
```bash
|
||||
cd aerenew/contracts
|
||||
@ -352,7 +455,7 @@ Committed results, to be reconfirmed by a fresh run:
|
||||
against an independent Python `hashlib.shake_256` oracle
|
||||
[CITED: aerenew/pqc-fork/results/kat-results-hashtopoint.json].
|
||||
|
||||
[MEASURE: `run-kats.sh` targets `$BESU_HOME` and `$STAGING` on an isolated build host and
|
||||
[MEASURE: `run-kats.sh` targets the Besu build tree and staging directory on the isolated fork host and
|
||||
cannot run on this machine or on any production host (heavy build; the infra box runs live services
|
||||
and must never take heavy compute). Reproduce on a scratch Linux box and publish the two result
|
||||
JSONs. The Rust acceleration crate has its own KATs: `cd aerenew/pqc-accel && cargo test`
|
||||
@ -393,7 +496,7 @@ measured once on the isolated fork and committed to the AIP. To reproduce them f
|
||||
fork (section 3c) and run a verify-and-record transaction per scheme through the live precompiles,
|
||||
then publish the receipt gasUsed. Do not restate these as current unless re-measured.]
|
||||
|
||||
**Precompile-versus-Solidity Falcon-512 gas benchmark.** `aerenew/pqc-fork/bench/bench.py` deploys
|
||||
**Precompile-versus-Solidity Falcon-512 gas benchmark.** `aere-research/bench/bench.py` deploys
|
||||
the pure-Solidity verifier and the precompile-backed variant on a single-node QBFT fork, runs the
|
||||
same Falcon-512 KAT vectors through both, and reports receipt gasUsed and accept/tamper-reject.
|
||||
|
||||
@ -423,19 +526,93 @@ in this document.]
|
||||
|
||||
Neither of these is a claimed number. Both are commands to run and publish.
|
||||
|
||||
**Coverage.**
|
||||
**Coverage. The one command.**
|
||||
|
||||
```bash
|
||||
cd aerenew/contracts
|
||||
npx hardhat coverage # solidity-coverage, the Hardhat-native coverage path
|
||||
# or, once the Foundry profile is used for the pqc/ scope:
|
||||
forge coverage
|
||||
npm install
|
||||
bash scripts/coverage/run-coverage.sh
|
||||
```
|
||||
|
||||
[MEASURE: run one of the above and publish the real line/branch coverage report. Do NOT write a
|
||||
coverage percentage in any public copy until it comes from a fresh run of this command. A
|
||||
fabricated "99.8% coverage" is a catastrophic credibility failure; an honest "here is the command,
|
||||
here is the report" is the standard.]
|
||||
That is the whole procedure from a clean checkout. It takes HOURS, not minutes, and it needs the
|
||||
contract tree to sit still for the duration. Read the next three paragraphs before you run it or
|
||||
before you quote anything it produces.
|
||||
|
||||
*Why it is not just `npx hardhat coverage`.* A single-process whole-repo coverage run does not fit
|
||||
in memory on a 16 GB machine. MEASURED: the coverage process was observed reaching 33.23 GB private
|
||||
bytes against a 33.78 GB commit limit and being killed by the OS with no report. So the driver
|
||||
shards the suite across many `hardhat coverage` processes and merges the istanbul JSONs. Summing
|
||||
shard counters is valid only if every shard instrumented byte-identical sources, so the driver
|
||||
fingerprints the contract tree with `scripts/coverage/tree-fingerprint.js` before the first shard
|
||||
and re-checks it after every single shard. If a contract is added or edited mid-run it ABORTS with
|
||||
exit 3 and writes no aggregate, because a merge across two different instrumentations is not a
|
||||
lower-quality number, it is a wrong one. That failure is why an earlier run of this suite could not
|
||||
be merged at all.
|
||||
|
||||
*Expected output.* On success the last lines are:
|
||||
|
||||
```
|
||||
=== DONE ===
|
||||
the number : <OUTDIR>/aere-coverage-summary.json
|
||||
what to distrust: <OUTDIR>/AERE-COVERAGE-README.md
|
||||
unmeasurable : <OUTDIR>/shards/unmeasurable.txt (N test files)
|
||||
```
|
||||
|
||||
`aere-coverage-summary.json` is the ONLY file in the run that is the coverage figure. Read its
|
||||
`totals` object. It also carries `treeFingerprint`, the sha256 of the exact contract tree measured;
|
||||
a coverage number published without that fingerprint is not reproducible and should not be quoted.
|
||||
|
||||
*Three artifacts that will mislead you, and they mislead DOWNWARD.* MEASURED on the July 2026 run:
|
||||
|
||||
| Artifact | What a reader would conclude | What it actually is |
|
||||
| --- | --- | --- |
|
||||
| `shards/shard-NNN.partial-istanbul.json` | 1.27% statements | one shard's hits against the whole tree's denominator |
|
||||
| `<report dir>/coverage-final.json` | 1.27% statements | solidity-coverage overwrites its report folder per invocation, so this is whichever shard finished last. The driver now renames it to `LAST-SHARD-ONLY-NOT-THE-COVERAGE-NUMBER.json`. |
|
||||
| the merged istanbul file's `l` counters | 0.25% lines | istanbul's line counters are derived data and were being carried over unmerged from the first shard. `merge-shards.js` now recomputes `l` from `statementMap` plus the summed `s`, so this trap is closed rather than labelled. |
|
||||
|
||||
We fixed these by renaming (the first two) and by recomputing the stale counter (the third), and
|
||||
`AERE-COVERAGE-README.md` is written into every run directory naming each one.
|
||||
|
||||
*The number is a LOWER BOUND, and the gap is in the technology we talk about most.* Some suites
|
||||
cannot be instrumented on this machine at all. MEASURED for `aere-contracts/test/mldsa44Verifier.test.js`, a 2.7 KB
|
||||
file with 4 test cases:
|
||||
|
||||
```bash
|
||||
# uninstrumented: passes in a 256 MB heap
|
||||
node --stack-size=8000 --max-old-space-size=256 \
|
||||
./node_modules/hardhat/internal/cli/bootstrap.js test aere-contracts/test/mldsa44Verifier.test.js
|
||||
# -> 4 passing (1m)
|
||||
|
||||
# instrumented: dies in a 8192 MB heap
|
||||
NODE_OPTIONS=--max-old-space-size=8192 \
|
||||
npx hardhat coverage --config hardhat.config.coverage.js \
|
||||
--testfiles aere-contracts/test/mldsa44Verifier.test.js
|
||||
# -> FATAL ERROR: Reached heap limit Allocation failed
|
||||
```
|
||||
|
||||
A thirty-fold heap multiplier on a file whose fixtures are measured in kilobytes rules out fixture
|
||||
size as the cause. The cost is solidity-coverage's per-statement bookkeeping executing inside a
|
||||
single ML-DSA-44 verification that costs roughly 52.9 million gas, where the same statements run
|
||||
millions of times in one process. Fourteen test files behave this way, disproportionately the
|
||||
post-quantum verifier suites, so THOSE CONTRACTS READ AS ZERO PERCENT COVERED even though their
|
||||
tests pass outside the coverage harness. The driver's answer is to split below the file and run one
|
||||
`it` per process (`scripts/coverage/list-test-cases.js` plus the `micro_shard` stage); where a
|
||||
suite's test titles are built from template literals in a loop, splitting would silently skip cases,
|
||||
so the driver refuses to split and leaves the file listed in `unmeasurable.txt` instead. Read that
|
||||
file before quoting the aggregate.
|
||||
|
||||
**Coverage, Foundry path.**
|
||||
|
||||
```bash
|
||||
cd aerenew/contracts
|
||||
forge coverage --ir-minimum
|
||||
```
|
||||
|
||||
MEASURED, and it does NOT work today: forge 1.7.1 fails to compile the coverage build with
|
||||
`Yul exception: Cannot swap Variable var_sigLen with Variable var_sig_length: too deep in the stack
|
||||
by 1 slots`. `forge coverage` refuses a plain `via_ir` build, and `--ir-minimum` turns the optimizer
|
||||
down far enough that a PQC signature-verification function no longer fits the stack. No Foundry
|
||||
coverage number exists for this repository and none should be quoted until that is resolved.
|
||||
|
||||
**Mutation testing.**
|
||||
|
||||
|
||||
117
VERIFY-POLICY.md
Normal file
117
VERIFY-POLICY.md
Normal file
@ -0,0 +1,117 @@
|
||||
# The `[VERIFY]` marker: what it means in this repository
|
||||
|
||||
**Status:** normative for every Aere Network repository published on `git.aere.network`.
|
||||
**Written:** 2026-08-03. Supersedes the earlier wording that described these markers as items
|
||||
"for a human to confirm before publication".
|
||||
|
||||
---
|
||||
|
||||
## The rule, in one paragraph
|
||||
|
||||
A `[VERIFY]` or `[VERIFY: ...]` marker is a **permanent, deliberate disclosure that one named fact
|
||||
is NOT MEASURED**. It is published exactly as it stands. It does not block publication. It is closed
|
||||
in exactly one way, by a measurement that settles the named fact, and the closing measurement is
|
||||
written down next to it. **A marker is never closed by deleting it**, and it is never closed by
|
||||
softening the sentence around it.
|
||||
|
||||
## Why the earlier wording was wrong, and how
|
||||
|
||||
Three documents in this bundle used to say that these markers were flags "for a human to confirm
|
||||
before publication" or "before publishing":
|
||||
|
||||
- `AERE-EIP-COMPATIBILITY-MATRIX.md`, the "How to read this" list and the open-flags heading
|
||||
- `AERE-NIST-VALIDATION-STATUS.md`, the Appendix A heading and one marker body
|
||||
- `AERE-PROTOCOL-SPECIFICATION.md`, the honesty conventions list and the Section 11 register heading
|
||||
|
||||
That sentence was not true. These repositories were published on 2026-07-20 with **263** exact
|
||||
`[VERIFY]` markers still open across **83** files (measured 2026-08-03 against the published trees,
|
||||
not against a working copy). A document that says its unknowns will be resolved before publication,
|
||||
and is then published with the unknowns in place, asserts more than was done. That is the same class
|
||||
of defect the markers exist to prevent, one level up: **the honesty convention itself was making an
|
||||
unmeasured claim.**
|
||||
|
||||
The repair was to make the text match the practice, not to make the practice match the text. Deleting
|
||||
243 disclosures so that a grep would come back empty would have removed real information from readers
|
||||
and replaced an honest document with a quiet one.
|
||||
|
||||
## Why publishing open unknowns is the right choice here
|
||||
|
||||
This is the same reasoning already recorded in `KNOWN-ISSUES.md` in `aere-contracts`, where our own
|
||||
test suite's findings are published deliberately, with status attached. Publishing a finding is
|
||||
useful. Publishing it with no status was the oversight, and the fix was to add status, not to remove
|
||||
the finding.
|
||||
|
||||
The prior art we followed is the Rust RFC process, where every RFC carries a mandatory
|
||||
"Unresolved questions" section, so the unknowns of a design are an enumerated, permanent part of the
|
||||
published document rather than something that disappears at publication time
|
||||
(`https://github.com/rust-lang/rfcs/blob/master/0000-template.md`).
|
||||
|
||||
The prior art we deliberately did **not** follow is the common docs-CI habit of failing a build on
|
||||
the literal string `TODO` (for example a Vale `existence` rule at `level: error`,
|
||||
`https://docs.vale.sh/topics/styles`). That rule is right for a marker that means "I have not
|
||||
finished writing this sentence". It is wrong for a marker that means "this fact about a live chain
|
||||
has not been measured", because the only thing it can force is deletion, and deletion here is a lie.
|
||||
It is worth noting that GitLab, which runs one of the more thorough public documentation pipelines
|
||||
(Vale, markdownlint, link checking, Mermaid validation), does **not** gate on placeholder markers at
|
||||
all (`https://docs.gitlab.com/development/documentation/testing/`).
|
||||
|
||||
## What is actually enforced
|
||||
|
||||
The guard is `aerenew/scripts/deschise/flaguri-verify.cjs` in the private working repository. It is
|
||||
not a marker ban. It checks four things, and it distinguishes "measured and wrong" from
|
||||
"could not measure":
|
||||
|
||||
1. **No document may promise that markers are closed before publication.** The forbidden phrasings
|
||||
are matched across line breaks, because a sentence split by a line wrap is the same sentence.
|
||||
2. **Every published repository that carries at least one marker must carry this file at its root.**
|
||||
A marker whose meaning is only defined in some other repository is undefined for the reader who
|
||||
found it.
|
||||
3. **The count is tracked, never asserted.** Markers are counted in both forms, `[VERIFY]` and
|
||||
`[VERIFY: ...]`, and compared against the recorded snapshot below. Silent drift fails.
|
||||
4. **The published surface is measured over the network, not from disk.** A working copy is not
|
||||
evidence about what the world can read. If the network cannot be reached, that half of the
|
||||
measurement reports NOT MEASURED and never reports green.
|
||||
|
||||
## Recorded snapshot
|
||||
|
||||
This file is excluded from every count below and from the guard's own counting, because it defines
|
||||
the marker rather than carrying a disclosure. Counting the definition would make the number grow by
|
||||
writing the rule down.
|
||||
|
||||
Working tree of `aerenew/publish-bundle`, measured 2026-08-03:
|
||||
|
||||
| Repository | `[VERIFY]` exact | `[VERIFY` any form | Files carrying a marker |
|
||||
|---|---|---|---|
|
||||
| `aere-contracts` | 8 | 16 | 10 |
|
||||
| `aere-docs` | 177 | 226 | 46 |
|
||||
| `aere-node` | 0 | 0 | 0 |
|
||||
| `aere-research` | 60 | 66 | 18 |
|
||||
| **total** | **245** | **308** | **74** |
|
||||
|
||||
Published trees on `git.aere.network`, cloned and measured 2026-08-03
|
||||
(`aere-docs` at `58780bd`, `aere-contracts` at `c0fcf3d`, `aere-node` at `48416df`,
|
||||
`aere-research` at `37f55e4`, all four commits dated 2026-07-20):
|
||||
|
||||
| Repository | `[VERIFY]` exact | `[VERIFY` any form | Files carrying a marker |
|
||||
|---|---|---|---|
|
||||
| `aere-contracts` | 8 | 16 | 10 |
|
||||
| `aere-docs` | 171 | 224 | 46 |
|
||||
| `aere-node` | 0 | 0 | 0 |
|
||||
| `aere-research` | 84 | 92 | 27 |
|
||||
| **total** | **263** | **332** | **83** |
|
||||
|
||||
The two tables do not agree, and that disagreement is itself a finding rather than an error in the
|
||||
counting. The working copy and the published repositories have drifted apart in **both** directions
|
||||
since 2026-07-20: the working copy holds 21 files that were never published (including
|
||||
`KNOWN-ISSUES.md`, `LICENSING.md`, `CITATIONS-UNRESOLVED.md`, `RUN-A-NODE.md`, `genesis.json` and
|
||||
`bootnodes.txt`), and the published `aere-research` holds 33 files under `formal-consensus/` that no
|
||||
longer exist in the working copy. Any future publication has to reconcile that first, because a
|
||||
naive re-stage and force-push would silently delete 33 files that are public today.
|
||||
|
||||
## For a reader who is not us
|
||||
|
||||
If you found a `[VERIFY]` marker in one of these documents: it is there on purpose. It marks the
|
||||
exact boundary of what we measured. Everything around it is intended to be literally true, and the
|
||||
marker tells you which specific claim we could not stand behind on the date the document was written.
|
||||
If a marker matters to you, the fastest way to close it is usually to measure it yourself against
|
||||
the public endpoint, and we would rather you did that than trust us.
|
||||
Loading…
Reference in New Issue
Block a user