EIP-8288 Mempool signature and proof aggregation (In-mempool signature and proof aggregation)

No call decision · Security & privacy · EIP status Draft · created 2026-06-03

Adds an EIP-8141 frame mode that, instead of putting post-quantum signatures and STARK proofs into the block as they are, bundles them in the mempool into one recursive STARK and carries it in the block header.

Why it is needed

A quantum-safe hash-based signature is about 2 to 3 kB each and costs 150,000 to 200,000 gas to verify. Lattice-based signatures cost about the same. STARKs (Scalable Transparent ARguments of Knowledge), which are hash-based zero-knowledge proofs, exceed 128 kB and grow to 512 kB if they are to be generated quickly on a user's device, so verification needs millions of gas. Putting this data into a transaction as it is makes privacy protocols too expensive to use and makes it incompatible with FOCIL (EIP-7805), the inclusion list mechanism, and with frame transactions (EIP-8141). This EIP solves the problem by leaving only a light declaration in the transaction, having the mempool verify the actual signatures and proofs and merge them into one recursive STARK, so that a block carries only that single proof.

What changes

Today

After EIP-8288

Who is affected

In depth

Dependency verification frame (DEP_VERIFY_FRAME_MODE = 4)

Adds DEP_VERIFY_FRAME_MODE (value 4) to the EIP-8141 frame modes. This frame is not executed as EVM code and declares (scheme, data_hash, verification_key_hash) triples as dependencies. The data is exactly 96*k bytes, and each 96 bytes consists of 31 bytes of zero padding, 1 byte of scheme, 32 bytes of data_hash and 32 bytes of verification_key_hash. Currently only LEANSPHINCS_SCHEME (0x10) is valid, and LEANSTARK_SCHEME (0x11) is reserved until get_deps_hash is defined. The number of triples must be at least 1 and at most MAX_DEPENDENCIES_PER_FRAME (256), target must be None, value and flags must be 0, and the frame cannot be a member of an atomic batch. limits.execution must equal exactly the sum of the verification gas of each triple, and limits.state is 0. The receipt is recorded with status = 1, gas_used.state = 0 and no logs. A receipt is kept even for a frame that is not executed, because removing one frame would shift the indexes of the later frames and break FRAMEPARAM lookups.

Transaction dependencies and the zero data_hash convention

A transaction's dependency list is the triples of all dependency verification frames, sorted and deduplicated with deduplicate_and_sort. If data_hash is 32 zero bytes, it means the transaction's own signature hash, compute_sig_hash(tx). Because the signature hash covers the frame data, a transaction cannot carry its own signature hash directly, so this placeholder convention exists. The frame's data itself does not change, so compute_sig_hash covers the zero bytes as they are and FRAMEDATACOPY also returns 0. During execution, a contract can inspect the declared dependencies by reading the frame mode with FRAMEPARAM(0x02, i), reading the data length with FRAMEPARAM(0x04, i), and copying the triples with FRAMEDATACOPY.

Block validity: the recursive_stark header field

A recursive_stark = [stark_proof, block_deps_hash] field is added to the block header. block_deps_hash is get_deps_hash(dependencies(block)) over the union of all transaction dependencies in the block, and it is the digest that the proof commits to as a public input. For a block to be valid, this hash must match. If the dependencies are empty, stark_proof must also be empty. Otherwise the proof must verify against AGGREGATED_VK, a fixed protocol-level verification key. The recursive STARK circuit checks direct dependencies with the leanSPHINCS and leanSTARK verifiers, verifies the inner recursive proofs to merge their dependencies, and proves that the hash of the result, after removing the discard set and duplicates, equals the public input deps_hash. To allow recursion of unlimited depth, AGGREGATED_VK itself is fed in as an input to the proof. The circuit knows nothing about transactions or block structure and sees only a flat list of triples.

Mempool wrapper and recursive aggregation

In the mempool, transactions are wrapped in a [transactions, mode, content] wrapper and broadcast every AGGREGATION_INTERVAL (1,000 milliseconds). Mode 0 carries individual proofs per dependency, and mode 1 carries one recursive STARK that proves the whole set. Both modes check the limits of 16 leanSPHINCS dependencies (MAX_LEANSIG_DEPS_PER_WRAPPER) and 1 leanSTARK dependency (MAX_LEANSTARK_DEPS_PER_WRAPPER), and the condition that deps is the sorted, deduplicated union of all transaction dependencies. A mempool node verifies and accepts the wrappers it receives, creates a new mode 1 wrapper containing all valid transactions every interval and relays it, replacing transactions it has already sent with their hashes. If proving time runs short, it prioritizes in this order: its own aggregation from the previous round, aggregations from other nodes that reflect removals and add many new transactions, and then user transactions ordered by priority fee. For a pool that has only leanSPHINCS and no STARK, mode 0 rebroadcast that simply concatenates signatures may be more space efficient up to about 100 signatures.

Gas accounting

The limits.execution of a dependency verification frame is the sum of LEANSPHINCS_VERIFICATION_GAS (3,000) or LEANSTARK_VERIFICATION_GAS (30,000) for each triple. Actual STARK verification is done off-chain by the builder, so this gas is an expected cost, and because only the builder and the mempool bear the cost rather than every validating node, it is much cheaper than on-chain verification. On top of this, for each transaction, recursive_stark_gas(tx) = LEANSTARK_VERIFICATION_GAS * the number of triples counted with duplicates is added to the intrinsic gas and enters the gas_used of the transaction and the block. Dependencies sit at the transaction body level, so they are unaffected if execution reverts, and the gas is charged in full. Declaring the same dependency several times is legal, but it is wasteful because each declaration is charged. The EIP notes that the fixed gas assumes one parameter set each for leanSPHINCS and STARK, and that it could change to variable cost if mixing of k-time signatures or trade-offs by proof size appear.

FOCIL compatibility

The FOCIL (EIP-7805) data structure is extended to [transactions, recursive_stark], so an inclusion list, like a block, carries the dependency proof for its own transactions. Attesters verify the recursive proof in the FOCIL to decide which transactions are subject to the inclusion obligation. Builders handle FOCIL and mempool wrappers in the same way. They extract dependencies and proofs, decide which transactions to include, and create a new recursive STARK over the union minus the dependencies of transactions not included, and put it in the header. Mempool rebroadcast, FOCIL creation and block building are, by design, exactly the same aggregation job. A mempool node can recursively aggregate proofs without knowing transaction semantics, and the per-peer bandwidth overhead is constant regardless of the number of transactions, so FOCIL's censorship resistance is preserved.

Trust assumptions and DoS defense

Security rests on the soundness of the Lean Ethereum circuits, the hash function used for deps_hash (current tooling uses BLAKE2s, BLAKE3 is the leading replacement candidate, and the header and circuit would change together), and the soundness of the recursive STARK. The soundness of recursive proofs is widely believed to hold and is already used on-chain, but it makes end-to-end formal proofs hard, and the recursion depth of user-supplied verification keys may be unbounded. DoS defense consists of 16 leanSPHINCS dependencies (MAX_SIGS_PER_TX) and 1 leanSTARK dependency (MAX_STARKS_PER_TX) per transaction, 256 per frame, a per-wrapper limit, and gas proportional to the number of dependencies. The limits are set so that the worst-case mempool load equals that of sending the same data as calldata, but because post-quantum signatures and proofs are themselves larger and more expensive than existing elliptic curve schemes, increased mempool DoS exposure still remains. The limit design drew on the mempool policy framework of ERC-7562.

Current status

This EIP is in Draft status, so its constants (AGGREGATED_VK and DEPS_HASH are still TBD) and specification may change. It was discussed in AMA #15 on September 16, 2026, but no decision was made, and there is no decision yet to include it in any specific fork.

Original EIP · ← EIPs