aere-docs/AERE-XMSS-CIRCUIT-CORE-SUMMARY.md
Aere Network e4cead319d Initial public release
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.
2026-07-20 01:01:36 +03:00

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