Aere Network public source. Everything here can be checked against the live chain (chain id 2800, https://rpc.aere.network). Scope note, stated up front rather than buried: consensus on chain 2800 is classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at the signature, precompile, account and transport layers. Nothing here makes the consensus post-quantum, and no document in it should be read as claiming so.
99 lines
5.3 KiB
Markdown
99 lines
5.3 KiB
Markdown
# Post-Quantum Finality Certificate (#4): XMSS aggregation circuit, verification core
|
|
|
|
Date: 2026-07-19
|
|
|
|
## What was asked
|
|
|
|
Advance the research core of Aere Network's Post-Quantum Finality Certificate: the
|
|
off-chain XMSS/leanSig aggregation circuit that a zkVM would run to prove a quorum of
|
|
validators hash-based-signed a block. Implement the tractable, independently-testable
|
|
VERIFICATION CORE now (validated against real vectors) and specify the rest as design.
|
|
Never claim the aggregation proof works end to end.
|
|
|
|
## What was found (grounding)
|
|
|
|
- OFFICIAL RFC 8391 XMSS-SHA2_10_256 known-answer vector already committed at
|
|
`aerenew/contracts/test/fixtures/xmss-sha2_10_256-kat.json`
|
|
(github.com/XMSS/xmss-reference, oid=1, idx=512, msg=0x25, pubRoot 0x9d898033...c3483).
|
|
- Deployed on-chain XMSS verifier + independent JS oracle:
|
|
`contracts/contracts/pqc/AereXmssVerifier.sol`, `contracts/test/xmssVerifier.test.js`.
|
|
- SP1 guest style is a clean "pure-Rust core crate + thin no_main guest + std test"
|
|
split (`aerenew/zk-light-client/qbft-finality` + `guest`), sha2/k256 SP1-patched.
|
|
- On-chain public-values layout (192 bytes, 6 words) and quorum rule read from
|
|
`contracts/contracts/pqfinality/AereFinalityCertificateVerifier.sol`:
|
|
abi.encode(bytes32 blockHash, uint256 blockHeight, bytes32 validatorSetRoot,
|
|
uint256 validatorSetSize, uint256 quorumCount, bytes32 attestationDomain);
|
|
threshold `_quorumThreshold(n) = (2n+2)/3 = ceil(2N/3)`.
|
|
- Committee commitment (registry-defined, flat keccak):
|
|
leaf_i = keccak256(abi.encode(validator_i, keyEpoch_i, keyHash_i)),
|
|
keyHash_i = keccak256(pubKey_i), root = keccak256(abi.encode(leaves)).
|
|
- Attestation message: attestationDomain = keccak256(abi.encode(DOMAIN_PREFIX, chainId,
|
|
registry)); M = keccak256(abi.encode(attestationDomain, blockHash, blockHeight)).
|
|
|
|
## What was built (IMPLEMENTED + TESTED)
|
|
|
|
Dir: `aerenew/pqc-fork/pq-finality-circuit/`
|
|
- `xmss-verify-core/` Rust crate, ZERO external deps, `no_std`, allocation-free,
|
|
float-free, hash-only, deterministic (models the aggregation guest's per-validator
|
|
inner logic):
|
|
- `src/sha256.rs` dependency-free SHA-256 (FIPS 180-4). Note: production SP1 guest
|
|
swaps in the SP1-patched `sha2` precompile; identical bytes.
|
|
- `src/xmss.rs` RFC 8391 XMSS-SHA2_10_256 verify core: chain_lengths, WOTS_PKFromSig,
|
|
L-tree, compute_root, xmss_recover_root, xmss_verify. Byte-for-byte model of the
|
|
on-chain AereXmssVerifier.sol / JS oracle.
|
|
- `src/vectors.rs` official vector, GENERATED from the committed KAT (provenance,
|
|
no hand transcription).
|
|
- `tests/kat.rs` known-answer validation.
|
|
- `scripts/gen_vectors.mjs` regenerates vectors.rs from the committed JSON.
|
|
- `README.md`.
|
|
|
|
## REAL vector-test result (run, not asserted from memory)
|
|
|
|
`cargo test --offline` in `xmss-verify-core/`: 12 passed, 0 failed.
|
|
- recovers_the_official_reference_root: OK (recovers pubRoot 0x9d898033...c3483)
|
|
- accepts_the_official_reference_signature: OK
|
|
- rejects tampered: wots value, wots tail/checksum, auth node, message, leaf index,
|
|
wrong claimed root, tampered R randomizer: all fail to verify (OK)
|
|
- sha256 self-checks vs FIPS 180-4 ("abc", ""): OK
|
|
- chain_lengths checksum shape: OK
|
|
|
|
## Design doc written
|
|
|
|
`aerenew/docs/AERE-XMSS-AGGREGATION-CIRCUIT.md`:
|
|
- Full aggregation-circuit design: per validator recover XMSS root, recompute the
|
|
registry committee commitment (membership), verify each attestation, structural
|
|
distinctness, count >= ceil(2N/3), emit the exact 192-byte public values bound to the
|
|
on-chain verifier; message + domain binding spelled out.
|
|
- Scheme choice + tradeoff: WOTS+/XMSS (standardized RFC 8391, most conservative,
|
|
matches on-chain verifier, one-time/few-time so rotation required, which
|
|
AerePQAttestationKeyRegistry already models; SHA-256 expensive in-circuit) vs
|
|
leanSig/Poseidon2 (SP1/STARK-native field, dramatically cheaper + scalable, but newer
|
|
and hashing story diverges from the deployed SHA-256 verifier); SLH-DSA stateless
|
|
alternative; ML-DSA is lattice not hash-based (out of scope for the hash-only claim).
|
|
- Structural cost table (derivable): ~3320 SHA-256 calls per validator worst case,
|
|
~23k for N=7.
|
|
- Effort estimate: several weeks specialist work + audit for the full guest + proving.
|
|
- Honest status labels throughout.
|
|
|
|
## HONESTY flags
|
|
|
|
- [MEASURE] / NOT implemented: the zkVM aggregation guest, SP1 proving pipeline,
|
|
end-to-end certificate, cycle counts, proving latency/memory, real-gateway verify gas,
|
|
native-STARK vs Groth16-wrap decision.
|
|
- [VERIFY]: exact Solidity `abi.encode` framing the guest must reproduce for the
|
|
committee commitment (address/uint32 left-padding to 96-byte leaf pre-image; the
|
|
bytes32[] ABI head of a 0x20 offset word + N length word before the leaves). Flagged
|
|
in the doc; to be matched against the deployed registry when the guest is built.
|
|
- Verification core is REAL + tested against the official vector (above).
|
|
|
|
## On-chain side
|
|
|
|
UNCHANGED. AereFinalityCertificateVerifier.sol and AerePQAttestationKeyRegistry.sol were
|
|
only Read, never modified; their tests untouched. Still fail-closed: no certificate can
|
|
pass the real gateway until a real guest + real proof exist.
|
|
|
|
## Scope boundary held
|
|
|
|
Additive PQ finality attestation only. Base QBFT consensus is still classical ECDSA;
|
|
this does not flip it. PQ finality is NOT live end to end.
|