# 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.