# Aere Network Protocol Specification **Document:** spec-24-protocol-spec **Chain:** Aere Network mainnet, chain ID 2800 (`0xaf0`) **Base execution client:** Hyperledger Besu 26.4.0 line (fork), with a second client (patched Nethermind 1.39.0) as a validation cross-check **Status:** Internal draft for adversarial review and for the external audit that follows. Every value in this document is intended to be checkable against the repository, the live chain, or a cited upstream specification. It is internally verified and adversarially self-reviewed; it is not yet externally audited. Read every parameter as "internally verified, not externally attested" until an independent audit completes. --- ## 0. How to read this document This is a *delta* specification. It does not restate Ethereum execution semantics or the QBFT consensus protocol. It specifies, precisely and exhaustively, only what Aere Network *adds to* and *changes from* the union of two upstream specifications: 1. **Ethereum execution semantics**, as defined by the Ethereum execution-layer specifications ("execution-specs") and the Ethereum Yellow Paper, at the Pectra plus Fusaka ruleset. 2. **QBFT consensus**, as defined by the Hyperledger Besu QBFT implementation and the IBFT 2.0 / QBFT literature. A second implementation team should be able to take a stock Besu (or a stock Nethermind), apply the changes in this document, and produce a client that matches Aere Network byte-for-byte on chain 2800. If a behavior is not described here as a delta, it is by definition identical to the referenced upstream, and the upstream specification governs. **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. - 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. --- ## 1. Scope and non-scope ### 1.1 The delta framing Aere Network did not invent a new protocol. Aere Network is: ``` Aere Network = Ethereum execution (Pectra + Fusaka ruleset) + QBFT consensus (Besu / IBFT 2.0 family) + the Aere delta specified in this document ``` The Aere delta is small and enumerable. It consists of exactly the following: 1. **Chain and consensus parameters** distinct from Ethereum mainnet: chain ID, block period (with one mid-chain transition), the QBFT validator-set size and quorum, and the genesis allocation. (Section 2, Section 3.) 2. **The AerePQC hard fork**: five native post-quantum verification precompiles at `0x0AE1..0x0AE5`, the native EIP-2935 write path, and the EIP-7939 CLZ opcode, all activated together at one block height. (Section 4.) 3. **Two further precompiles built but not activated on mainnet** (`0x0AE6` ML-KEM-768, `0x0AE7` Falcon HashToPoint) and one reference skeleton (`0x0AE8` hash-based STARK verify; the BabyBear/FRI skeleton targets Aere's own Plonky3 circuits, NOT SP1 6.1.0, which is Hypercube, see 4.8.3). Specified for completeness and clearly marked non-live. (Section 4.6.) 4. **Fee and burn mechanics**: a 1-Gwei EIP-1559 base-fee floor applied at the execution layer, and a validator-reward-cut burn applied *above* consensus by an application contract. (Section 5.) 5. **A set of deliberate EIP deviations** from Ethereum parity that follow from Aere being a QBFT chain with no beacon layer and no blob data-availability market. (Section 6.) Everything else, meaning the EVM instruction set, gas schedule (except the additions in Section 4 and the floor in Section 5), transaction types, state trie, RLP encoding, receipt and log format, and JSON-RPC surface, is identical to the referenced Ethereum ruleset and is out of scope for this document. ### 1.2 Upstream references this document builds on (and does not restate) | Ref | Title | Role in this spec | |---|---|---| | ES | Ethereum execution-layer specifications ("execution-specs") | The executable definition of EVM execution, state transition, and the gas schedule that Aere inherits unchanged. | | YP | Ethereum Yellow Paper | The formal state-transition reference for the base layer. | | QBFT | Hyperledger Besu QBFT consensus, and the IBFT 2.0 formal model (Saltini and Hyland-Wood, "IBFT 2.0: A Safe and Live Variation of the IBFT Blockchain Consensus Protocol for Eventually Synchronous Networks") | The consensus protocol Aere runs. Section 3 specifies only the Aere-specific parameters and does not redefine the message flow, which QBFT governs. | | EIP-1559 | Fee market change for ETH 1.0 | Base-fee mechanics that Aere inherits, then floors (Section 5.1). | | EIP-2935 | Serve historical block hashes from state | Aere activates the write path at the AerePQC fork (Section 4.5). | | EIP-7825 | Transaction gas limit cap (2^24) | The per-transaction cap Aere keeps identical to Ethereum; it is the reason the PQC precompiles exist (Section 4). | | EIP-7939 | Count leading zeros (CLZ) opcode | Activated at the AerePQC milestone (Section 4.7). | | EIP-7702 | Set EOA account code | The EOA-delegation primitive Aere carries (Section 6). | | FIPS 202 | SHA-3 / SHAKE | Basis of the `0x0AE5` SHAKE256 precompile. | | FIPS 203 | ML-KEM | Basis of the non-live `0x0AE6` precompile. | | FIPS 204 | ML-DSA | Basis of the `0x0AE3` precompile. | | FIPS 205 | SLH-DSA | Basis of the `0x0AE4` precompile. | | Falcon | NIST PQC round-3 Falcon | Basis of the `0x0AE1` and `0x0AE2` precompiles. | | RIP-7212 / RIP-7951 | secp256r1 (P-256) verification precompile | The `0x100` precompile Aere shares with Ethereum's Osaka; standards-aligned, not Aere-proprietary. | Anywhere this document is silent, the referenced upstream is authoritative. ### 1.3 Aere-specific source artifacts 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). - `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). - `aerenew/docs/AERE-EIP-COMPATIBILITY-MATRIX.md`, `AERE-ENGINEERING-SECURITY-SPEC.md`, `AERE-ARCHITECTURE-MAP.md`. - `aere-genesis-current.json` (the genesis config). The build artifact of record for the fork is the Aere Besu fork, base `hyperledger/besu:26.4.0` (base commit `d203201`), gold binary SHA-256 `7c5c0743088e9fa765d54c745814601b3c7a27a892e396156f88092b34c80772`. --- ## 2. Chain parameters This section states every chain-level parameter where Aere differs from an Ethereum mainnet default, plus the small set of core constants a reimplementer must pin exactly. ### 2.1 Identity and genesis | Parameter | Value | Source / note | |---|---|---| | Chain ID | `2800` (`0xaf0`) | `aere-genesis-current.json` `config.chainId`. Used in EIP-155 replay protection and the EIP-2124 fork id. | | Network genesis | genesis-v2, re-genesised 2026-05-07 | The current chain is the second genesis (see `AIP-3`, `project_chain_live`); block 0 of the live chain is genesis-v2. | | Genesis timestamp | `0x69fbd960` | `aere-genesis-current.json` `timestamp`. | | Native coin | AERE (ticker uppercase `AERE`) | The single native coin; there is no protocol mint path. | | Total supply | 2,800,000,000 AERE, fixed at genesis | Sum of the six genesis allocations below. | | Genesis difficulty | `0x1` | QBFT (proof-of-authority family); difficulty is nominal. | | Genesis coinbase | `0x0000000000000000000000000000000000000000` | Genesis has no block reward beneficiary. | Genesis allocation (fixed, 2.8B AERE total): | Beneficiary | Amount (AERE) | Share | Address | |---|---|---|---| | Strategic Investor | 100,000,000 | 3.57% | `0xaee2f3989f0AB23296Fa3b92247fe67587141311` | | Foundation (ops + signing) | 180,000,000 | 6.43% | `0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3` | | Mining Reserve (emissions) | 1,400,000,000 | 50.00% | `0x038f59A40ceeCd599A4588E4B0ff4642a0fbfFB8` | | Ecosystem Reserve | 560,000,000 | 20.00% | `0xB6a364F47d21DC2CbEB803565c111c1026e11C75` | | Team Reserve | 420,000,000 | 15.00% | `0x7968C438204a78B4e032fcFFd9A56Edb15fdCCdf` | | Airdrop Reserve | 140,000,000 | 5.00% | `0x261913fA73D6F109382F1aE98Ff6822ff03628B1` | There is no protocol-level inflation or mint path in the state-transition rules; emissions come from moving pre-allocated Mining Reserve balances, not from minting. ### 2.2 Block period Aere runs a shorter block period than Ethereum, and it changed once mid-chain via a QBFT configuration transition (not a re-genesis and not a client fork). | 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 }` | 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`.) 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. ### 2.3 Gas limits, and the genesis gas-limit ambiguity stated honestly | Parameter | Value | Note | |---|---|---| | Genesis block gas limit | `0x1fffffffffffff` = 9,007,199,254,740,991 (2^53 − 1) | `aere-genesis-current.json` `gasLimit`. This is effectively unbounded. | | Per-transaction gas cap | `16,777,216` (2^24), EIP-7825 | Inherited identically from Ethereum's Fusaka ruleset; enforced on chain 2800. | **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")`.] ### 2.4 QBFT consensus parameters | Parameter | Value | Source | |---|---|---| | Consensus family | QBFT (Istanbul BFT / IBFT 2.0 family) | `AERE-ENGINEERING-SECURITY-SPEC` §1.1 | | Live validator set size | N = 7 | Engineering spec §1.1; live set expanded from a smaller genesis set (Section 3.2). | | Byzantine fault bound | f = 2 (at N = 7) | `f = floor((N-1)/3) = 2` | | Commit quorum | 5 of 7 (`ceil(2N/3) = 5`, equivalently `2f + 1`) | Engineering spec §1.1 | | Validator identity | secp256k1 ECDSA, recovered from the seal (`ecrecover`); no stored validator public key at verify time | Engineering spec §1.1 | | Epoch length | 30,000 blocks | genesis `config.qbft.epochlength` | | Request timeout | 4 seconds (base round timeout) | genesis `config.qbft.requesttimeoutseconds` | | Finality | deterministic single-slot (a committed block is final) | Engineering spec §4.1 | Genesis QBFT config (from `aere-genesis-current.json`): ```json "qbft": { "blockperiodseconds": 1, "epochlength": 30000, "requesttimeoutseconds": 4 } ``` 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. [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).] ### 2.5 Fork schedule Aere tracks Ethereum's hard forks so that its EVM surface matches mainnet at the same addresses and opcodes, then adds one Aere-specific milestone. | 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). | 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. [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.] --- ## 3. Consensus (QBFT) delta and seal format Aere runs QBFT unmodified in protocol; the delta is entirely in parameters (Section 2.4) and in operational posture. This section specifies what a reimplementer needs to reproduce Aere's block sealing and validation, and references QBFT for the message flow it does not restate. ### 3.1 What is inherited from QBFT (not restated here) The following are governed entirely by the QBFT reference and are identical on Aere: - The three-phase message flow (Pre-prepare / Prepare / Commit) within a round. - Round-change (view-change) on timeout, with a doubling round-timeout backoff from the base `requesttimeoutseconds`. - IBFT 2.0 locking: a validator that has prepared a block retains the prepared block and its prepare-certificate, carries the certificate in a round-change message, and a new proposer re-proposes the justified (locked) block rather than a conflicting one. This is the property that prevents a stale or conflicting proposal from being committed across a round change. - Round-robin proposer selection over the ordered validator set. - The RLP layout of the QBFT `extraData` header field (vanity, validator list, vote, round, committed seals) and the two hashing passes (the proposer-seal hash over the header with an empty committed-seal list, and the block hash over the header with the committed seals populated). A reimplementer should take these directly from Besu QBFT. Aere changes none of them. ### 3.2 Validator set The validator set is QBFT-managed on-chain via the standard QBFT validator-vote mechanism in the header `extraData`, not by any Aere-specific rule and not by any Ethereum beacon-layer deposit (Section 6 explains why the Pectra deposit/withdrawal machinery has no effect on the Aere validator set). - **Genesis validator set.** The genesis `extraData` encodes the initial QBFT validator list. In `aere-genesis-current.json` the genesis `extraData` is: `0xf865a00000...0000f83f94b5e768cb3117ea25175f51aa956b48691025c2a894f73bbbd26a82dbc769066550d8d4585eab2fc00d944bf6f91d84b37454544279cba152581ed6820044c080c0` which decodes to a three-validator genesis set: - `0xb5e768cb3117ea25175f51aa956b48691025c2a8` - `0xf73bbbd26a82dbc769066550d8d4585eab2fc00d` - `0x4bf6f91d84b37454544279cba152581ed6820044` - **Live validator set.** The live set is N = 7 (f = 2, quorum 5), all Foundation-operated, expanded from the genesis set by QBFT votes at chain head (see `validator_expansion`). Enumerating the exact seven live validator addresses is an operational detail outside this protocol spec. [VERIFY: the exact list of the seven live validator addresses at the current head, if they are to be published; the genesis `extraData` above encodes only the three-validator genesis set.] ### 3.3 Seal format (the part a reimplementer must match exactly) Aere's seals are standard QBFT, restated here because a reimplementer must reproduce them byte-for-byte: - **Committed seal.** Each committed seal is a **65-byte recoverable ECDSA signature** over secp256k1: `r` (32 bytes) `|| s` (32 bytes) `|| v` (1 byte recovery id). The signer (committer) address is recovered with `ecrecover` over the commit-seal pre-image (the block hash computed with an empty committed-seal list, per QBFT). There is no stored validator public key consulted at verification time; identity is the recovered address. - **Proposer seal.** The proposer's seal in `extraData` is likewise a 65-byte recoverable ECDSA signature over the proposer-seal hash. - **Quorum rule.** A block is valid only if it carries at least **5 distinct committed seals**, each recovering to a **distinct member of the current validator set**. Fewer than 5 distinct in-set committers, or any duplicate committer, invalidates the block. - **Hash algorithm.** keccak-256, as in Ethereum. Block hashing, Merkle-Patricia state proofs, and commit-seal pre-images assume keccak-256 collision resistance (Assumption A-4 in the engineering spec). The seal signature scheme is classical secp256k1 ECDSA. Forging a block reduces to forging secp256k1 ECDSA, which is classically hard and Shor-breakable under a cryptographically relevant quantum computer. **This is the precise reason Aere consensus is described as classical, not post-quantum.** ### 3.4 Safety and liveness envelope (specification of guarantees, not a proof) At N = 7, f = 2, quorum 5: - **Safety (no fork / no equivocation)** holds with up to 2 Byzantine validators. A 3-of-7 collusion (more than one third) can violate agreement; this bound is exact, not a soft target. - **Liveness** is eventual under partial synchrony (Assumption A-1). At the exact f = 2 boundary (2 validators down, exactly 5 survivors with zero quorum slack) a rare, temporary, self-healing zero-progress window can occur; this is inherent to partially synchronous BFT (FLP), is not a fork, and is not a permanent halt. Adversarial soak testing (100 kill-2-of-7 cycles) recorded 0 forks and 100/100 resync. - **Sub-quorum behavior.** With 3 or more validators down (4 or fewer alive, below the quorum of 5), the chain halts cleanly and resumes from the exact halted height when quorum is restored, with no re-genesis and no split. These follow from the QBFT quorum math and the locking property, plus the fault-tolerance characterization; they are consensus guarantees, not Aere-specific protocol rules, and are reproduced here only to fix the parameter envelope. The load-bearing operational caveat is that all seven validators are Foundation-operated (Nakamoto coefficient about 1), which is a trust assumption, not a cryptographic guarantee. ### 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. ### 3.6 A note on base-fee validation under QBFT A consensus-relevant subtlety a reimplementer must know: the QBFT header ruleset on chain 2800 does not include a base-fee gas-price validation rule (the `BaseFeeMarketBlockHeaderGasPriceValidationRule` present in Besu's Clique and Merge rulesets). Consequently a change to the base fee, including the 1-Gwei floor of Section 5.1, cannot halt or split the chain: non-validating nodes follow the producer's header base fee automatically. Validators must be upgraded to the floor logic only for base-fee *consistency* across proposers (so the value does not oscillate by proposer), not to avoid a halt. (Source: base-fee floor runbook; memory `rpc_basefee_honesty_fix`.) --- ## 4. The AerePQC fork (the main delta) The AerePQC hard fork is the single largest element of the Aere delta. It activated on mainnet chain 2800 at **block 9,189,161** (2026-07-12), configured as a Besu `futureEips` milestone with activation timestamp `futureEipsTime = 1783820272`. It is a coordinated, client-only, flag-day activation with **no re-genesis and no state migration**. It added three things, all at the execution layer: 1. Five native post-quantum verification precompiles at the address band `0x0AE1..0x0AE5`. 2. The native EIP-2935 historical-block-hash write path. 3. The EIP-7939 CLZ opcode. It did **not** change how blocks are proposed, signed, or committed. Blocks are still produced and committed by the QBFT validator set signing classical secp256k1 ECDSA committed seals (Section 3). (Source: `AIP-7`.) ### 4.1 Common precompile conventions (as shipped) These conventions apply to all five live verify/hash precompiles and are the *as-shipped* behavior, which differs from an earlier design draft. Where the draft `aip-draft-pqc-precompiles.md` said "MUST revert on malformed input" and "single-byte output", that was the original design intent; the reconciled, live behavior is below and is what a reimplementer MUST match. - **Fail-closed, never fault.** A malformed, unparseable, or wrong-length input MUST NOT revert and MUST NOT throw. The four signature-verify precompiles (`0x0AE1..0x0AE4`) return a **32-byte zero word** (`0x00..00`, read as "not verified"). The SHAKE256 precompile (`0x0AE5`) returns **empty output** (`0x`). This was verified against the live chain (2026-07-18) and is the consensus rule: every node MUST return byte-identical output for identical input. - **Output on a well-formed verify.** A **32-byte word**: `0x00..01` if the signature is valid for the given public key and message, `0x00..00` if it is well-formed but cryptographically invalid. Note this is a full 32-byte word, not a single byte. A consuming contract reads the low byte: valid iff `ret.length >= 32 && ret[31] == 0x01` (this is exactly how `AerePQCAttestation._verify` decides). - **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. **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. ### 4.2 `0x0AE1` Falcon-512 verify, and `0x0AE2` Falcon-1024 verify **Address.** `0x0000000000000000000000000000000000000AE1` (Falcon-512), `0x0000000000000000000000000000000000000AE2` (Falcon-1024). **Scheme.** NIST PQC round-3 Falcon signature verification. Integer-only verification path. **Parameters:** | | Falcon-512 (`0x0AE1`) | Falcon-1024 (`0x0AE2`) | |---|---|---| | `logn` | 9 | 10 | | Ring | `Z_q[x]/(x^512 + 1)` | `Z_q[x]/(x^1024 + 1)` | | Degree `n` | 512 | 1024 | | `q` | 12289 | 12289 | | Squared-norm acceptance bound `floor(beta^2)` | 34,034,726 | 70,265,242 | | Nonce (salt) length | 40 | 40 | | Public key length | 897 bytes | 1793 bytes | | Public-key header byte | `0x09` (`0x00 + logn`) | `0x0A` | | Signature (`esig`) header byte | `0x29` (`0x20 + logn`) | `0x2A` | **Input calldata layout (as shipped, per `AerePQCAttestation._buildInput`):** ``` input = pk || sm pk = pkHeader(1) || packed_h ; 897 bytes (Falcon-512), 1793 bytes (Falcon-1024) ; pkHeader = 0x09 (F-512) or 0x0A (F-1024); packed_h = n coefficients, 14-bit packed sm = sigLen(2, big-endian uint16) || nonce(40) || message || esig ; sigLen == len(esig) esig = esigHeader(1) || compressedSig ; esigHeader = 0x29 (F-512) or 0x2A (F-1024) ; compressedSig = compressed Gaussian encoding of s2 ``` Concretely, `sm` is `abi.encodePacked(uint16(sigLen), nonce, message, esig)`, and the full precompile input is `abi.encodePacked(pk, sm)`. The 40-byte nonce and the `esig` are the two halves of the caller's detached Falcon signature envelope `nonce(40) || esig`. **Verification behavior (Falcon reference `hash_to_point_vartime` plus norm check):** 1. `HashToPoint`: stream `SHAKE256(nonce || message)` and rejection-sample the challenge polynomial `c` (16-bit big-endian samples, keep values `w < 5q = 61445`, reduce mod `q`), collecting `n` coefficients. 2. Decode the public key into `h` (n coefficients, 14-bit packed; reject coefficients `>= q` and nonzero trailing bits). 3. `comp_decode` the compressed `s2` (sign bit, 7 low bits, unary high bits; reject "-0", overflow above 2047, buffer overrun, nonzero trailing bits, and any unconsumed trailing bytes). 4. Recompute `s1 = c - s2*h` in the ring via negacyclic NTT convolution mod `q`, centered into `(-q/2, q/2]`. 5. Accept iff `||(s1, s2)||^2 <= floor(beta^2)` (34,034,726 for Falcon-512, 70,265,242 for Falcon-1024). **Output.** 32-byte word: `0x00..01` if valid, else `0x00..00`. **Fail-closed.** Any structurally malformed input (wrong `pk` length, wrong `pk` header, wrong `esig` header, inconsistent `sigLen`, or a total length that does not frame as `pk || sm`) returns `0x00..00`, identical to a non-verifying signature. It does not revert. (A probe of `0x0AE1` with `0xdeadbeef` returns `0x00..00`, confirmed live 2026-07-18.) **Gas.** | | Marginal verify-op gas | Full verify-and-record tx gasUsed | Share of 2^24 cap | |---|---|---|---| | Falcon-512 | 40,000 | 86,336 | 0.51% | | Falcon-1024 | 75,000 | 145,496 | 0.87% | The marginal verify-op gas is a fixed cost (Falcon verification work is bounded and near-constant per verify). Falcon-1024 does roughly double the ring work of Falcon-512. These figures were measured on the pre-activation scratch fork (chain 28099) and carried to mainnet. [VERIFY: the precise low-level `sm` byte order the native `0x0AE1`/`0x0AE2` parser expects (whether `message` precedes or follows `esig` inside `sm`), against the gold-binary precompile source or the committed conformance vectors. This spec states the order `sigLen || nonce || message || esig` exactly as `AerePQCAttestation._buildInput` builds it and as a real on-chain attestation confirmed, but the native parser source is not in the repository.] ### 4.3 `0x0AE3` ML-DSA-44 verify **Address.** `0x0000000000000000000000000000000000000AE3`. **Scheme.** NIST ML-DSA-44 (Dilithium2), FIPS 204, internal interface (`Verify_internal`, Algorithm 8, `externalMu = false`, empty context string). **Parameters:** `q = 8380417`, `n = 256`, `(k, l) = (4, 4)`, `d = 13`, `tau = 39`, `gamma1 = 2^17`, `gamma2 = (q-1)/88`, `beta = 78`, `omega = 80`, `lambda = 128`, public key 1312 bytes, signature 2420 bytes, `c~` 32 bytes, infinity-norm acceptance bound `||z||_inf < gamma1 - beta = 130994`. **Input calldata layout (as shipped):** ``` input = pk || sig || message pk : 1312 bytes ; rho(32) || t1 (k=4 polys, 10-bit SimpleBitUnpack) sig : 2420 bytes ; c~(32) || z (l=4 polys, 18-bit BitUnpack) || hint (omega+k = 84 bytes) message : remaining bytes ; the signed message (32 bytes in the AerePQCAttestation flow) ``` There is **no length-field header**: the fields are fixed-size (1312 and 2420) and the message is the remainder. This is `abi.encodePacked(pubKey, signature, message)` in `AerePQCAttestation._buildInput`. **Verification behavior.** Full FIPS 204 `Verify_internal`: `pkDecode`; `sigDecode` (`BitUnpack` plus `HintBitUnpack` with strict-increasing and bound validation); `ExpandA` (SHAKE128 rejection sampling of `A_hat` directly in the NTT domain); `mu = H(H(pk, 64) || M, 64)` with `H = SHAKE256`; `c = SampleInBall(c~)`; `w'approx = NTT^{-1}(A_hat o NTT(z) - NTT(c) o NTT(t1 * 2^d))` over `Z_q[x]/(x^256+1)`; `w1 = UseHint(h, w'approx)`; `c~' = H(mu || w1Encode(w1), 32)`; accept iff `||z||_inf < 130994`, the hint is valid, and `c~' == c~`. **Output.** 32-byte word: `0x00..01` valid, `0x00..00` invalid. **Fail-closed.** A `pk` length `!= 1312`, a `sig` length `!= 2420`, or any structurally broken input returns `0x00..00` (does not revert). Confirmed live: a probe with `0xdeadbeef` returns `0x00..00`. Note: this precompile implements the *internal* interface (empty context); a general ML-DSA `Verify` with a nonempty context string is a distinct interface and is out of scope for this precompile. **Gas.** Marginal verify-op gas 55,000; full verify-and-record tx 351,050 (2.09% of the 2^24 cap). This is the change that moves ML-DSA-44 from view-only (its pure-Solidity `verifyAndRecord` is about 52.9M gas, above the cap) to record-on-chain. ### 4.4 `0x0AE4` SLH-DSA-SHA2-128s verify **Address.** `0x0000000000000000000000000000000000000AE4`. **Scheme.** NIST SLH-DSA-SHA2-128s (SPHINCS+-SHA2-128s-simple), FIPS 205, internal interface (`slh_verify_internal`, Algorithm 20, no pre-hash). **Parameters:** `n = 16`, `h = 63`, `d = 7`, `h' = 9`, `a = 12`, `k = 14`, `lg_w = 4`, `w = 16`, `len = 35`, public key 32 bytes, signature 7856 bytes. **Input calldata layout (as shipped):** ``` input = pk || sig || message pk : 32 bytes ; PK.seed(16) || PK.root(16) sig : 7856 bytes ; R(16) || SIG_FORS || SIG_HT message : remaining bytes ``` No length-field header; fixed-size fields plus the message remainder (`abi.encodePacked(pubKey, signature, message)`). **Verification behavior.** Full FIPS 205 `slh_verify_internal`: `H_msg = MGF1-SHA256(R || PK.seed || SHA256(R || PK.seed || PK.root || M))` split into `(md, idx_tree mod 2^54, idx_leaf mod 2^9)`; FORS `pkFromSig` with base-`2^12` big-endian index extraction (the FIPS 205 change versus round-3 SPHINCS+); a `d = 7` hypertree of WOTS+ (`len = 35`) with `h' = 9` Merkle layers; tweakable hash `Th = Trunc16(SHA256(PK.seed || 0^48 || ADRSc || M))`. Accept iff the recomputed root equals `PK.root`. **Output.** 32-byte word: `0x00..01` valid, `0x00..00` invalid. **Fail-closed.** `pk` length `!= 32`, `sig` length `!= 7856`, or any structurally broken input returns `0x00..00` (does not revert). SLH-DSA is stateless and many-time, so unlike XMSS there is no one-time-per-leaf state caveat at the scheme level. **Gas.** Marginal verify-op gas 350,000; full verify-and-record tx 558,276 (3.33% of the 2^24 cap). SLH-DSA-SHA2-128s already fit under the cap in pure Solidity (about 1.81M gas), so this precompile is a cost reduction rather than an enabler; it is included so the whole PQC suite shares one native code path and one gas model. The fixed cost is higher than the lattice precompiles because SLH-DSA verification is hash-heavy (thousands of SHA-256 and tweakable-hash calls). ### 4.5 `0x0AE5` SHAKE256 **Address.** `0x0000000000000000000000000000000000000AE5`. **Scheme.** FIPS 202 `SHAKE256` extendable-output function. **Input calldata layout (as shipped):** ``` offset 0 : outLen (32 bytes, big-endian word) desired output length in bytes offset 32 : data (all remaining bytes) message to absorb ``` The live precompile reads `outLen` as a **full 32-byte big-endian word** at offset 0, with the data to absorb starting at offset 32. (An earlier draft framed `outLen` as a 4-byte `uint32`; that is the design record, not the live encoding.) **Behavior.** Compute `SHAKE256(data)` with rate 136 bytes, domain separation `0x1F`, and `pad10*1` padding (identical to the on-chain `AereFalcon512Verifier.shake256`), then squeeze `outLen` bytes. True extendable-output squeezing: for a fixed `data`, the first `k` bytes of an `outLen = m >= k` output are byte-identical to an `outLen = k` output. **Output.** Exactly `outLen` bytes. An `outLen` of 0 returns empty output. **Fail-closed.** Any input the parser cannot interpret as a 32-byte `outLen` word followed by data (including a short input, or the draft 4-byte framing) returns **empty output** (`0x`), not a revert. Live confirmation (2026-07-18): - `outLen = 32`, data `abc` returns `0x483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739` = `shake_256(b'abc').hexdigest(32)`. - `outLen = 32`, empty data returns `0x46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f` = `shake_256(b'').hexdigest(32)`. - `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`: ``` words = ceil((len(data) + 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. [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.] ### 4.6 Native EIP-2935 block-hash lookback (write path) The AerePQC fork activates the native EIP-2935 history-storage system contract. - **Address.** `0x0000F90827F1C53a10cb7A02335B175320002935`. - **Structure.** A ring buffer of the last **8191** (`0x1FFF`) block hashes. - **Write path.** At the start of every block, before any user transaction runs, the parent block hash is written into slot `(number - 1) mod 8191` by a **consensus system call** from the system address. There is no keeper, relayer, or Foundation key; the write is a condition of block validity. In Besu terms this is the `PraguePreExecutionProcessor` system-address write. - **Read path.** A contract reads a historical hash by `STATICCALL` to the system contract with the 32-byte block number as calldata. A query outside the served window `[number - 8191, number - 1]` reverts (contract-level revert of the read, not a consensus fault). - **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. ### 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.] ### 4.8 Precompiles built but NOT live on mainnet (specified for completeness) The following three addresses are Aere-specific but are **not activated on mainnet chain 2800**. A mainnet `STATICCALL` to any of them hits an empty account and returns empty. They are specified here so a reimplementer knows the full band allocation and does not accidentally activate them. Their source is in `aerenew/pqc-fork/precompiles/`. #### 4.8.1 `0x0AE6` ML-KEM-768 deterministic encapsulation (testnet only) FIPS 203 ML-KEM-768. Aere's first post-quantum confidentiality primitive (every live precompile is signature or hash, giving authenticity only). Built and ACVP-verified (25/25) on an isolated QBFT testnet; founder- and audit-gated for mainnet. - **Input layout:** `ek(1184) || m(32)` = 1216 bytes exactly. `ek` is the ML-KEM-768 encapsulation (public) key; `m` is the 32-byte encapsulation randomness ("coins"). - **Output layout:** `c(1088) || K(32)` = 1120 bytes; or empty (`0x`) on any malformed input. - **Behavior:** deterministic Encaps. Feed the caller-supplied `m` as the encapsulation randomness to Bouncy Castle `MLKEMGenerator.internalGenerateEncapsulated(pub, m)`, so every node computes the identical `(c, K)`. (The standard FIPS 203 Encaps draws `m` from a CSPRNG, which cannot run in a consensus-critical precompile; taking `m` from calldata makes it deterministic.) - **Fail-closed:** `input.size() != 1216`, or any thrown `Throwable`, returns `Bytes.EMPTY`. Source-verified fail-closed in `MLKEM768PrecompiledContract.computePrecompile`. - **Gas:** fixed `60,000` (`GAS`). #### 4.8.2 `0x0AE7` Falcon HashToPoint (testnet only) The SHAKE256-driven map from `(nonce, message)` to a Falcon challenge polynomial `c` in `Z_q[x]/(x^n+1)`, `q = 12289`. Built and KAT-verified (12/12 versus an independent Python FIPS 202 SHAKE256 oracle) on isolated testnet; founder- and audit-gated. - **Input layout:** `logn(1) || nonce(40) || message(rest)`, where `logn` is 9 (Falcon-512, n=512) or 10 (Falcon-1024, n=1024). - **Output:** `2n` bytes, that is `n` coefficients each a big-endian `uint16` in `[0, q)`. - **Behavior:** absorb `nonce || message` into a SHAKE256 sponge; repeatedly squeeze two bytes, interpret as a big-endian 16-bit `w`, keep `w mod q` whenever `w < 5q = 61445`, until `n` coefficients are collected (matches the reference `hash_to_point_vartime`). - **Fail-closed:** input length `< 41`, or `logn` not in `{9, 10}`, returns `Bytes.EMPTY`; any thrown `Throwable` returns `Bytes.EMPTY`. - **Gas:** `BASE_GAS(60) + GAS_PER_WORD(12) * words`, where `words = ceil(absorbBytes/32) + ceil(squeezeBytes/32)`, `absorbBytes = input.size() - 1`, and `squeezeBytes = (2 * n * 70) / 64` (a conservative fixed approximately 1.094x expansion so gas is a pure function of the input, independent of the rejection-sampling outcome). On malformed input (`n == 0`) it charges only `BASE_GAS + GAS_PER_WORD * ceil(input.size()/32)`. #### 4.8.3 `0x0AE8` hash-based STARK verify (reference skeleton, never to be activated as-is) A reference skeleton for direct on-chain verification of a hash-based FRI/STARK proof. **It is not a working verifier.** Scope caveat (2026-07-19 research finding): the generic components confirmed so far are a BabyBear + FRI STARK verifier, conformance-confirmed against Plonky3 `0.4.3-succinct`, that 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; removing the SP1 BN254 Groth16 outer wrap requires a separate ~22 to 32 person-week retarget to the SP1 Hypercube stack (see `AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md`). The crypto core (Poseidon2-BabyBear permutation, FRI folding arithmetic, SP1 recursion-AIR constraint evaluation) is deliberately not ported; those methods return "unavailable", which makes `computePrecompile` fail-closed: it returns `Bytes.EMPTY` for every input and can never return a positive result by construction. It MUST NOT be activated on mainnet until the crypto core is ported and audited. - **Wire layout (v1):** `magic(4)="AS1\0" || version(1) || configId(1) || reserved(2) || vkeyDigest(32) || publicValuesLen(4, big-endian) || publicValues || proofLen(4, big-endian) || friProof`. - **Output:** on a fully verified proof, the 32-byte word `0x00..01`; on any malformed input, unsupported config, or (in this skeleton) any path reaching the un-ported core, empty (`0x`). Never faults. - **Gas:** illustrative placeholder model `BASE_GAS(250,000) + numQueries * GAS_PER_QUERY(40,000) + GAS_PER_BYTE(3) * input.size()`, to be re-benchmarked on the frozen artifact. ### 4.9 Fork-registration summary (for a reimplementer) The five live precompiles are registered in `MainnetPrecompiledContracts.populateForFutureEIPs` (the `futureEips` milestone), gated by `futureEipsTime = 1783820272` (block 9,189,161). The two testnet precompiles add their `Address` constants (`AERE_MLKEM768`, `AERE_HASHTOPOINT`) and register into the same `populateForFutureEIPs` method in their patch, which is the pattern the mainnet five follow. Address band allocation: | Address | Precompile | Standard | Live on mainnet? | |---|---|---|---| | `0x0AE1` | Falcon-512 verify | NIST round-3 Falcon | Yes (block 9,189,161) | | `0x0AE2` | Falcon-1024 verify | NIST round-3 Falcon | Yes | | `0x0AE3` | ML-DSA-44 verify | FIPS 204 (internal) | Yes | | `0x0AE4` | SLH-DSA-SHA2-128s verify | FIPS 205 (internal) | Yes | | `0x0AE5` | SHAKE256 | FIPS 202 XOF | Yes | | `0x0AE6` | ML-KEM-768 encapsulation | FIPS 203 | No (testnet only) | | `0x0AE7` | Falcon HashToPoint | Falcon / FIPS 202 | No (testnet only) | | `0x0AE8` | Hash-based STARK verify (skeleton; BabyBear/FRI, targets Aere's own Plonky3 circuits, NOT SP1 6.1.0 which is Hypercube; see 4.8.3) | Plonky3 BabyBear FRI/STARK | No (reference skeleton) | The band `0x0AE1..0x0AE5` sits above the Ethereum standard precompiles, above the EIP-2537 BLS12-381 range, and above the RIP-7951 P-256 precompile at `0x100`, so upstream precompile allocations do not collide. If upstream Ethereum later allocates into this band, Aere will re-evaluate to preserve equivalence. ### 4.10 Consuming-contract note (not part of the precompile, but load-bearing for correct use) A `0x00..01` from a verify precompile establishes only that the signature is valid for the given public key and message. It does not establish freshness, ordering, replay protection, or key ownership. Consuming contracts add their own nonce and domain separation. `AerePQCAttestation` (`0x465d9E3b476BF98Aa1393079e240Db5D2a9bEA6A`), for example, supplies the 32-byte message itself and binds a per-key strictly increasing nonce, so a relayer can only pay gas and can never forge or replay. For hash-based schemes with one-time-per-leaf state (XMSS, WOTS+, which are pure-Solidity, not precompiles), a valid verification does not prove the signer has not reused a leaf; that state is the application's responsibility. --- ## 5. Fee and burn mechanics Aere makes two distinct, deliberately separated changes in the fee area. One is a protocol-layer base-fee floor. The other is an application-layer burn. **They must not be conflated, and neither is a consensus base-fee burn.** ### 5.1 The 1-Gwei EIP-1559 base-fee floor (protocol layer) - **What it is.** A minimum on the EIP-1559 base fee: from block **10,141,734**, the base fee on chain 2800 cannot fall below **1 Gwei = 1,000,000,000 wei**. Before that block the real minimum floored at 7 wei. - **Where it lives.** A single-file, fork-gated clamp in the fee-market logic (`LondonFeeMarket.java`), gated by client flags `aere.basefee.floor.forkBlock` and `aere.basefee.floor.value = 1000000000`. Both flags are dormant by default, so the build is byte-identical to the pre-floor binary before the fork block. The `BASEFEE` opcode (EIP-3198) returns this floored value. - **What it is not.** It is not a burn. It sets a minimum base fee; it does not change base-fee disposal. It is entirely separate from the burn in Section 5.2. - **Consensus impact.** None that can halt or split the chain: the QBFT header ruleset on chain 2800 lacks a base-fee gas-price validation rule (Section 3.6), so non-validators follow automatically and validators need the change only for base-fee consistency across proposers. 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.] ### 5.2 The validator-reward-cut burn (application layer) Aere's "burn" is a cut of the validator coinbase block reward, applied *above consensus* by a contract that validators (or their forwarder daemons) call each block. It is **not** an EIP-1559 protocol-level base-fee burn. **Splitter: `AereCoinbaseSplitterV2`.** A 3-way split of the validator coinbase reward, in basis points (`BPS = 10000`): | Bucket | Default | Cap | Destination | |---|---|---|---| | `burnBps` | 3750 (37.5%) | `MAX_BURN_BPS = 5000` (50%) | `AereFeeBurnVault` (direct burn) | | `sinkBps` | 1500 (15.0%) | `MAX_SINK_BPS = 3000` (30%) | `AereSink` (3-bucket router) | | `rebateBps` | 4750 (47.5%) | derived: `10000 - burnBps - sinkBps` | back to the validator | Rules a reimplementer must honor: - The rate is Foundation-settable via `setBps(_burnBps, _sinkBps)` but hard-bounded: `setBps` reverts if `_burnBps > MAX_BURN_BPS` (5000), if `_sinkBps > MAX_SINK_BPS` (3000), or if `_burnBps + _sinkBps > 10000`. The burn can never exceed 50%. - The splitter cannot custody AERE across calls: every `splitAndDistribute` / `splitToSelf` fully dispatches `msg.value` into the three buckets in one transaction. The sink bucket is wrapped via WAERE and routed through `IAereSink.flush()` atomically; if the sink call reverts, the whole transaction reverts and the validator retries. - The sink address is owner-settable but rate-limited by a 7-day timelock (`SINK_CHANGE_TIMELOCK`). Until a sink is set, the splitter behaves like V1 (no sink bucket; the 15% would be rebated instead). **Router: `AereSink`.** An immutable, ownerless 3-bucket router. Its invariants (verified in tests, `saere_architecture` design): - 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). - `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. **Why this is not a base-fee burn (design record).** Routing the burn through the coinbase layer rather than enshrining it in consensus keeps the burn out of the consensus-critical path (a burn-rate change cannot halt or fork the chain, whereas changing a consensus base-fee rule would be a hard fork), and it lets the *destinations* be made immutable at the contract layer while the *rate* stays a bounded, governable dial. What is sealed is not the rate but the endpoints. This document must not describe the Aere burn as a base-fee burn; it is a validator-reward-cut burn, rate-adjustable within a 50% ceiling, into immutable destinations. --- ## 6. Deliberate EIP deviations from Ethereum parity Aere tracks Ethereum's ruleset at Pectra plus Fusaka, so its EVM surface matches mainnet at the same addresses and opcodes, with one set of intentional deviations that follow from Aere being a QBFT chain with no separate beacon (consensus) layer and no blob data-availability market. A reimplementer must reproduce each of these deviations to match chain 2800. (Source: `AERE-EIP-COMPATIBILITY-MATRIX`.) Status vocabulary: **Supported** (matches Ethereum), **Partial** (present but materially limited), **Not implemented** (absent), **No-op** (present in the ruleset but neutralized, returns a defined zero/empty value under QBFT). | EIP | Name | Aere status | Deviation a reimplementer must reproduce | |---|---|---|---| | 1559 | Fee market | Partial | Fee-market mechanics present, plus the 1-Gwei base-fee floor from block 10,141,734 (Section 5.1). No consensus base-fee burn narrative; the "burn" is the separate validator-reward cut (Section 5.2). | | 3198 | BASEFEE opcode | Supported | Returns the current base fee, floored at 1 Gwei. | | 4844 | Blob transactions | Partial | Type-3 blob transactions exist in the EVM, but Aere runs no blob data-availability market; blobs carry no fee and are not served or persisted. | | 7516 | BLOBBASEFEE opcode | No-op | Returns 0. There is no blob market, so no blob base fee. | | 4788 | Beacon block root in the EVM | No-op | The beacon-root ring buffer returns `0x0`. A QBFT chain has no separate beacon layer to source a root from. | | 4895 | Beacon push withdrawals | No-op | The withdrawal-operation ruleset is present, but Aere has no beacon layer to originate withdrawals, so none are produced. | | 2935 | Historical block hashes | Supported (activated at AerePQC fork) | The 8191-block ring buffer at `0x0000F90827...2935`, populated on mainnet from block 9,189,161, not from Pectra (Section 4.6). | | 6110 | Validator deposits on chain | Partial | The deposit-request ruleset is tracked for Pectra parity, but no beacon layer consumes deposits; a deposit does not create or fund a QBFT validator (the set is QBFT-managed). | | 7002 | EL triggerable withdrawals/exits | Partial | Ruleset present, no beacon consumer; does not affect the QBFT validator set. | | 7251 | MAX_EFFECTIVE_BALANCE consolidations | Partial | Ruleset present, no beacon consumer. | | 7685 | General execution-layer requests | Partial | The requests umbrella (6110/7002/7251) exists in the ruleset, but no beacon layer consumes the requests. | | 7549 | Move committee index outside signature | Not implemented | Beacon consensus-layer change only; no EVM surface; not applicable under QBFT. | | 3074 | AUTH / AUTHCALL | Not implemented | Deliberately absent; superseded by EIP-7702, which is the EOA-delegation primitive Aere carries. | | 7702 | Set EOA account code | Supported | Matches Ethereum. The reason 3074 is not needed. | | 7825 | Per-transaction gas cap (2^24) | Supported | Enforced on chain 2800; the constraint that motivates the PQC precompiles. | | 7939 | CLZ opcode | Supported | Activated at the AerePQC milestone (block 9,189,161), not at Osaka (Section 4.7). | | 7594 | PeerDAS | Not implemented | No data-availability sampling role under QBFT (no blob market). | | 7805 | FOCIL (inclusion lists) | Not implemented | No fork-choice or proposer-inclusion layer to enforce inclusion lists against under QBFT. | | 7692 | EOF (EVM Object Format) | Not implemented | Not activated under the current ruleset; the `0xEF` lead byte stays reserved by EIP-3541 (legacy behavior). | **Deviations recap (the seven that matter):** 1. **Base-fee floor plus a validator-reward burn, not a consensus base-fee burn** (Sections 5.1, 5.2). 2. **EIP-4844 blobs present, EIP-7516 BLOBBASEFEE returns 0** (no blob market). 3. **EIP-4788 parent beacon block root returns `0x0`** (no beacon layer). 4. **EIP-3074 not implemented, superseded by EIP-7702**. 5. **PeerDAS (7594), FOCIL (7805), and EOF (7692) have no active role under QBFT** (0xEF stays reserved by EIP-3541). 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.] [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. --- ## 7. How to reimplement Aere's delta on a stock client This is the minimal, ordered checklist a stock Besu (or Nethermind) operator applies to match Aere Network on chain 2800. Each item points to the section that specifies it. ### 7.1 Chain configuration (genesis and forks) 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.) 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. ### 7.2 Client code changes (the AerePQC fork) 7. **Register five precompiles** at `0x0AE1..0x0AE5` in the `futureEips` precompile set, each wrapping the Bouncy Castle 1.83 BCPQC verifier for its scheme, behind a classloader-isolation boundary. Match the exact input parsing (Sections 4.2 to 4.5), the fixed gas per scheme, and the fail-closed behavior (32-byte zero word for `0x0AE1..0x0AE4`, empty for `0x0AE5`; never revert). 8. **Native EIP-2935 write path**: at block start, before user transactions, write the parent hash into slot `(number - 1) mod 8191` from the system address; serve reads within `[number - 8191, number - 1]`; ensure the history contract runtime at `0x0000F90827...2935` is the canonical Pectra runtime (deploy it via the keyless Nick's-method transaction so the block-0 state root is unchanged). (Section 4.6.) 9. **Activate EIP-7939 CLZ** at the same milestone. (Section 4.7.) 10. **Do NOT** activate EOF, PeerDAS, or FOCIL; keep `0xEF` reserved by EIP-3541; keep BLOBBASEFEE and the beacon-root buffer returning 0. (Section 6.) ### 7.3 Client code change (the base-fee floor) 11. **Add a fork-gated base-fee floor** in the fee-market logic: from block 10,141,734, clamp the EIP-1559 base fee to a minimum of 1,000,000,000 wei (1 Gwei). Keep it dormant (byte-identical to stock) before the fork block. (Section 5.1.) Roll it out across all validators for base-fee consistency; it cannot halt the chain. ### 7.4 Application layer (not a client change) 12. **Deploy the burn stack** and point the validators' coinbase forwarder daemon at `AereCoinbaseSplitterV2` (3-way split: `burnBps` default 3750 capped at 5000, `sinkBps` default 1500 capped at 3000, `rebateBps` derived), routing the sink bucket through the immutable `AereSink` and the burn bucket to the no-withdraw `AereFeeBurnVault`. (Section 5.2.) This is an off-chain operational wiring plus contracts, not a consensus rule. ### 7.5 What you do NOT change 13. The EVM instruction set (except CLZ), the gas schedule (except the precompile additions and the base-fee floor), transaction types, the state trie, RLP, receipts, logs, and JSON-RPC are all stock Pectra-plus-Fusaka. Do not modify them. 14. Consensus stays classical secp256k1 ECDSA QBFT. Do not add any post-quantum consensus rule; the precompiles are an application and account layer verification surface only. A client built to this checklist validates the live chain, re-executes chain-2800 blocks to byte-identical state roots, and runs the five PQC precompiles byte-for-byte. The reference second client (patched Nethermind 1.39.0) is exactly such a build and has re-validated the full chain to genesis and re-executed real blocks to identical hashes and state roots, and runs the 27/27 PQC KAT vectors identically. --- ## 8. Consolidated [VERIFY] register Every flag left open for a human to confirm before external publication: 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")`. 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`). 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). 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). --- ## Appendix A. Activation timeline (chain 2800) | 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. | | 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). | | Base-fee floor | 10,141,734 | `aere.basefee.floor.forkBlock` | 1-Gwei EIP-1559 base-fee floor. | ## Appendix B. Address registry (Aere-specific, live on mainnet) | Address | What | |---|---| | `0x0AE1` | Falcon-512 verify precompile | | `0x0AE2` | Falcon-1024 verify precompile | | `0x0AE3` | ML-DSA-44 verify precompile (FIPS 204 internal) | | `0x0AE4` | SLH-DSA-SHA2-128s verify precompile (FIPS 205 internal) | | `0x0AE5` | SHAKE256 precompile (FIPS 202) | | `0x100` | P-256 / secp256r1 verify (RIP-7212 / RIP-7951; shared with Ethereum Osaka) | | `0x0000F90827F1C53a10cb7A02335B175320002935` | EIP-2935 history-storage system contract (8191-block ring buffer) | | `0x465d9E3b476BF98Aa1393079e240Db5D2a9bEA6A` | AerePQCAttestation (consuming contract; input-layout oracle) | Non-live (specified in Section 4.8, not activated on mainnet): `0x0AE6` (ML-KEM-768, testnet), `0x0AE7` (Falcon HashToPoint, testnet), `0x0AE8` (hash-based STARK verify, reference skeleton; BabyBear/FRI, targets Aere's own Plonky3 circuits, NOT SP1 6.1.0 which is Hypercube, see 4.8.3). ## Appendix C. Build artifact of record - Base client: `hyperledger/besu:26.4.0`, base commit `d203201`. - Fork commits: `c8d2ef9` ("AERE PQC fork baseline (0x0AE1-0x0AE5)"), and `cc6bf56` (the two testnet precompiles `0x0AE6`/`0x0AE7`, not on mainnet). - Gold binary SHA-256: `7c5c0743088e9fa765d54c745814601b3c7a27a892e396156f88092b34c80772`. - Primitive library: Bouncy Castle `bcprov-jdk18on-1.83.jar` (Falcon, ML-DSA, SLH-DSA, SHAKE, ML-KEM), classloader-isolated on the client classpath. - Second client: patched Nethermind 1.39.0 (.NET), validation cross-check and PQC KAT re-runner; not a live producing validator. --- *End of specification. The post-quantum scope boundary is absolute: signatures, accounts, and the `0x0AE1..0x0AE5` precompiles verify post-quantum schemes; consensus (secp256k1 ECDSA QBFT) and the on-chain ZK verifiers (BN254 Groth16) are classical. Aere Network as a whole is not post-quantum, and no material derived from this document may claim otherwise.*