The published line and the local line of this repository had no common ancestor: the public one carried the hygiene pass (no host names, no internal paths), the local one carried a month of corrections that never shipped. This commit ports the local work onto the public line, keeping the public hygiene wording wherever the two touched the same sentence, and keeping the public version of AERE-CROSS-CLIENT-DETERMINISM.md entirely. Carried: LICENSE/LICENSING corrections, VERIFY-POLICY.md, CITATIONS-UNRESOLVED.md remeasured 2026-08-11, the 'audited' adjective removed from next to Bouncy Castle, citation paths rewritten to published form, AIP-8, the QA consolidation report, the second EIP validation pass, fork-height corrections, the AereSink / threshold-factory correction, the forge test floor, and the architecture-map updates.
5.5 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
aere-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):aere-research/pq-finality-circuit/xmss-verify-core/src/sha256.rsdependency-free SHA-256 (FIPS 180-4). Note: production SP1 guest swaps in the SP1-patchedsha2precompile; identical bytes.aere-research/pq-finality-circuit/xmss-verify-core/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.aere-research/pq-finality-circuit/xmss-verify-core/src/vectors.rsofficial vector, GENERATED from the committed KAT (provenance, no hand transcription).aere-research/pq-finality-circuit/xmss-verify-core/tests/kat.rsknown-answer validation.
aere-research/pq-finality-circuit/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.