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

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.