From ea4ebcda5d53f6037d8dce145e2b06f400a80986 Mon Sep 17 00:00:00 2001 From: Aere Network Date: Thu, 1 Oct 2026 13:27:11 +0300 Subject: [PATCH] AIP-22 stages 1 to 3 on chain 2800 in the node package; verifier no longer prints the stage-5 sentence on chain 2800 README, SPEC, RUN-A-NODE, SECURITY, AUDITS and anchor/README now state the live rules: at least seven of ten seals per scheme from block 20,715,632 (stage 1), Falcon-512 at every 32nd block and SLH-DSA-SHA2-128s at every 128th from block 20,746,736 (stage 2), post-quantum validator ids in the header and in qbft_getValidatorsByBlockNumber from block 20,836,228 (stage 3). Stages 4 and 5 are not active on chain 2800. tools/verify-anchor.mjs: the FINALIZED line said on every chain that a header between anchors carries only its proposer's seal, which is true only where AIP-22 stage 5 is active (testnet 28001). It now reports what it measured: on chain 2800 headers between anchors carry the validators' classical ECDSA commit seals. Checked on both chains on 2026-10-01: chain 2800, 4/4 anchors verified, ECDSA branch printed; testnet 28001, 2/2 anchors and 20/20 proposer seals verified, stage-5 branch printed. Co-Authored-By: Claude Opus 5.5 --- AUDITS.md | 9 ++++---- README.md | 17 +++++++++----- RUN-A-NODE.md | 16 ++++++++------ SECURITY.md | 9 ++++---- SPEC.md | 25 +++++++++++---------- anchor/README.md | 49 +++++++++++++++++++++++------------------ tools/verify-anchor.mjs | 8 ++++++- 7 files changed, 77 insertions(+), 56 deletions(-) diff --git a/AUDITS.md b/AUDITS.md index db8360e..8a06f83 100644 --- a/AUDITS.md +++ b/AUDITS.md @@ -38,10 +38,11 @@ findings we chose not to fix and why. ## Verify the chain yourself, without trusting us The post-quantum anchor is designed so you do not have to take our word for it: from block -13,014,000 every 32nd block, and from block 17,225,968 every 128th, carries a post-quantum certificate -(Falcon-512, and from block 17,047,600 also SLH-DSA-SHA2-128s), and the block hash covers it. From -block 14,961,456 that certificate requires at least six valid seals of each scheme (six of nine -validators then, six of ten since 2026-09-11). The verifier is +13,014,000 every 32nd block (every 128th from block 17,225,968 to block 20,746,736) carries a +post-quantum certificate (Falcon-512, and from block 17,047,600 also SLH-DSA-SHA2-128s, at every +128th block since block 20,746,736), and the block hash covers it. Since block 20,715,632 that +certificate requires at least seven valid seals of each scheme, the full quorum of the ten +validators (six from block 14,961,456, six of nine validators then). The verifier is public, the signatures are in the headers, and the check runs against any node — ours or your own. ## Reporting a vulnerability diff --git a/README.md b/README.md index 1497b18..92b81ea 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,18 @@ consensus post-quantum, and nothing in the precompile patches touches consensus. Consensus on chain 2800 is **hybrid post-quantum in a precise and limited sense**, by a separate mechanism: the QBFT header anchor in `anchor/` and `patches/0003`. Since 2026-08-14 every -32nd block (an anchor block; every 128th from block 17,225,968, see below) must carry, under its block hash, a certificate of valid post-quantum +32nd block (an anchor block; every 128th from block 17,225,968 to block 20,746,736, see below) must carry, under its block hash, a certificate of valid post-quantum validator seals, and a node does not finalize an anchor block without it: at least three Falcon-512 -seals at first (f+1 of nine), **six of nine, a full 2f+1 quorum, since block 14,961,456** (August 21, -2026), and since block 17,047,600 (2026-09-04) a **hybrid** certificate of Falcon-512 AND -SLH-DSA-SHA2-128s seals, six of nine of each scheme. From block 17,225,968 (schedule set on all nine -validators on 2026-09-05) the anchor falls on every 128th block instead of every 32nd. Classical -secp256k1 ECDSA QBFT still finalizes every block and validator identity is classical; the QBFT +seals at first (f+1 of nine), six of nine, a full 2f+1 quorum, from block 14,961,456 (August 21, +2026), and **seven of ten per scheme, the full 2f+1 quorum of the ten validators, since block +20,715,632** (2026-09-29, AIP-22 stage 1); since block 17,047,600 (2026-09-04) the certificate is +**hybrid**, Falcon-512 AND SLH-DSA-SHA2-128s seals. From block 17,225,968 (schedule set on all nine +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. Classical +secp256k1 ECDSA QBFT still finalizes every block, and node identity and transport (RLPx) remain +classical; 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/RUN-A-NODE.md b/RUN-A-NODE.md index e8d761d..7e46eb6 100644 --- a/RUN-A-NODE.md +++ b/RUN-A-NODE.md @@ -138,11 +138,13 @@ running a configuration the chain does not. ## The post-quantum header anchor: apply patch 0003 to follow the current chain -Since block 13,014,000 every 32nd header of chain 2800, and from block 17,225,968 every 128th, -carries a sixth element in its QBFT `extraData`: a certificate of validator post-quantum seals, -universal since block 13,889,296, enforced at a minimum of three seals per anchor block (f+1 of -nine) from 2026-08-14 and of six from block 14,961,456, for each scheme once the certificate became -hybrid (Falcon-512 and SLH-DSA-SHA2-128s) at block 17,047,600. A node rejects an anchor block whose +Since block 13,014,000 every 32nd header of chain 2800 (every 128th from block 17,225,968 to block +20,746,736) carries a sixth element in its QBFT `extraData`: a certificate of validator post-quantum +seals, universal since block 13,889,296, enforced at a minimum of three seals per anchor block (f+1 +of nine) from 2026-08-14, of six from block 14,961,456 and of seven, the full quorum of the ten +validators, from block 20,715,632, for each scheme once the certificate became hybrid (Falcon-512 +and SLH-DSA-SHA2-128s) at block 17,047,600; since block 20,746,736 SLH-DSA seals are required at +every 128th block only. A node rejects an anchor block whose certificate holds fewer valid seals than the schedule requires at its height. (Correction 2026-08-19: an earlier version of this paragraph said that from block 14,050,000 the network refuses to finalize any block without a post-quantum quorum; the per-block rule armed at that height is retired in the @@ -332,8 +334,8 @@ export BESU_OPTS="\ A node syncing from block 0 starts into the GENESIS validator set, which is small (three validators). The startup threshold guard (`PqAnchorThresholdGuard`) refuses to arm a seal threshold at or above that set's QBFT quorum, because a proposer at that set size could never gather it. The -published schedule reaches K=3 (block 13,034,000) and K=6 (block 14,961,456), both unreachable at -N=3, so without `aere.pq.anchor.minSealsCeiling` a from-genesis node refuses to start with +published schedule reaches K=3 (block 13,034,000), K=6 (block 14,961,456) and K=7 (block +20,715,632), all unreachable at N=3, so without `aere.pq.anchor.minSealsCeiling` a from-genesis node refuses to start with `AERE-PQC-THRESHOLD-01`. The ceiling lowers the EFFECTIVE threshold to what the genesis set supports (`quorum(3) - 1 = 1`) WITHOUT editing the published schedule, exactly as that guard's own message instructs (`--Xaere-pq-anchor-min-seals-max`). It does not weaken the post-quantum binding a diff --git a/SECURITY.md b/SECURITY.md index 68319bd..8a33cf7 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -35,10 +35,11 @@ pointer is . have to agree to halt this chain is one. No amount of cryptography changes that number, and a report pointing at the consequences of that fact is in scope and welcome. - **The post-quantum guarantee is at anchor heights**, not on every block: from block 13,014,000, - every 32nd block, and from block 17,225,968 every 128th, carries a post-quantum certificate under - the block hash (Falcon-512, and from block 17,047,600 also SLH-DSA-SHA2-128s), requiring at least - six valid seals of each scheme from block 14,961,456 (six of nine validators then, of ten since - 2026-09-11). Blocks between anchors rest on ECDSA. We correct + 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, the full quorum of the ten validators (six from block 14,961,456, six of + nine validators then). Blocks between anchors rest on ECDSA. 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 ec4578d..0bc042b 100644 --- a/SPEC.md +++ b/SPEC.md @@ -201,7 +201,7 @@ negative control shows a majority quorum forks) (source: | Index | Element | Encoding | |---|---|---| | 0 | `vanityData` | exactly 32 bytes. Historically arbitrary (the client writes a version string); at anchor heights from H it carries the anchor digest D (section 3.3) | -| 1 | `validators` | RLP list of 20-byte addresses | +| 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 | @@ -414,9 +414,10 @@ in the Aere repository. ### 3.1 The claim, stated exactly -From block 13,014,000, every 32nd header of chain 2800 (an "anchor block"), and from block -17,225,968 every 128th (`aere.pq.anchorIntervalSchedule=17225968:128`, set on every node on -2026-09-05), carries a certificate of validator seals over its parent, and the anchor block's keccak +From block 13,014,000, every 32nd header of chain 2800 (an "anchor block"), every 128th from block +17,225,968 to block 20,746,736 (`aere.pq.anchorIntervalSchedule=17225968:128`, set on every node on +2026-09-05) and every 32nd again from block 20,746,736 (`17225968:128,20746736:32`, AIP-22 stage 2, +2026-09-29), carries a certificate of validator seals over its parent, and the anchor block's keccak block hash covers a 32-byte commitment to that certificate. Until block 17,047,600 the certificate is v1, a list of `[index, falconSignature]` pairs under the domain `AERE-PQ-ANCHOR-1`; from block 17,047,600 (`aere.pq.anchorV2Block`) it is v2, `RLP[2, [[scheme, index, signature], ...]]` under the @@ -428,13 +429,13 @@ that also carries a valid Falcon seal [MEASURED 2026-09-05, 400 consecutive anch `anchor/consensus/common/.../PqAnchorV2.java`, `PqSchemeSchedule.java`; the public verifier `tools/verify-anchor.mjs`). The enforced minimum number of valid seals is a height schedule: 0 from 13,014,000 (warm-up), 3 from 13,034,000 (f+1 of the nine validators of that time; enforced on the fleet since -2026-08-14), and **6 from block 14,961,456** (of nine then, a full 2f+1 quorum at that size and below the ten-validator quorum of seven since 2026-09-11, the same count QBFT itself +2026-08-14), 6 from block 14,961,456 (of nine then, a full 2f+1 quorum at that size, and below the ten-validator quorum of seven from 2026-09-11), and **7 from block 20,715,632** (AIP-22 stage 1, the full 2f+1 quorum of the ten validators, the same count QBFT itself requires) (source: `anchor/README.md`, "Scope boundary"; `RUN-A-NODE.md`, the anchor section). The defensible sentence, and the only form this document endorses: *every anchor block (every -128th block from 17,225,968, every 32nd before it) does not -finalize without a certificate of at least six valid Falcon-512 validator seals (of ten validators since 2026-09-11) under its -hash (three, before block 14,961,456; see the schedule and the historical windows)*. Blocks between +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, the full 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, prepare, commit, round-change) carry and require post-quantum seals since 2026-09-08 (section @@ -453,9 +454,9 @@ 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 <= 128 blocks since -block 17,225,968 (about 75 seconds at the measured rhythm; <= 32 blocks, about 16 seconds, before -it); rewriting anything below an anchor changes that anchor's parent hash, forces the +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 anchor to be reproduced, and reproducing it requires Falcon signatures the adversary does not have. History below H remains protected by ECDSA alone, permanently (source: `anchor/consensus/common/.../PqAnchorConfig.java`, interval javadoc; `anchor/README.md`). @@ -929,7 +930,7 @@ their liveness at any moment is only provable by your own `net_peerCount` (sourc ### 6.4 The genesis-set threshold problem, and the published answer A node syncing from block 0 starts INTO the genesis validator set (N=3, quorum 2). The anchor -threshold guard (section 3.7) refuses to arm K=3 or K=6 against that set, so a from-genesis +threshold guard (section 3.7) refuses to arm K=3, K=6 or K=7 against that set, so a from-genesis follower with the published schedule cannot start at all without one more setting. The published answer is `aere.pq.anchor.minSealsCeiling=1`, which lowers the EFFECTIVE seal-count floor to `quorum(3) - 1 = 1` WITHOUT editing the schedule (source: `RUN-A-NODE.md`, "Why the seal-threshold diff --git a/anchor/README.md b/anchor/README.md index e67b615..75acb90 100644 --- a/anchor/README.md +++ b/anchor/README.md @@ -11,11 +11,11 @@ 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 classical secp256k1 ECDSA QBFT with a post-quantum -checkpoint enforced every 128 blocks (every 32 until block 17,225,968).** This code is what adds the checkpoint, in two steps that +checkpoint enforced every 32 blocks (every 128 from block 17,225,968 to block 20,746,736).** 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 - block, every 128th from block 17,225,968) commits to a Falcon-512 certificate signed by the validators. That is a binding, not a + block; every 128th from block 17,225,968 to block 20,746,736) commits to a Falcon-512 certificate signed by the validators. That is a binding, not a replacement: a rewrite of anchored history must also forge the post-quantum signatures. 2. **The enforced minimum.** Since 2026-08-14 a node does not finalize an anchor block unless its certificate holds at least three valid Falcon-512 seals (f+1 of nine, the guarantee that at @@ -29,12 +29,14 @@ should not be confused: 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 Falcon seals and are finalized by ECDSA alone, so - the post-quantum guarantee is a checkpoint about every 75 seconds (128 blocks; about every 16 - seconds at 32 blocks, before block 17,225,968), not a per-block quorum. + the post-quantum guarantee 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 - form `RLP[2, [[scheme, index, signature], ...]]` and carries Falcon-512 (lattice) AND SLH-DSA-SHA2-128s - (hash-based) seals; the enforced minimum applies to EACH scheme on its own, at least six of nine valid - seals of each, and every SLH-DSA seal must sit at an index that also carries a valid Falcon seal. Properties: + form `RLP[2, [[scheme, index, signature], ...]]` and carries Falcon-512 (lattice) seals, with SLH-DSA-SHA2-128s + (hash-based) seals as well at every anchor until block 20,746,736 and at every 128th block since (item 4); + the enforced minimum applies to EACH scheme required at that anchor on its own, at least six of nine valid + seals of each at that time (seven of ten since block 20,715,632), and every SLH-DSA seal must sit at an index that also carries a valid Falcon seal. Properties: `aere.pq.anchorV2Block=17047600`, `aere.pq.hybrid.attachBlock=17047568`, `aere.pq.schemeSchedule=17047568:falcon-512+slh-dsa-sha2-128s`, `aere.pq.hybridRegistry` (the epoch-2 key manifest, also published under `/pq/manifests/`). The fleet schedule carries one dated step, @@ -48,7 +50,7 @@ should not be confused: on every reading node on 2026-09-05: from block 17,225,968 an anchor falls on every 128th block instead of every 32nd. Each hybrid certificate adds about 53 KB to its header; quartering the frequency divides that cost by four without touching the rule, the thresholds or the schemes. Until that height the - interval is 32, and the checkpoint above becomes one about every 64 seconds after it. + interval was 32, and from it to block 20,746,736 the checkpoint was one about every 75 seconds. Correction 2026-08-19: the fleet was also configured on 2026-08-15 with `aere.falcon.forkBlock` at 14,050,000, intended as a per-block blocking Falcon quorum. In the shipped code that rule @@ -108,7 +110,8 @@ defend yourself"; it is "you cannot make the attacker pay, on your own." ground.** What it addresses is the case where key-evolving signatures stop working. Their guarantee rests on a validator's old key being *gone* once deleted. Against an adversary with a cryptographically relevant quantum computer, an old secp256k1 key does not need to have been kept or -stolen. QBFT headers carry validator addresses rather than public keys, but every seal a validator +stolen. QBFT headers carried validator addresses rather than public keys (post-quantum ids since block +20,836,228, AIP-22 stage 3), but every commit seal a validator ever wrote is an ECDSA signature from which its public key can be recovered, and those seals are in the chain forever. From the public key, a quantum adversary derives the private one. Deleting the private key buys nothing, because the chain reconstructs it. The certificate under the block hash is what still has to be forged, and forging it requires @@ -171,7 +174,7 @@ This matters more than the file list, so it is stated before it. | Layer | In this directory | Armed on chain 2800 | |---|---|---| | Anchor certificate under the block hash | yes | **yes**, since block 13,014,000 | -| Enforced minimum seals at an anchor height | yes | **yes**, 6 of 9 since 14,961,456 | +| Enforced minimum seals at an anchor height | yes | **yes**, 7 of 10 per scheme since 20,715,632 (6 from 14,961,456) | | Legacy per-block Falcon rule (`aere.falcon.forkBlock`) | yes | **no** — retired at the anchor block | | Post-quantum seal on PREPARE, emission | yes | **yes**, since block 16,690,000 | | Post-quantum seal on PREPARE, enforcement | yes | **armed for block 17,700,000** (set 2026-09-05) | @@ -180,14 +183,14 @@ This matters more than the file list, so it is stated before it. | Post-quantum seal on ROUND-CHANGE, emission / enforcement | yes | **yes**, since block 16,660,000 / **armed for block 17,550,000** | | Post-quantum seal on COMMIT, emission / enforcement | yes | **yes**, since the anchor / **armed for block 17,250,000** | | Hybrid Falcon + SLH-DSA certificate (v2) | yes | **yes**, since block 17,047,600 (2026-09-04) | -| Anchor interval 128 (`aere.pq.anchorIntervalSchedule`) | yes | **armed for block 17,225,968** (set 2026-09-05) | -| Per-scheme anchor intervals, Falcon-512 every 32 and SLH-DSA every 128 (AIP-22 stage 2, `scheme/interval` steps in `aere.pq.schemeSchedule`) | yes (added 2026-09-23) | **no**; proven on testnet 28001 only | -| Post-quantum validator identity and the v3 key registry (AIP-22 stage 3, `aere.pq.identityBlock`, `aere.pq.registryV3`) | yes (added 2026-09-23) | **no**; proven on testnet 28001 only | -| Sealing keys read from the v3 epochs, key rotation under an id (AIP-22 stage 3b, `aere.pq.registryV3.keysFrom`, `aere.falcon.keys.next`) | yes (added 2026-09-23) | **no**; proven on testnet 28001 only | +| Anchor interval 128 (`aere.pq.anchorIntervalSchedule`) | yes | **yes**, from block 17,225,968 to block 20,746,736 (set 2026-09-05) | +| Per-scheme anchor intervals, Falcon-512 every 32 and SLH-DSA every 128 (AIP-22 stage 2, `scheme/interval` steps in `aere.pq.schemeSchedule`) | yes (added 2026-09-23) | **yes**, since block 20,746,736 (2026-09-29) | +| Post-quantum validator identity and the v3 key registry (AIP-22 stage 3, `aere.pq.identityBlock`, `aere.pq.registryV3`) | yes (added 2026-09-23) | **yes**, since block 20,836,228 (2026-09-30) | +| Sealing keys read from the v3 epochs, key rotation under an id (AIP-22 stage 3b, `aere.pq.registryV3.keysFrom`, `aere.falcon.keys.next`) | yes (added 2026-09-23) | **keys read from the v3 epoch since block 20,836,228**; no key rotated on chain 2800 | | 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) | **no**; proven on testnet 28001 only (H_fin 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) | -| 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) | **no** (no v3 epoch on chain 2800); on testnet 28001 since 2026-09-23 22:51Z | +| 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 are unset, and unset means never. Each refuses loudly on a value it cannot parse rather than booting @@ -297,8 +300,9 @@ sentence. Someone else has to do the verifying, which is why it is here. ## Terminology, used precisely -**A certificate at an anchor height is signed by at least six validators, since block 14,961,456 -(August 21, 2026). It was f+1 before that, and this paragraph said so. Between that date and +**A certificate at an anchor height is signed by at least seven validators since block 20,715,632 +(2026-09-29), and was signed by at least six from block 14,961,456 (August 21, 2026). It was f+1 +before that, and this paragraph said so. Between that date and 2026-09-11 six WAS the 2f+1 quorum of a nine-validator set; from 2026-09-11 until block 20,715,632, with ten validators, the quorum was seven and six was not one, so we did not call it a quorum. From block 20,715,632 (AIP-22 stage 1, armed 2026-09-29) the minimum is seven, the 2f+1 quorum of ten, and there it @@ -307,14 +311,15 @@ is worth keeping in view rather than deleting, because it is the difference betw different claims. f+1 signatures guarantee only that at least one honest validator signed. A quorum of 2f+1 is the same count QBFT itself requires to agree on the block. Between 14,961,456 and 2026-09-11 the post-quantum certificate at an anchor height was backed by as many validators as the -block itself; with ten validators it is backed by six of the seven the block needs, which is more -than f+1 and less than the block's own quorum. Raising it to seven is a deliberate decision with a -liveness cost, and it has not been taken. +block itself; from 2026-09-11 until block 20,715,632, with ten validators, it was backed by six of +the seven the block needs, more than f+1 and less than the block's own quorum. Raising it to seven +was a deliberate decision with a liveness cost, taken for block 20,715,632 (AIP-22 stage 1); since +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** - about every 128th block (every 32nd until block 17,225,968); the blocks between them carry no Falcon +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 Falcon seals at all and are finalized by ECDSA alone, so "a post-quantum quorum on every block" would be -false. And the higher threshold costs liveness margin: at K=6 of ten, four late validators are +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/tools/verify-anchor.mjs b/tools/verify-anchor.mjs index 0bcb27e..cf204a5 100644 --- a/tools/verify-anchor.mjs +++ b/tools/verify-anchor.mjs @@ -699,7 +699,13 @@ console.log(all + ' proposer seals were not judged. This says nothing about the chain; try another endpoint (RPC=...).' : '') : 'PROBLEMS: ' + bad + ' of ' + COUNT + ' anchors and ' + manifestBad + ' manifests failed' + (propBad ? ', and ' + propBad + ' proposer seals' : '') + ' - do not take our word for anything; the failure list above is the finding.' + (unmeasured ? ' (' + unmeasured + ' more could not be checked here: npm install @noble/post-quantum)' : ''))); -if (newestOk !== null) console.log('FINALIZED (post-quantum): block ' + (newestOk - 1) + ', the parent of anchor ' + newestOk + ', the most recent anchor whose certificate verified here. Nothing between anchors is final; a header between anchors carries only its proposer\'s seal.'); +// 2026-10-01: the tail of this line said, on every chain, that a header between anchors carries only its proposer's seal. That is true only +// where AIP-22 stage 5 is active (testnet 28001 from block 3,131,000); on chain 2800 headers between anchors still carry the validators' +// classical ECDSA commit seals, and this tool printed the stage-5 sentence there on every run. It now says what it measured above. +if (newestOk !== null) console.log('FINALIZED (post-quantum): block ' + (newestOk - 1) + ', the parent of anchor ' + newestOk + ', the most recent anchor whose certificate verified here. Nothing between anchors is post-quantum final; ' + + (propChecked === 0 + ? 'a header between anchors carries the validators\' classical ECDSA commit seals (AIP-22 stage 5 is not active at these heights on this chain).' + : 'a header between anchors carries only its proposer\'s seal.')); if (!slhDsa) console.log('note: @noble/post-quantum is not installed, so a v2 certificate carrying SLH-DSA seals cannot be verified here (npm install @noble/post-quantum).'); // ANCHOR_REPORT= (2026-09-27): the most recent anchor that verified here, as JSON, for a tool that builds on it (the AIP-23 proof // verifier). parentHash is the hash the certificate's seals were verified over, so such a tool can bind the parent header to it by