SPEC 1.1.0: section 2.6 consensus messages under post-quantum seal (wire format, domains, commit form under armed anchor = D8, emission gates, enforcement rules, activation order), G11, registry-binding domains; amended 2026-09-02
This commit is contained in:
parent
2f6950e44e
commit
8d3ae8a83d
133
SPEC.md
133
SPEC.md
@ -1,6 +1,6 @@
|
||||
# Aere Network chain 2800: full protocol specification
|
||||
|
||||
Version: 1.0.0, written 2026-08-25. Scope: everything a third party needs to implement a client
|
||||
Version: 1.1.0, written 2026-08-25, amended 2026-09-02 (section 2.6, D8, G11). Scope: everything a third party needs to implement a client
|
||||
that follows chain 2800 from block 0 to the live head and validates what the network validates,
|
||||
without reading Aere source code. It specifies the follower (validation) protocol completely; it
|
||||
describes seal production only where a follower must understand it to validate.
|
||||
@ -264,6 +264,100 @@ factory and grepping `consensus/`; recorded in `RUN-A-NODE.md`, "Which Besu", an
|
||||
over the block hash, which commits to it. 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 not yet armed)
|
||||
|
||||
Since 28-31 August 2026 every one of the four QBFT message types (PROPOSAL, PREPARE, COMMIT,
|
||||
ROUND-CHANGE) can carry a Falcon-512 seal of its author, and since 2 September 2026 all nine
|
||||
validators of chain 2800 EMIT such seals on every message they send (source:
|
||||
`PqAnchor.java`, the four `*_DOMAIN` constants and `*Message` builders; the four payload classes
|
||||
`ProposalPayload.java`, `PreparePayload.java`, `CommitPayload.java`, `RoundChangePayload.java`;
|
||||
fleet configuration measured 2026-09-02). This section specifies the wire format, the signed
|
||||
pre-images, the emission gates and the enforcement rules exactly as the shipped client implements
|
||||
them. **Enforcement is a per-node height switch and is NOT active on chain 2800 at publication:**
|
||||
a message without a seal, or with an invalid seal, still counts as a vote everywhere on 2800. On
|
||||
the public testnet 28001 all four enforcements are active (source: `testnet-public/CITESTE-MA.md`).
|
||||
|
||||
**Wire format.** Each payload keeps its upstream RLP list and appends, as its LAST element, an
|
||||
optional two-element list `[validatorIndex, signature]` (`validatorIndex` an integer index into the
|
||||
active Falcon registry, `signature` the Falcon-512 signature bytes). The element is OMITTED when
|
||||
there is no seal; an explicit empty list is non-canonical. `writeTo` DEFINES the canonical encoding
|
||||
and `readFrom` refuses any encoding that does not reproduce the received bytes, so a message with
|
||||
a seal and the same message without one never share a hash (source: `PreparePayload.writeTo`,
|
||||
comment "This method DEFINES the canonical encoding"). A COMMIT may additionally carry a list of
|
||||
non-Falcon "extra" seals for the hybrid certificate (`[schemeWireId, index, signature]`), REQUIRED
|
||||
to be accompanied by a Falcon seal; no extra seals exist on the fleet today (source:
|
||||
`CommitPayload.java`, constructor javadoc "empty for every commit on the fleet today").
|
||||
|
||||
**Signed pre-images: one domain per message type.** Every seal signs
|
||||
`keccak256(RLP[DOMAIN, chainId, height, ...])` with an ASCII domain string that names the message
|
||||
type, so a seal given honestly for one message type cannot be pasted onto another (source:
|
||||
`PqAnchor.java`):
|
||||
|
||||
| message | domain | pre-image fields after the domain |
|
||||
|---|---|---|
|
||||
| PROPOSAL | `AERE-PQ-PROPOSAL-1` | chainId, height, round, proposed block digest |
|
||||
| PREPARE | `AERE-PQ-PREPARE-1` | chainId, height, round, digest |
|
||||
| ROUND-CHANGE | `AERE-PQ-ROUNDCHANGE-1` | chainId, height, target round, hasPrepared, prepared round, prepared digest |
|
||||
| COMMIT | `AERE-PQ-COMMIT-1` or the committed-seal hash | see below |
|
||||
|
||||
The COMMIT seal is special, and the rule was corrected on 2026-09-02 (D8 in section 8): the
|
||||
message a commit seal signs is decided in ONE place, `PqAnchorProducer.commitSealMessage`, and is
|
||||
**the anchor form** `keccak256(RLP["AERE-PQ-COMMIT-1", chainId, height, round-independent block
|
||||
hash])` whenever the anchor is armed at that height (`height + 1 >= aere.pq.anchorBlock`, which on
|
||||
2800 is every height since 13,013,999), and the ECDSA committed-seal hash otherwise (source:
|
||||
`PqAnchorProducer.commitSealMessage`, `QbftRound.pqSealMessageFor`,
|
||||
`MessageValidator.SubsequentMessageValidator`). The anchor form is what lets the same seals be
|
||||
carried into the next anchor header's certificate (section 3.3); the round-independent hash is the
|
||||
on-chain hash with the round forced to 0 in the committed-seal encoding.
|
||||
|
||||
**Emission gates (producer side, per node).** `aere.falcon.attachBlock` arms Falcon seals on
|
||||
COMMIT messages (on 2800: 13,889,296); `aere.pq.proposalPq.attachBlock`,
|
||||
`aere.pq.roundChangePq.attachBlock` and `aere.pq.preparePq.attachBlock` arm the other three (on
|
||||
2800: 16,620,000, 16,660,000, 16,690,000, measured 9 of 9 emitting). Absence of a property means
|
||||
never. A node without a Falcon key emits nothing and is byte-for-byte upstream on the wire
|
||||
(source: `FalconSealSupport.java`, `*_ATTACH_PROPERTY`; fleet options measured 2026-09-02).
|
||||
|
||||
**Enforcement (validator side, per node): `aere.pq.commitPq.forkBlock`,
|
||||
`aere.pq.proposalPq.forkBlock`, `aere.pq.roundChangePq.forkBlock`, `aere.pq.preparePq.forkBlock`.**
|
||||
From the configured height a message of that type COUNTS as a vote only if all of the following
|
||||
hold; otherwise the message is logged and ignored ("the vote does not count"), it is not a
|
||||
consensus fault of the sender and it does not disconnect the peer (source: `PqCommitEnforcement`,
|
||||
`PqPrepareEnforcement`, `PqProposalEnforcement`, `PqRoundChangeEnforcement`, the `refusal`
|
||||
methods and their message strings):
|
||||
|
||||
1. the message carries a seal;
|
||||
2. the registry active at that height binds the seal's index to exactly the message's ECDSA
|
||||
author (recovered from the upstream signature): the seal is bound to the author, so a seal
|
||||
from validator A cannot be attached to validator B's message;
|
||||
3. the registry accepts the index (it refuses indices outside the active set);
|
||||
4. the signature verifies, with the Falcon-512 public key of that index, over the pre-image of
|
||||
the table above (for COMMIT, over the message `commitSealMessage` names at that height);
|
||||
5. for a COMMIT that carries extra seals, every scheme the hybrid schedule requires at that
|
||||
height is present, of the same index, and verifies over the SAME message.
|
||||
|
||||
Below the configured height nothing changes: the upstream ECDSA rules alone decide. There is no
|
||||
consensus binding on these heights (the same caveat as section 3.2): two validators armed at
|
||||
different heights disagree about which votes count, and the published activation procedure arms
|
||||
all nine at the same four heights, one node at a time, with the chain measured to advance between
|
||||
restarts (source: `ARMAREA-IMPUNERII-MESAJELOR-2026-09-02.md`,
|
||||
`armeaza-impunerea-pe-flota.sh`).
|
||||
|
||||
**Order of activation, and why.** The published package arms COMMIT first (a commit that does not
|
||||
count only delays finality within the round; the liveness margin is measured), then PROPOSAL,
|
||||
then ROUND-CHANGE (whose enforcement touches only the failure path: the happy path never emits a
|
||||
round change), and PREPARE last (the strictest: without a quorum of sealed PREPAREs a round
|
||||
cannot reach "prepared"). Rehearsed end to end on the seven-node kit (F95: the four heights in
|
||||
one restart, a coordinated postponement, each height crossed, a muted node, a sub-quorum stop and
|
||||
its healing) and, since 2026-09-02, WITH the anchor armed as on 2800 (source:
|
||||
`consensus-pqc/fullpq-activare-2026-08-28/`, `F-lib.sh`, `dovezi/`). The machine-checked model of
|
||||
these rules is `formal-consensus/pq_message_enforcement_smt.py` (section 7).
|
||||
|
||||
**What this section does not claim.** Node-to-node authentication (RLPx) is ECDSA. The hybrid
|
||||
(Falcon + SLH-DSA) certificate is implemented and tested but no hybrid keys exist on 2800. None of
|
||||
this is audited by a third party. Until the four `forkBlock` heights are set on the fleet, chain
|
||||
2800's consensus is post-quantum in EMISSION only, and the defensible sentence remains the one in
|
||||
section 3.1.
|
||||
|
||||
---
|
||||
|
||||
## 3. The post-quantum certificate anchor
|
||||
@ -505,6 +599,25 @@ contract at `0x5214F0e53899Dad805ef3AdF0624F5e49d2a5EB5` from block 13,889,290 (
|
||||
`RUN-A-NODE.md`, follower configuration; the contract's own interface is not specified in this
|
||||
bundle, see section 9, G6).
|
||||
|
||||
**Domain tags of the registry binding and of node-local persistence (named here so that a
|
||||
third-party client sees every `AERE-PQ-*` tag the shipped client uses).** A registry row binds a
|
||||
Falcon key to a validator address with two signatures over two distinct pre-images (source:
|
||||
`PqRegistryBinding.java`, class javadoc "The canonical pre-image"):
|
||||
|
||||
- the **possession proof** is a Falcon-512 signature over
|
||||
`"AERE-PQ-POP-1" || uint8(formatVersion) || uint64be(chainId) || uint64be(bindHeight) ||
|
||||
uint32be(count) || uint32be(index) || address(20) || uint32be(len(publicKey)) || publicKey`.
|
||||
The tag sits at offset 0 INSIDE the hashed pre-image, so a possession proof can never be
|
||||
replayed as a seal (the seal pre-images are `AERE-PQ-COMMIT-1` and the section 2.6 domains);
|
||||
the public key is inside the signed message because Falcon does not have exclusive ownership;
|
||||
- the **claim** is an ECDSA signature by the validator's consensus key, in an EIP-191 context
|
||||
that mixes the tag `AERE-PQ-CLAIM-1`, so a key cannot be moved under another validator's
|
||||
address, indices cannot be swapped, and a key cannot appear under an address whose owner did
|
||||
not ask for it.
|
||||
- `AERE-PQ-SEALSTORE-1` is the label of the node-local file in which a node persists the seals it
|
||||
has heard for its chain head across restarts (`aere-pq-seals.rlp`); it is not consensus data and
|
||||
a client is free to implement it differently or not at all (source: `PqSealStore.java`).
|
||||
|
||||
### 3.6 The canonical registry hash
|
||||
|
||||
(source: `anchor/consensus/common/.../PqRegistryHash.java`; exact and normative)
|
||||
@ -905,6 +1018,18 @@ are the authoritative in-protocol trace of the expansion (source: `registries/RE
|
||||
|
||||
---
|
||||
|
||||
**D8. The COMMIT seal message under an armed anchor (found 2026-09-02, D-311).** A verifier of the
|
||||
COMMIT enforcement that checks the seal over the ECDSA committed-seal hash refuses EVERY commit as
|
||||
soon as the anchor is armed, because the emitter signs the anchor form (section 2.6). The shipped
|
||||
client before 2026-09-02 had exactly this divergence between its emitter and its verifier; it was
|
||||
found on the public testnet 28001 at the first enforcement height (the chain stopped at block
|
||||
999), fixed by deriving both sides from one function, proven with unit and plumbing tests, a
|
||||
rehearsal with the anchor armed, and the testnet itself, and the fleet was moved to the fixed
|
||||
build on 2026-09-02 (image `d311-20260902`, version `26.4.0-aere.1-d203201-wt95fac2d7`). A
|
||||
third-party client implementing COMMIT enforcement MUST verify over the anchor form whenever
|
||||
`height + 1 >= aere.pq.anchorBlock` (source: `testnet-public/D-311-DOVADA-2026-09-02.md`,
|
||||
`deploy/validators/d311-2026-09-02/SURSA.md`).
|
||||
|
||||
## 9. What this specification cannot state from the published sources
|
||||
|
||||
Honest list, for completion in a later revision. An implementer hitting one of these should treat
|
||||
@ -941,7 +1066,11 @@ the gap as real rather than assume.
|
||||
- **G9. Whether a certificate reused by an adversary for its one permitted fork block passes
|
||||
eligibility in every corner case** was argued from code and never executed as a run (source:
|
||||
`CE-DEVINE-INVALID-LA-ANCORA-2026-08-07.md`, NEMASURAT item 8).
|
||||
- **G10. Anything about the chain after 2026-08-25.** Every measured statement carries its date;
|
||||
- **G11. When, and whether, the four message-layer enforcements of section 2.6 are armed on
|
||||
2800.** At publication they are not; the heights are a founder decision. A reader must measure
|
||||
the fleet's `aere.pq.*Pq.forkBlock` properties (or observe refusals in node logs) rather than
|
||||
assume either state.
|
||||
- **G10. Anything about the chain after 2026-09-02.** Every measured statement carries its date;
|
||||
the live schedule, set size, and head move. The registries directory and the follower
|
||||
configuration are the values current at publication.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user