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.
5.3 KiB
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.rsdependency-free SHA-256 (FIPS 180-4). Note: production SP1 guest swaps in the SP1-patchedsha2precompile; identical bytes.src/xmss.rsRFC 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.rsofficial vector, GENERATED from the committed KAT (provenance, no hand transcription).tests/kat.rsknown-answer validation.
scripts/gen_vectors.mjsregenerates 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.encodeframing 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.