diff --git a/README.md b/README.md index c150f01..0e2199e 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ seals at first (f+1 of nine), six of nine, as many as the QBFT quorum of nine (c validators on 2026-09-05) the anchor fell on every 128th block instead of every 32nd, with both schemes at every anchor; since block 20,746,736 (AIP-22 stage 2) Falcon-512 is required at every 32nd block again and SLH-DSA-SHA2-128s at every 128th. Since block 20,836,228 (AIP-22 stage 3) the -header and `qbft_getValidatorsByBlockNumber` name the validators by post-quantum ids. QBFT finalizes every block, whose votes every validator attributes, since block 24,300,000 (AIP-22 stage 4), only through their verified post-quantum seals (headers are still admitted on their ECDSA commit seals until AIP-22 stage 5), and node identity and transport (RLPx) remain classical; the QBFT +header and `qbft_getValidatorsByBlockNumber` name the validators by post-quantum ids. QBFT finalizes every block, whose votes every validator attributes, since block 24,300,000 (AIP-22 stage 4), only through their verified post-quantum seals (since block 25,080,000, AIP-22 stage 5, headers no longer carry ECDSA commit seals and are admitted on the Falcon-512 seal of their proposer alone; a commit still carries the ECDSA commit seal of its validator as an additional check), and node identity and transport (RLPx) remain classical, as does the ECDSA envelope that every consensus message still carries on the wire, whose form both clients judge and which no longer names its author on the Besu-derived validators; the QBFT messages themselves carry post-quantum seals of their authors on the live fleet (emission since blocks 16,620,000 to 16,690,000), with refusal of unsealed messages armed for blocks 17,250,000 to 17,700,000 (set 2026-09-05; see `anchor/README.md`, the arming table). Correction 2026-08-19: the diff --git a/SECURITY.md b/SECURITY.md index dfba02c..6a44e3e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -38,7 +38,7 @@ pointer is . every 32nd block (every 128th from block 17,225,968 to block 20,746,736) carries a post-quantum certificate under the block hash (Falcon-512, and from block 17,047,600 also SLH-DSA-SHA2-128s, at every 128th block since block 20,746,736), requiring at least seven valid seals of each scheme - since block 20,715,632, as many as the quorum of the ten validators (six from block 14,961,456, six of nine validators then); below block 24,148,752 the seals proved those validators signed the block, not that it was decided (AIP-22 erratum, 2026-10-01), and from that block a certificate that carries the quorum of one round proves the decision. Blocks between anchors carry no certificate of their own and are decided by QBFT, whose votes every validator attributes, since block 24,300,000 (AIP-22 stage 4), only through their verified post-quantum seals (headers are still admitted on their ECDSA commit seals until AIP-22 stage 5); between anchors a node that does not take part in consensus checks only their headers (this sentence corrected on 2026-10-28: it said that blocks between anchors rest on ECDSA). We correct + since block 20,715,632, as many as the quorum of the ten validators (six from block 14,961,456, six of nine validators then); below block 24,148,752 the seals proved those validators signed the block, not that it was decided (AIP-22 erratum, 2026-10-01), and from that block a certificate that carries the quorum of one round proves the decision. Blocks between anchors carry no certificate of their own and are decided by QBFT (this sentence corrected on 2026-10-28: it said that blocks between anchors rest on ECDSA): since block 24,300,000 (AIP-22 stage 4) every vote counts only with the verified post-quantum seal of its author, and a commit still carries the ECDSA commit seal of its validator as an additional check; their headers were admitted on their ECDSA commit seals until block 25,080,000 (AIP-22 stage 5), and from it a node that does not take part in consensus admits a header between anchors on the Falcon-512 seal of its proposer alone, so the post-quantum key of one validator can serve such a node a branch up to the block before the next anchor (below block 25,080,000 that took the ECDSA keys of a quorum), and the next anchor ends it for a node that requires the seals of a quorum in its certificate (the published follower, with its seal ceiling at 1, is not such a node: for it one leaked or misused post-quantum key of a validator makes the rewrite depth unbounded, section 6.4 of the aere-node SPEC). We correct over-claims publicly when we find them, and we have done so before. ## Fixes diff --git a/SPEC.md b/SPEC.md index 2673c58..0bd68f5 100644 --- a/SPEC.md +++ b/SPEC.md @@ -240,13 +240,14 @@ negative control shows a majority quorum forks) (source: | 1 | `validators` | RLP list of 20-byte entries: ECDSA addresses, and from `aere.pq.identityBlock` (AIP-22 stage 3; block 20,836,228 on chain 2800) post-quantum validator ids | | 2 | `vote` | empty RLP list when no vote; else `RLP[recipient(20 bytes), voteValue]` with the add/drop byte values defined in upstream Besu's `Vote` class | | 3 | `round` | int scalar | -| 4 | `committedSeals` | RLP list of ECDSA (secp256k1) commit signatures | -| 5 | the anchor certificate (Aere, optional; carried only at anchor heights) | present ONLY in the stored-header encoding and ONLY when non-empty. Its form is chosen by height alone and is defined HERE, once (rewritten 2026-10-14; until then this row named only the first form): **v1**, from block 13,014,000: RLP list of `[validatorIndex intScalar, falconSignature bytes]` pairs, indices strictly increasing; **v2**, from block 17,047,600 (`aere.pq.anchorV2Block`): `RLP[2, [[scheme intScalar, validatorIndex intScalar, signature bytes], ...]]`, scheme 1 = Falcon-512, 2 = SLH-DSA-SHA2-128s, rows in canonical order; **v3**, from `H_r` (`aere.pq.commitRoundBlock`, AIP-22 stage R, patch 0010; block 24,148,752 on chain 2800, where it was not yet set as of 2026-10-14; 6,157,024 on testnet 28001 since 2026-10-14): `RLP[3, round intScalar, [[scheme, validatorIndex, signature], ...]]`, every seal over the commit message of that one round (section 2.6), the round written once, before the list, so that a v2 reader refuses a v3 certificate instead of counting its seals. The digest of the carried certificate, under the block hash, is element 0 (section 3.3) | +| 4 | `committedSeals` | RLP list of ECDSA (secp256k1) commit signatures below `aere.pq.headerBlock` (`H_hdr`, AIP-22 stage 5; block 25,080,000 on chain 2800, 2026-10-30); an empty list from it | +| 5 | the anchor certificate (Aere, optional; carried at anchor heights; from `H_hdr` present on every header, as an empty list where there is no certificate) | present ONLY in the stored-header encoding; below `H_hdr` ONLY when non-empty. Its form is chosen by height alone and is defined HERE, once (rewritten 2026-10-14; until then this row named only the first form): **v1**, from block 13,014,000: RLP list of `[validatorIndex intScalar, falconSignature bytes]` pairs, indices strictly increasing; **v2**, from block 17,047,600 (`aere.pq.anchorV2Block`): `RLP[2, [[scheme intScalar, validatorIndex intScalar, signature bytes], ...]]`, scheme 1 = Falcon-512, 2 = SLH-DSA-SHA2-128s, rows in canonical order; **v3**, from `H_r` (`aere.pq.commitRoundBlock`, AIP-22 stage R, patch 0010; block 24,148,752 on chain 2800, where it was not yet set as of 2026-10-14; 6,157,024 on testnet 28001 since 2026-10-14): `RLP[3, round intScalar, [[scheme, validatorIndex, signature], ...]]`, every seal over the commit message of that one round (section 2.6), the round written once, before the list, so that a v2 reader refuses a v3 certificate instead of counting its seals. The digest of the carried certificate, under the block hash, is element 0 (section 3.3). From `H_hdr`, when element 6 is present, element 5 is present too, as an empty list where the header carries no certificate (AIP-22 section 5; added 2026-10-30). | +| 6 | `proposerSeal` (Aere, AIP-22 stage 5; from `H_hdr`) | `RLP[validatorIndex intScalar, falconSignature bytes]`: the Falcon-512 seal of the proposer over `keccak256(RLP["AERE-PQ-PROPOSAL-1", chainId, height, round, proposalDigest])`, the round being element 3 and `proposalDigest` the hash of the `EXCLUDE_COMMIT_SEALS` encoding; present only in the stored-header encoding, outside both hashes like elements 4 and 5 (section 3.4 states the rule; added 2026-10-30) | Three encodings exist, and which elements they carry is consensus-critical (source: same file, `encode(...)`): -- `ALL` (stored header): all six elements; element 5 omitted when the certificate is empty. +- `ALL` (stored header): below `H_hdr` six elements, element 5 omitted when the certificate is empty; from `H_hdr` seven, element 4 an empty list, element 5 present (an empty list where the header carries no certificate) and element 6 the proposer seal (AIP-22 section 5; added 2026-10-30). - `EXCLUDE_COMMIT_SEALS` (the ECDSA commit-seal signing pre-image): round kept, committedSeals written as an empty list, falconSeals omitted. - `EXCLUDE_COMMIT_SEALS_AND_ROUND_NUMBER` (the block-hash pre-image): round forced to 0, @@ -256,11 +257,9 @@ Three encodings exist, and which elements they carry is consensus-critical (sour `EXCLUDE_COMMIT_SEALS_AND_ROUND_NUMBER` form, not over the stored bytes.** Consequences a client must implement and must not "fix": -1. The ECDSA commit seals, the round number, and the entire Falcon certificate are NOT covered by - the block hash. Stripping or replacing the certificate leaves the hash unchanged (it is caught +1. The ECDSA commit seals, the round number, the entire Falcon certificate and, from `H_hdr`, the proposer seal of element 6 are NOT covered by the block hash. Stripping or replacing the certificate leaves the hash unchanged (it is caught by validation instead: section 3.4). -2. Two correct neighbours can legally store different extraData bytes for the same block hash: - every node assembles its final header locally from the commits it heard. Measured on the live +2. Below `H_hdr` (block 25,080,000 on chain 2800, AIP-22 stage 5) two correct neighbours can legally store different extraData bytes for the same block hash: every node assembles its final header locally from the commits it heard. From `H_hdr` element 4 is empty and element 6 is the seal of the proposal accepted in the round in which a node committed the block, so nodes that committed a block in the same round store the same bytes, and only the round (element 3) and the proposer seal of that round (element 6) can still differ under the same hash, for a block that nodes committed in different rounds (a value locked in one round and proposed again in a later one); a node that imports the block stores the form of the node that served it (source: `anchor/consensus/qbft/.../QbftRound.java`, which seals with the round of its own commit and the proposer seal of that round). Measured on the live chain: over 200 consecutive headers read simultaneously from two Aere RPC nodes with identical block hashes 200/200, the ECDSA seal ORDER differed on 68 headers and the seal SET differed on 11 (source: `anchor/consensus/common/.../PqAnchor.java`, class javadoc, which cites this @@ -285,19 +284,17 @@ the codec (source: `QbftExtraDataCodec.java`, `decodeRaw`, the two commented gat 2. **Canonical round trip**: the decoded structure re-encoded in `ALL` form must reproduce the received bytes exactly, or the header is rejected. This closes, among other shapes, the "explicit empty Falcon list" ambiguity: an empty certificate must be OMITTED, and a header that - carries an explicit empty list is non-canonical and rejected. Every header any Aere or stock - Besu node ever produced round-trips unchanged, so the whole pre-anchor history still decodes. + carries an explicit empty list is non-canonical and rejected. Every header any Aere or stock Besu node ever produced round-trips unchanged, so the whole pre-anchor history still decodes. (Amended 2026-10-30, AIP-22 stage 5: from `H_hdr` element 5 is written as an explicit empty list when element 6 is present, and only then; a six-element header whose element 5 is an empty list is not canonical and is refused.) ### 2.5 What QBFT header validation on chain 2800 checks, and one thing it does not The QBFT ruleset validates ancestry, timestamp, gas usage and gas-limit bounds, the constant -difficulty, mixHash, coinbase, the validator set and the ECDSA commit seals, plus the Aere rules of -section 3. It does **not** recompute the EIP-1559 base fee at import: Besu's +difficulty, mixHash, coinbase, the validator set and the ECDSA commit seals below `H_hdr` (the proposer seal of element 6 from it, section 3.4), plus the Aere rules of section 3. It does **not** recompute the EIP-1559 base fee at import: Besu's `BaseFeeMarketBlockHeaderGasPriceValidationRule` is registered only by the Clique and Merge rulesets, not by QBFT, upstream or in this fork [MEASURED 2026-08-02, by reading the ruleset factory and grepping `consensus/`; recorded in `RUN-A-NODE.md`, "Which Besu", and in `../../docs`-level runbook history]. The base fee is ratified through the quorum's commit seals -over the block hash, which commits to it. Section 5 states what this means for a client that DOES +over the block hash, which commits to it. (Below `H_hdr` those commit seals sit in the header; from `H_hdr`, block 25,080,000 on chain 2800, the header carries instead the proposer's Falcon-512 seal over the proposal digest, which commits to it as well, and the decision of the quorum is certified by the next anchor; added 2026-10-30.) Section 5 states what this means for a client that DOES validate base fees. ### 2.6 Consensus messages under post-quantum seal (emission live since 2026-09-02; enforcement armed by height on 2026-09-05) @@ -521,9 +518,7 @@ schedule: 0 from 13,014,000 (warm-up), 3 from 13,034,000 (f+1 of the nine valida The defensible sentence, and the only form this document endorses: *every anchor block (every 32nd block; every 128th from 17,225,968 to 20,746,736) does not -finalize without a certificate of at least seven valid Falcon-512 validator seals, as many as the quorum of the ten validators, under its hash (seven since block 20,715,632; six from block 14,961,456 and three before it; see the schedule and the historical windows)*. Blocks between -anchors carry no Falcon seals in the header and their header is finalized by the ECDSA committed -seals alone. *Amended 2026-09-17:* the consensus MESSAGES that produce every block (proposal, +finalize without a certificate of at least seven valid Falcon-512 validator seals, as many as the quorum of the ten validators, under its hash (seven since block 20,715,632; six from block 14,961,456 and three before it; see the schedule and the historical windows)*. Until block 25,080,000 (AIP-22 stage 5) blocks between anchors carried no Falcon seals in the header and their header was admitted on the ECDSA committed seals alone; from it each header carries the Falcon-512 seal of its proposer instead, which admits it, while the commit quorum of one round decides the block; a node that does not take part in consensus admits a header between anchors on the Falcon-512 seal of its proposer alone, so the post-quantum key of one validator can serve such a node a branch up to the block before the next anchor (below block 25,080,000 that took the ECDSA keys of a quorum), and the next anchor ends it for a node that requires the seals of a quorum in its certificate (the published follower, with its seal ceiling at 1, is not such a node: for it one leaked or misused post-quantum key of a validator makes the rewrite depth unbounded, section 6.4 of the aere-node SPEC). *Amended 2026-09-17:* the consensus MESSAGES that produce every block (proposal, prepare, commit, round-change) carry post-quantum seals; every validator requires them on commits, the nine validators that run the primary client require them on all four since 2026-09-08, and the second client applies the rule to the other three from AIP-22 stage 4, whose height is not yet set @@ -534,8 +529,7 @@ messages in that validator's name to the second client. Alone, that misleads one below `f` = 3, whose own commits stay sealed with its own key; combined with `f` Byzantine validators, the misled second client would count as one more faulty node, and that case is not analyzed (*Corrected 2026-10-09:* until that date this paragraph said that all four messages "carry -and require" seals, without the second client's exception). Node identity and transport (RLPx) -remain classical secp256k1 ECDSA, and so does the per-block header artifact between anchors. The anchor is a binding, not a +and require" seals, without the second client's exception). Node identity and transport (RLPx) remain classical secp256k1 ECDSA, and so did the per-block header artifact between anchors until block 25,080,000 (AIP-22 stage 5), which carries the Falcon-512 seal of its proposer from that block; a commit still carries the ECDSA commit seal of its validator as an additional check, and every consensus message still carries the ECDSA envelope of the upstream wire format, whose form both clients judge and which, since block 24,300,000 (AIP-22 stage 4), no longer names its author on the Besu-derived validators (AIP-22, section 5). The anchor is a binding, not a replacement, and "post-quantum consensus" without these qualifications overstates (source: `anchor/README.md`, section 2.6 as amended). None of this code has been audited by a third party (source: `anchor/README.md`, "What is not proven here"). @@ -548,9 +542,8 @@ against the four known mitigation families and states what it does NOT claim, in safety). Security property bought by the interval: an adversary holding every classical validator key and no -Falcon key can rewrite at most the tail since the last anchor, so fork depth <= 32 blocks since -block 20,746,736 (about 20 seconds at the measured rhythm; <= 128 blocks, about 75 seconds, from block -17,225,968 to block 20,746,736; <= 32 blocks, about 16 seconds, before that); rewriting anything below an anchor changes that anchor's parent hash, forces the +Falcon key can rewrite, below block 25,080,000 (AIP-22 stage 5), at most the tail since the last anchor, so fork depth <= 32 blocks since block 20,746,736 (about 20 seconds at the measured rhythm; <= 128 blocks, about 75 seconds, from block +17,225,968 to block 20,746,736; <= 32 blocks, about 16 seconds, before that), and from block 25,080,000 it can produce no header a node admits (section 3.4); rewriting anything below an anchor changes that anchor's parent hash, forces the anchor to be reproduced, and reproducing it requires Falcon signatures the adversary does not have. Added 2026-10-01 (AIP-22 erratum of that date): the certificate's seals carry no round, so an anchor can be certified over the undecided sibling of the decided block, with honest validators' seals, if @@ -866,6 +859,8 @@ the startup guard `AERE-PQC-THRESHOLD-02` refuses an effective threshold step ab the set, and `AERE-PQC-ROUND-01` refuses an `H_r` that is not an armed anchor height above the v2 height (section 3.7). Below `H_r` nothing in this paragraph runs. +**From `H_hdr`, `PqHeaderSealRule` (AIP-22 stage 5; added 2026-10-30).** It replaces the upstream committed-seal rule (`BftCommitSealsValidationRule`), which it applies unchanged below `H_hdr` (block 25,080,000 on chain 2800), so below that height a header is admitted on a quorum of ECDSA committed seals of the parent's validators, exactly as upstream (source: `anchor/consensus/qbft/.../headervalidationrules/PqHeaderSealRule.java`). From `H_hdr` a header, anchors included, is admitted iff: element 4 (the ECDSA committed seals) is empty; element 6 carries a proposer seal; the round in element 3 is between 0 and 1024; with the parent known, the `coinbase` is the proposer of some round from 0 to that round (it built the block); the seal's index names, in the v3 epoch in force at the header's height, the `coinbase` `id` or, at a round above zero, the `id` of the proposer of that round, computed from the parent's `coinbase` and the header's validator list (a block re-proposed unchanged in a later round keeps its builder's `coinbase` and carries the later proposer's seal, AERE D-406); and the seal verifies over `keccak256(RLP["AERE-PQ-PROPOSAL-1", chainId, height, round, proposalDigest])`, with `proposalDigest` recomputed from the stored header. An anchor is judged by R1 and R2 as well. The proposer seal admits a header; it does not decide the block: for a validator a block is final on import, as before, and its post-quantum proof is the anchor that covers it (AIP-22 section 4). This rule is what admits a header between anchors: a node that does not take part in consensus admits a header between anchors on the Falcon-512 seal of its proposer alone, so the post-quantum key of one validator can serve such a node a branch up to the block before the next anchor (below block 25,080,000 that took the ECDSA keys of a quorum), and the next anchor ends it for a node that requires the seals of a quorum in its certificate (the published follower, with its seal ceiling at 1, is not such a node: for it one leaked or misused post-quantum key of a validator makes the rewrite depth unbounded, section 6.4 of the aere-node SPEC). + **`PqRegistryBindingRule`** and **`PqEmergencyShoutRule`** are also registered: the former is part of the registry-binding machinery, the latter only logs (it makes a disarmed-but-configured node shout at every block) (source: `QbftBlockHeaderValidationRulesetFactory.java`). @@ -1209,9 +1204,8 @@ answer, and `run-node.sh` does not set it. - Between anchor heights, headers carry no Falcon element (extraData 634 bytes at N=9); at anchor heights they carry element 5 and a digest in vanityData (2,516+ bytes) [MEASURED 2026-08-09 on the live chain; recorded in the repository operating notes; sizes are descriptive, not - normative]. -- Stored extraData for the same block can differ between peers (section 2.3); only the hash - pre-image is canonical. + normative]. From `H_hdr` (block 25,080,000 on chain 2800, AIP-22 stage 5; added 2026-10-30) every header carries element 6, the Falcon-512 seal of its proposer, and element 4 is empty. +- Stored extraData for the same block can differ between peers below `H_hdr` (section 2.3); from `H_hdr` (block 25,080,000) nodes that committed a block in the same round store the same bytes, and only the round (element 3) and the proposer seal of that round (element 6) can still differ under the same hash, for a block that nodes committed in different rounds (a value locked in one round and proposed again in a later one); a node that imports the block stores the form of the node that served it. Only the hash pre-image is canonical. - The full from-genesis import of exactly this bundle's patches reached the live tip (height 14,088,211) and followed it, with zero anchor rejections and zero state mismatches, after the two historical windows and the H boundary alignment were carried; the consensus test suites stood at @@ -1354,8 +1348,7 @@ RETIRED rule and changed no enforcement.** The fleet was configured on 2026-08-1 intended as a per-block blocking Falcon quorum, and public material said so. In the shipped code the rule it arms (`FalconSealValidationRule`) retires at the anchor activation height 13,014,000 in favour of the anchor rules (`PqAnchorConfig.legacyFalconRuleRetirementBlock`), so at 14,050,000 it -was already inert. The chain itself confirms it: blocks between anchors carry no Falcon seals, -which a per-block rule would have rejected. The earlier public statement that from 14,050,000 every +was already inert. The chain itself confirms it: blocks between anchors carried no Falcon seals (from block 25,080,000, AIP-22 stage 5, each carries one, the seal of its proposer, never a quorum), which a per-block rule would have rejected. The earlier public statement that from 14,050,000 every block required a 2f+1 Falcon quorum to finalize is WITHDRAWN; nothing changed at that height (source: `anchor/README.md`, correction paragraph; `RUN-A-NODE.md`, correction paragraph; code: `FalconSealValidationRule.java`, `PqAnchorConfig.java`). A follower leaves diff --git a/anchor/README.md b/anchor/README.md index 16e518e..32a5fe9 100644 --- a/anchor/README.md +++ b/anchor/README.md @@ -10,7 +10,7 @@ demonstrable from these files is marked as not demonstrable from these files. ## Scope boundary, stated first and not in a footnote -**Consensus on Aere Network chain 2800 is QBFT with a post-quantum checkpoint enforced every 32 blocks (every 128 from block 17,225,968 to block 20,746,736); since block 24,300,000 (AIP-22 stage 4) every validator attributes each consensus vote only through the verified post-quantum seal of its author (headers are still admitted on their ECDSA commit seals until AIP-22 stage 5).** This code is what adds the checkpoint, in two steps that +**Consensus on Aere Network chain 2800 is QBFT with a post-quantum checkpoint enforced every 32 blocks (every 128 from block 17,225,968 to block 20,746,736); since block 25,080,000 (AIP-22 stage 5) headers no longer carry ECDSA commit seals and, since block 24,300,000 (AIP-22 stage 4), every vote counts only with the verified post-quantum seal of its author, and a commit still carries the ECDSA commit seal of its validator as an additional check, which we call post-quantum consensus, with three limits: the transport between nodes is still authenticated by secp256k1, the ten validators are run by one operator, and no third party has audited it yet.** This code is what adds the checkpoint, in two steps that should not be confused: 1. **The binding.** From block 13,014,000 the block hash of every anchored header (every 32nd @@ -31,7 +31,7 @@ should not be confused: The schedule is `aere.pq.anchorMinSeals=13014000:0,13034000:3,14961456:6,17102384:0,17102416:6,20715632:7`, uniform on all ten validators; the startup guard refuses any threshold above N - f = 7, the highest count reachable with the fault - budget down. Blocks between anchors carry no certificate of their own (headers are still admitted on their ECDSA commit seals until AIP-22 stage 5), and since block 24,300,000 (AIP-22 stage 4) every validator attributes their votes only through verified post-quantum seals, so the post-quantum certificate is a checkpoint about every 20 seconds (32 blocks since block 20,746,736; + budget down. Blocks between anchors carry no certificate of their own (since block 25,080,000, AIP-22 stage 5, headers no longer carry ECDSA commit seals and are admitted on the Falcon-512 seal of their proposer alone; a commit still carries the ECDSA commit seal of its validator as an additional check), and since block 24,300,000 (AIP-22 stage 4) every validator attributes their votes only through verified post-quantum seals, so the post-quantum certificate is a checkpoint about every 20 seconds (32 blocks since block 20,746,736; 128 blocks, about 75 seconds, from block 17,225,968 to block 20,746,736; 32 blocks, about 16 seconds, before that), not a per-block quorum. 3. **The hybrid certificate.** Since block 17,047,600 (2026-09-04) the certificate is the v2, scheme-tagged @@ -58,12 +58,11 @@ Correction 2026-08-19: the fleet was also configured on 2026-08-15 with `aere.fa at 14,050,000, intended as a per-block blocking Falcon quorum. In the shipped code that rule (`FalconSealValidationRule`) is retired at `aere.pq.anchorBlock` (13,014,000) in favour of the anchor rules (`PqAnchorConfig.legacyFalconRuleRetirementBlock`), so at 14,050,000 it was already -inert, and the chain itself confirms it: blocks between anchors carry no Falcon seals, which a -per-block quorum rule would have rejected. The earlier statement in this repository that from +inert, and the chain itself confirms it: blocks between anchors carried no Falcon seals (from block 25,080,000, AIP-22 stage 5, each carries one, the seal of its proposer, never a quorum), which a per-block quorum rule would have rejected. The earlier statement in this repository that from 14,050,000 every block required a 2f+1 Falcon quorum to finalize is withdrawn. "Hybrid" is the honest word in two senses and no more: the checkpoint sense above and, since -2026-09-04, the two-scheme certificate. "Post-quantum consensus" without qualification still overstates: since block 24,300,000 (AIP-22 stage 4) every validator attributes a consensus vote only through its verified post-quantum seal (headers are still admitted on their ECDSA commit seals until AIP-22 stage 5), and the transport between nodes is still authenticated by secp256k1 (this sentence corrected on 2026-10-26: until that date it also called per-block finality and validator identity classical, and validator identity has been post-quantum since block 20,836,228, AIP-22 stage 3). The +2026-09-04, the two-scheme certificate. "Post-quantum consensus" is the word since block 25,080,000 (AIP-22 stage 5), in this sense: headers no longer carry ECDSA commit seals and, since block 24,300,000 (AIP-22 stage 4), every vote counts only with the verified post-quantum seal of its author, and a commit still carries the ECDSA commit seal of its validator as an additional check; its limits are stated with it: the transport between nodes is still authenticated by secp256k1, the ten validators are run by one operator, and no third party has audited it yet (this sentence corrected on 2026-10-26: until that date it also called per-block finality and validator identity classical, and validator identity has been post-quantum since block 20,836,228, AIP-22 stage 3) (corrected on 2026-10-30, at AIP-22 stage 5: until that day this sentence said that "post-quantum consensus" without qualification overstates). The four QBFT message types carry a post-quantum seal of their author on chain 2800 since blocks 16,620,000 (PROPOSAL), 16,660,000 (ROUND-CHANGE) and 16,690,000 (PREPARE), COMMIT seals since the anchor itself; and a message without a valid seal is REFUSED by the Besu-derived validators from @@ -76,11 +75,11 @@ Besu-derived client, the whole set in September; the tenth validator, admitted a runs the second, Nethermind-derived client, which refuses an unsealed commit since block 18,131,633 and applies the rule to proposal, prepare and round-change messages since block 24,300,000 (AIP-22 stage 4, 2026-10-25).) What a quantum adversary cannot do at any height is rewrite history past the last anchor without also forging -Falcon-512 and SLH-DSA-SHA2-128s signatures (added 2026-10-01, AIP-22 erratum of that date: except the +Falcon-512 and SLH-DSA-SHA2-128s signatures (Added 2026-10-01, AIP-22 erratum of that date: except the last anchor's parent while headers carry ECDSA seals, before stage 5 of AIP-22, since an anchor can be certified, with honest validators' seals, over the undecided sibling of the decided block; measured in a test fixture with the production rules, not exercised on any network; SPEC.md, interval -section) (Note added 2026-10-26: from block 24,148,752, AIP-22 stage R, a certificate whose quorum is of one round closes the exception for a validator; a follower that accepts a certificate below that quorum, such as the published follower with its ceiling at 1, keeps it; SPEC.md, interval section.). None of this has been audited by a third party. +section) (Note added 2026-10-26: from block 24,148,752, AIP-22 stage R, a certificate whose quorum is of one round closes the exception for a validator; a follower that accepts a certificate below that quorum, such as the published follower with its ceiling at 1, keeps it; SPEC.md, interval section.) (Note added 2026-10-30: from block 25,080,000, AIP-22 stage 5, the header of an anchor also needs the Falcon-512 seal of its proposer.). None of this has been audited by a third party. The threat it addresses is not "harvest now, decrypt later". A signature is public; there is nothing to harvest. The threat is **retroactive rewriting**: validator keys recovered later can be used to @@ -202,7 +201,7 @@ This matters more than the file list, so it is stated before it. | The post-quantum commit seal bound to the consensus round (COMMIT-2) and the v3 anchor certificate (AIP-22 stage R, `aere.pq.commitRoundBlock`, patch 0010) | yes (added 2026-10-14) | **yes**, since block 24,148,752 (2026-10-24); on testnet 28001 since block 6,157,024 | | Message authorship from VERIFIED post-quantum seals, with the startup guards AERE-PQC-FIN-01/02/03 (AIP-22 stage 4, `aere.pq.finalityBlock`) | yes (added 2026-09-23) | **yes**, since block 24,300,000 (2026-10-25); on testnet 28001 since block 3,117,000 | | Checkpoint option, a header rule that refuses another hash at a checkpoint height (AIP-22 stage 4, `aere.pq.checkpoint`) | yes (added 2026-09-23) | **no**; not configured anywhere | -| Headers without ECDSA committed seals, sealed by the proposer's post-quantum seal as extraData element 6 (AIP-22 stage 5, `aere.pq.headerBlock`, guards AERE-PQC-HDR-01/02) | yes (added 2026-09-23) | **no**; proven on testnet 28001 only (H_hdr 3,131,000) | +| Headers without ECDSA committed seals, sealed by the proposer's post-quantum seal as extraData element 6 (AIP-22 stage 5, `aere.pq.headerBlock`, guards AERE-PQC-HDR-01/02) | yes (added 2026-09-23) | **yes**, since block 25,080,000 (2026-10-30); on testnet 28001 since block 3,131,000 (in its corrected form since 2026-09-26) | | The hybrid (SLH-DSA) seal of a commit judged, from the v3 key height, with the key of the v3 epoch in force (a rotated row signs with its new key) | yes (corrected 2026-09-23) | **yes**, since block 20,836,228 (the v3 epoch of chain 2800); on testnet 28001 since 2026-09-23 22:51Z | Everything not yet in force is **disarmed by absence or by height, never by a flag**: the properties that arm them @@ -225,7 +224,7 @@ proposal without a valid Falcon seal from its own proposer does not open a round its own domain over (chainId, height, round, digest), so an honest proposal seal cannot be replayed as a vote nor a vote seal as a proposal - both directions are tested. The ROUND-CHANGE message carries its own seal since 2026-08-31 (its embedded justifications are coupled to PREPARE -enforcement). What remains classical on chain 2800: node-level devp2p authentication, the ECDSA commit seals that every header still carries until AIP-22 stage 5, the ECDSA commit seal that a commit carries besides its post-quantum seal, and the ECDSA envelope that every consensus message still carries on the wire, whose form both clients judge and which, since block 24,300,000 (AIP-22 stage 4), no longer names its author on the Besu-derived validators (this sentence corrected on 2026-10-28: it did not name the envelope; AIP-22, note of 2026-10-27 under section 5). The validators are named in +enforcement). What remains classical on chain 2800: node-level devp2p authentication, the ECDSA commit seal that a commit carries besides its post-quantum seal, which both clients check as an additional check, and the ECDSA envelope that every consensus message still carries on the wire, whose form both clients judge and which, since block 24,300,000 (AIP-22 stage 4), no longer names its author on the Besu-derived validators (this sentence corrected on 2026-10-28: it did not name the envelope; AIP-22, note of 2026-10-27 under section 5); until block 25,080,000 (AIP-22 stage 5) every header also carried the ECDSA commit quorum. The validators are named in consensus by the post-quantum ids of AIP-22 since block 20,836,228 (stage 3, 2026-09-30); that code is in this directory. (Corrected 2026-10-22: until that date this sentence also listed validator identity as classical and said that the post-quantum identity was unarmed on chain 2800 and ran only on testnet 28001.) @@ -334,7 +333,7 @@ was a deliberate decision with a liveness cost, taken for block 20,715,632 (AIP- then the certificate at an anchor height is again backed by as many validators as the block itself. Two things follow, and both should be said rather than left to be discovered. The word "quorum" -applies **only at anchor heights** - every 32nd block (every 128th from block 17,225,968 to block 20,746,736); the blocks between them carry no certificate of their own (headers are still admitted on their ECDSA commit seals until AIP-22 stage 5), so "a post-quantum quorum certificate on every block" would be false. And the higher threshold costs liveness margin: at K=7 of ten, four late validators are +applies **only at anchor heights** - every 32nd block (every 128th from block 17,225,968 to block 20,746,736); the blocks between them carry no certificate of their own (since block 25,080,000, AIP-22 stage 5, headers no longer carry ECDSA commit seals and are admitted on the Falcon-512 seal of their proposer alone; a commit still carries the ECDSA commit seal of its validator as an additional check), so "a post-quantum quorum certificate on every block" would be false. And the higher threshold costs liveness margin: at K=7 of ten, four late validators are enough to stall an anchor block, where K=3 tolerated seven. That trade was made deliberately, and it is the reason the threshold is a configured schedule rather than a constant. diff --git a/validator/README.md b/validator/README.md index a4d301d..bceaf6c 100644 --- a/validator/README.md +++ b/validator/README.md @@ -503,9 +503,7 @@ safety. ### 7c. Post-quantum seals on consensus messages (live since September 2026) -Every 32nd block carries a post-quantum certificate under its hash. The blocks between anchors carry -no Falcon seal of their own, and their validity at import rests on ECDSA, so the measured depth a -fabricated segment could reach before an anchor stops it is **31 consecutive blocks**. +Every 32nd block carries a post-quantum certificate under its hash. The blocks between anchors carry no certificate of their own; below block 25,080,000 their validity at import rested on the ECDSA commit quorum, and from it (AIP-22 stage 5) on the Falcon-512 seal of their proposer, so a fabricated segment stops at the next anchor: the depth measured below block 25,080,000 with classical keys was **31 consecutive blocks**, and the bound derived from the anchor rule, for a node that requires a quorum of seals in the certificate, was 33 blocks below block 24,148,752 (32 plus the sealed-sibling exception) and is 32 from it, where that quorum must be of one round: the latest anchor and the 31 after it (SPEC.md 3.1; from block 25,080,000 such a segment takes the post-quantum key of one validator, not measured); for the published follower, with its ceiling at 1, the bound stays 33 against an adversary without a post-quantum key, and one leaked or misused post-quantum key of a validator makes the depth unbounded (SPEC.md 6.4). Beyond the anchors, each of the four QBFT messages (proposal, prepare, commit, round-change) carries a Falcon-512 seal of its author, each under its own domain. On chain 2800 the nine Besu-derived @@ -539,8 +537,7 @@ admits you, and the same emission and enforcement heights as the fleet, which th A validator whose seals are refused does not fork and does not accept anything wrong: it loses its turn as proposer, and the chain continues without it as long as a quorum of the others can seal. -**What we do not claim.** Since block 24,300,000 (AIP-22 stage 4) every validator attributes a consensus vote only through its verified post-quantum seal, but headers still carry ECDSA commit seals until AIP-22 stage 5, so AERE is -not a "fully post-quantum consensus" and we do not describe it as one. What you can verify yourself, +**What we claim, and what we do not.** Since block 25,080,000 (AIP-22 stage 5) headers no longer carry ECDSA commit seals and, since block 24,300,000 (AIP-22 stage 4), every vote counts only with the verified post-quantum seal of its author, and a commit still carries the ECDSA commit seal of its validator as an additional check, which we call post-quantum consensus. We do not claim a post-quantum transport (the peer-to-peer transport is still authenticated by secp256k1), the ten validators are run by one operator, and no third party has audited it yet. What you can verify yourself, without taking our word for it, is the anchor certificate at every 32nd block, with the public verifier.