89 KiB
Aere Network Protocol Specification
Note added 2026-08-19. Statements in this document that consensus on chain 2800 is (or remains) classical secp256k1 ECDSA QBFT were written before the post-quantum header anchor went live, and remain true for block-by-block finality. Since block 13,014,000 anchor blocks (every 32nd block, on every one since block 13,889,296) also carry, under the block hash, a certificate of validator Falcon-512 seals, and since 2026-08-14 a node rejects an anchor block with fewer than three valid seals (f+1 of nine; eight or nine are carried in practice). That is a post-quantum checkpoint about every 16 seconds, not a per-block quorum: the claim published on 2026-08-15 that from block 14,050,000 no block finalizes without a post-quantum quorum was wrong (the per-block rule armed at that height is retired in the shipped code in favour of the anchor rules) and was withdrawn on 2026-08-19. Details: https://aere.network/quantum.html and the aere-node repository, anchor/README.md.
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:
- Ethereum execution semantics, as defined by the Ethereum execution-layer specifications ("execution-specs") and the Ethereum Yellow Paper, at the Pectra plus Fusaka ruleset.
- 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. 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.mdat 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.
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:
- 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.)
- 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.) - Two further precompiles built but not activated on mainnet (
0x0AE6ML-KEM-768,0x0AE7Falcon HashToPoint) and one reference skeleton (0x0AE8hash-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.) - 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.)
- 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:
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 live0x0AE1..0x0AE4precompiles, whose native source lives in the gold binary rather than the repository).aerenew/pqc-fork/precompiles/*.java(the source of the non-live0x0AE6,0x0AE7, and the0x0AE8skeleton).aere-contracts/contracts/AereCoinbaseSplitterV2.solandaere-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,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 } |
{
"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.
- Path. The transition array lives at
config.transitions.qbft, a sibling ofconfig.qbft, not inside it. Besu reads the keytransitionsfrom the config root (JsonGenesisConfigOptions.java:47) and then the sub keyqbft(TransitionsConfigOptions.getQbftForks()). Atransitionsarray placed insideconfig.qbftis never read, parses without error, and is silently inert. - Key. The key is
xblockperiodmilliseconds, with thexprefix, which marks it experimental in Besu (BftFork.java:48). The unprefixedblockperiodmillisecondsis not a Besu key and is silently ignored. - Block number.
2137652is 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, appliesTimestampMoreRecentThanParent(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.
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.
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
| 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):
"qbft": {
"blockperiodseconds": 1,
"epochlength": 30000,
"requesttimeoutseconds": 4
}
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).]
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,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, 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.
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.
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
extraDataheader 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
extraDataencodes the initial QBFT validator list. Inaere-genesis-current.jsonthe genesisextraDatais:0xf865a00000...0000f83f94b5e768cb3117ea25175f51aa956b48691025c2a894f73bbbd26a82dbc769066550d8d4585eab2fc00d944bf6f91d84b37454544279cba152581ed6820044c080c0which decodes to a three-validator genesis set:0xb5e768cb3117ea25175f51aa956b48691025c2a80xf73bbbd26a82dbc769066550d8d4585eab2fc00d0x4bf6f91d84b37454544279cba152581ed6820044
- 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 withecrecoverover 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
extraDatais 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,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
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:
- Five native post-quantum verification precompiles at the address band
0x0AE1..0x0AE5. - The native EIP-2935 historical-block-hash write path.
- 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..01if the signature is valid for the given public key and message,0x00..00if 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 iffret.length >= 32 && ret[31] == 0x01(this is exactly howAerePQCAttestation._verifydecides). - Malformed is indistinguishable from invalid. Because malformed input returns the same
0x00..00word 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/STATICCALLto 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 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 inaerenew/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: seeAERE-NIST-VALIDATION-STATUS.mdsection 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.
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):
HashToPoint: streamSHAKE256(nonce || message)and rejection-sample the challenge polynomialc(16-bit big-endian samples, keep valuesw < 5q = 61445, reduce modq), collectingncoefficients.- Decode the public key into
h(n coefficients, 14-bit packed; reject coefficients>= qand nonzero trailing bits). comp_decodethe compresseds2(sign bit, 7 low bits, unary high bits; reject "-0", overflow above 2047, buffer overrun, nonzero trailing bits, and any unconsumed trailing bytes).- Recompute
s1 = c - s2*hin the ring via negacyclic NTT convolution modq, centered into(-q/2, q/2]. - 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, dataabcreturns0x483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739=shake_256(b'abc').hexdigest(32).outLen = 32, empty data returns0x46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f=shake_256(b'').hexdigest(32).outLen = 64, dataabcreturns 64 bytes whose first 32 bytes match theoutLen = 32result (confirming squeezing).- The draft 4-byte framing
0x00000020616263returns0x(empty), not parsed under the shipped encoding.
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) / 32) + ceil(outLen / 32)
gas = SHAKE_BASE + SHAKE_WORD * words
= 60 + 12 * words
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 measuring0x0AE5on 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 whenlen(data) mod 32andoutLen mod 32are 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.]
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 8191by 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 thePraguePreExecutionProcessorsystem-address write. - Read path. A contract reads a historical hash by
STATICCALLto 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
BLOCKHASHopcode 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_getCodeat the address returns the canonical Pectra runtime, which encodes the 8191-block ring buffer.
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.
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)
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.ekis the ML-KEM-768 encapsulation (public) key;mis 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
mas the encapsulation randomness to Bouncy CastleMLKEMGenerator.internalGenerateEncapsulated(pub, m), so every node computes the identical(c, K). (The standard FIPS 203 Encaps drawsmfrom a CSPRNG, which cannot run in a consensus-critical precompile; takingmfrom calldata makes it deterministic.) - Fail-closed:
input.size() != 1216, or any thrownThrowable, returnsBytes.EMPTY. Source-verified fail-closed inMLKEM768PrecompiledContract.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), wherelognis 9 (Falcon-512, n=512) or 10 (Falcon-1024, n=1024). - Output:
2nbytes, that isncoefficients each a big-endianuint16in[0, q). - Behavior: absorb
nonce || messageinto a SHAKE256 sponge; repeatedly squeeze two bytes, interpret as a big-endian 16-bitw, keepw mod qwheneverw < 5q = 61445, untilncoefficients are collected (matches the referencehash_to_point_vartime). - Fail-closed: input length
< 41, orlognnot in{9, 10}, returnsBytes.EMPTY; any thrownThrowablereturnsBytes.EMPTY. - Gas:
BASE_GAS(60) + GAS_PER_WORD(12) * words, wherewords = ceil(absorbBytes/32) + ceil(squeezeBytes/32),absorbBytes = input.size() - 1, andsqueezeBytes = (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 onlyBASE_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 flagsaere.basefee.floor.forkBlockandaere.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. TheBASEFEEopcode (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.)
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:
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)
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:setBpsreverts 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/splitToSelffully dispatchesmsg.valueinto the three buckets in one transaction. The sink bucket is wrapped via WAERE and routed throughIAereSink.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, orpause. - 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). 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 unlessBURN_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 splittersinkBps/burnBpswithin their caps. Note: theAereCoinbaseSplitterV2source 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-derivedamountOutMinfloor (sandwich-resistant); a failed swap leaves the portion as re-flushable dust rather than reverting the whole flush. AereSinkdoes not custody funds across calls; everyflush(token, amount)fully dispatches into the three buckets. Residual dust (up to 2 wei per call from integer rounding) is re-flushable by a permissionlesssweepDust().
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):
- Base-fee floor plus a validator-reward burn, not a consensus base-fee burn (Sections 5.1, 5.2).
- EIP-4844 blobs present, EIP-7516 BLOBBASEFEE returns 0 (no blob market).
- EIP-4788 parent beacon block root returns
0x0(no beacon layer). - EIP-3074 not implemented, superseded by EIP-7702.
- PeerDAS (7594), FOCIL (7805), and EOF (7692) have no active role under QBFT (0xEF stays reserved by EIP-3541).
- Validator-lifecycle requests (6110/7002/7251/7685) have no beacon consumer (validator set is QBFT-managed).
- EIP-2935 became functionally live at the AerePQC fork (block 9,189,161), not at Pectra.
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 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.
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)
- Chain ID
2800. (Section 2.1.) - Genesis allocation: the six balances totaling 2.8B AERE at the exact addresses in Section 2.1.
- Genesis fields:
gasLimit = 0x1fffffffffffff,difficulty = 0x1,timestamp = 0x69fbd960,nonce = 0x0,mixHash = 0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365(a 32-byte vanity value, ASCII "ctical byzantine fault tolerance"), the genesiscoinbase = 0x0, and the genesis QBFTextraDataencoding 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.) - QBFT config:
blockperiodseconds = 1,epochlength = 30000,requesttimeoutseconds = 4, plus the transition{ "block": 2137652, "xblockperiodmilliseconds": 500 }. (Sections 2.2, 2.4.) - Fork schedule:
londonBlock = 0,shanghaiTime = 0,cancunTime = pragueTime = 1780189051,osakaTime = 1780220351,futureEipsTime = 1783820272. (Section 2.5.) - Enforce EIP-7825 (per-transaction cap 2^24), identical to Fusaka.
7.2 Client code changes (the AerePQC fork)
- Register five precompiles at
0x0AE1..0x0AE5in thefutureEipsprecompile 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 for0x0AE1..0x0AE4, empty for0x0AE5; never revert). - Native EIP-2935 write path: at block start, before user transactions, write the parent hash into slot
(number - 1) mod 8191from the system address; serve reads within[number - 8191, number - 1]; ensure the history contract runtime at0x0000F90827...2935is the canonical Pectra runtime (deploy it via the keyless Nick's-method transaction so the block-0 state root is unchanged). (Section 4.6.) - Activate EIP-7939 CLZ at the same milestone. (Section 4.7.)
- Do NOT activate EOF, PeerDAS, or FOCIL; keep
0xEFreserved by EIP-3541; keep BLOBBASEFEE and the beacon-root buffer returning 0. (Section 6.)
7.3 Client code change (the base-fee floor)
- 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)
- Deploy the burn stack and point the validators' coinbase forwarder daemon at
AereCoinbaseSplitterV2(3-way split:burnBpsdefault 3750 capped at 5000,sinkBpsdefault 1500 capped at 3000,rebateBpsderived), routing the sink bucket through the immutableAereSinkand the burn bucket to the no-withdrawAereFeeBurnVault. (Section 5.2.) This is an off-chain operational wiring plus contracts, not a consensus rule.
7.5 What you do NOT change
- 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.
- 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. Formal state-transition delta (the delta as a set of function modifications)
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.
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(thefutureEipsmilestone; 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
transitionsconfig 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_HASHvalue(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
ethwire protocol version the live chain-2800 node negotiates (the Besu 26.4.0 line;eth/68is 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).
[Section 2.3] Operative block gas limit on the live headCLOSED by measurement 2026-08-01. HeadergasLimitat head block 11,810,041 is0x1fffffffffffff= 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; aneth_callabove that cap succeeded,eth_estimateGasdoes not discriminate, and the only conclusive probe is a transaction above the cap, which we do not send.- [Section 2.4] Inline fork/transition fields in the running config.
aere-genesis-current.jsonin the repo lacks the block-period transition and the Cancun/Prague/Osaka/futureEips time fields; confirm the authoritative running config carries them. [Section 2.5] Pectra and Osaka block heightsCLOSED 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).[Section 3.2] The seven live validator addresses at the current headCLOSED 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 genesisextraData, which is why the head must be read rather than derived.- [Section 4.2] The low-level
smbyte order the native0x0AE1/0x0AE2parser expects, against the gold-binary precompile source or the conformance vectors (this spec uses the orderAerePQCAttestation._buildInputbuilds). - [Section 4.5] Any
outLenupper bound enforced by the live0x0AE5SHAKE256 precompile. - [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).
- [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.
- [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'sfutureEipskey (EOF's usual staging ground). - [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).
- [Section 9.1] The concrete EIP-2124 / EIP-6122
FORK_HASHfor 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. - [Section 9.3] The maximum negotiated
ethwire protocol version on the live node (Besu 26.4.0 line;eth/68expected). The transport and message set are stock, not an Aere delta.
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,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). |
| 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 commitd203201. - Fork commits:
c8d2ef9("AERE PQC fork baseline (0x0AE1-0x0AE5)"), andcc6bf56(the two testnet precompiles0x0AE6/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.