# Spec 6: AerePQAggregate build summary ## What was built Constant-cost on-chain verification of a t-of-n POST-QUANTUM committee authorization via ONE succinct SP1 proof, exposed as an ERC-4337 path and a portable ERC-7579 validator module. ### Files (new, no deployed contracts modified) - `aerenew/contracts/contracts/mpc/AerePQAggregateVerifier.sol` - `registerCommittee(root, t, n, scheme)` — stores committee (root = commitment to n PQC keys; keys NOT stored on-chain, so cost stays O(1) in n). Permissionless, no admin, no funds. - `verifyAggregate(committeeId, messageDigest, publicValues, proofBytes)` view — strict fail-closed: binds committeeRoot / t / n / scheme / messageDigest / validCount>=t, then ONE `SP1_GATEWAY.verifyProof(pinnedVKey, publicValues, proofBytes)`. Reverts on any mismatch or bad proof. - `tryVerifyAggregate(...)` view — non-reverting bool (try/catch wrap) for 4337/7579 SHOULD-not-revert. - `recordAggregate(...)` — strict verify + provenance attestation event. - Immutable `SP1_GATEWAY` (chain 2800 canonical Succinct gateway 0x9ca479C8…70628) and `AGGREGATE_PROGRAM_VKEY` (pinned circuit; registrant cannot swap circuits). - Public-values layout (fixed 192 bytes / 6 words): `abi.encode(bytes32 committeeRoot, uint256 t, uint256 n, uint256 scheme, bytes32 msgDigest, uint256 validCount)`. - `aerenew/contracts/contracts/modular/AerePQAggregateModule.sol` - ERC-7579 type-1 validator (matches OZ draft-IERC7579 `IERC7579Validator`): `onInstall`/`onUninstall`/ `isModuleType`, `validateUserOp(PackedUserOperation, bytes32)->uint256` (0/1), and `isValidSignatureWithSender(address,bytes32,bytes)->bytes4` (0x1626ba7e / 0xffffffff). - Singleton, per-account committee binding keyed by msg.sender (AereSessionKeyValidator pattern). - Signature layout: `abi.encode(bytes publicValues, bytes proofBytes)`; malformed => FAILED, no revert. - Local PackedUserOperation struct (self-contained, portable to any EVM chain). - `aerenew/contracts/test/AerePQAggregate.test.js` — 17 tests. - `aerenew/docs/AERE-PQ-AGGREGATE.md` — scheme, gas argument, 4337/7579 portability, Bank28 use case, honest [MEASURE] status. ## REAL test result `npx hardhat test test/AerePQAggregate.test.js` => **17 passing (2s)**. Ran from aerenew/contracts. Test double = MockSp1Verifier (verifyProof REVERTS on invalid proof, exact production gateway semantics), same double as AereComputeMarketV3 / zk light clients. Coverage: valid proof authorizes (view+recorded); invalid proof rejects fail-closed; wrong message digest rejects; wrong committee root rejects; below-threshold rejects; t/n/scheme mismatch + malformed public values reject; unknown committee rejects; module returns 4337 code + ERC-1271 magic correctly and fails closed without reverting on invalid/malformed. ### Gas independence (the headline) `recordAggregate`: n=5 => 61,799 gas; n=1,000,000 => 61,823 gas; diff 24 gas (calldata encoding of the larger integer, O(log n) not O(n)). Concretely proves constant on-chain cost regardless of committee size. ## Flags - [MEASURE] OFF-CHAIN SP1 aggregation guest circuit NOT implemented (research zkVM work). Verifying Falcon FFT/float sampling in a zkVM is hard => ML-DSA-65 (FIPS 204, integer arithmetic) is the tractable first target (SCHEME_MLDSA65 = 5). On-chain side is built + tested vs a MOCK gateway only. Do NOT claim end-to-end aggregation works. - [MEASURE] real-gateway on-chain verify gas + real proving cost/latency (mock numbers above). - [VERIFY] ERC-7579 module assumes account stripped the validator-routing prefix before calling (matches OZ AccountERC7579); PackedUserOperation field layout to reconcile vs Safe7579 / Kernel / Nexus. - [VERIFY] isValidSignatureWithSender intentionally does NOT scope by `sender` (committee is sole authority). ## Scope boundary kept Account/authorization aggregation only. Consensus stays classical ECDSA QBFT. No new token. No funds, no admin. solc 0.8.23, viaIR, matches repo style. No em-dashes in prose.