Tacet: a trust-minimized encrypted mempool for the OP Stack (working prototype, seeking feedback)

Tacet is an EVM-native encrypted mempool for the OP Stack. (The name is the musical direction tacet: the voice is present in the score but stays silent until its cue - which is exactly what an encrypted transaction does in a committed block.) Transactions are threshold-encrypted before they reach the sequencer; the ordering is committed before anyone (including the sequencer) can read a transaction, and only after the block is fixed do t-of-n keypers release decryption shares (decrypt-then-execute). This takes content-based front-running off the table for everyone who is not the sequencer, and out of the sequencer’s hands as long as it honors its own commitment: nobody can read a transaction before the ordering is fixed, and once the key is released the committed batch executes at the top of the next block - without trusted hardware (no TEE) and without a permissioned validator set. That is the gap between the TEE-based block builders that are live today and the enshrined-L1 encrypted-mempool track (EIP-8105 / EIP-8184 “LUCID”) that is still years out. (The residual cases - a network-latency race at key release, back-running, and the Phase-0 fact that the ordering commitment is local sequencer state - are named below.) The application this is built toward first is not retail MEV protection but regulated order flow: for institutions, pre-execution confidentiality is a precondition for routing client orders over a public chain rather than a private one, and it is the setting in which a committee of identified, accountable keypers is a natural fit rather than a compromise. The mechanism itself is general - nothing in it is specific to that use.

The cryptographic core works and is reproducible today: a keyper committee runs DKG over libp2p, and the decrypt half of the pipeline - threshold-share aggregation, epoch-key verification, and a sealed epoch turned into its committed batch - runs end to end. Execution against the EVM is the op-geth fork’s half, not the standalone keyper’s. The op-geth integration - a native encrypted transaction type, an encrypted subpool, a sequencer that commits ordering before the key exists, direct delivery of the verified epoch key from the keypers to the sequencer, a decrypt pipeline, and a top-of-block miner hook that executes an epoch in the first block built after its key arrives - is implemented, unit-tested and wired into node startup; the remaining work is converging the standalone keyper prototype onto the canonical wire formats and standing up a devnet. This is a Phase 0 prototype, not audited, and I would value feedback from this community, in particular on the keyper committee and on how this should relate to the enshrinement track (EIP-8105 / LUCID) and the shutterized OP Stack.

Motivation

MEV has extracted billions of dollars from users to date. Notably, the recent decline in L1 sandwiching largely reflects flow moving into trusted private channels (EigenPhi puts L1 sandwich revenue at roughly a quarter of its late-2024 level by October 2025, and arXiv 2512.17602 documents sandwiching inside private channels) - which relocates the trust problem rather than solving it. The live EVM-facing mitigations are either TEE-based (Unichain via Flashbots rollup-boost - hardware trust; Base runs the same builder stack for Flashblocks) or out-of-protocol relays (no cryptographic guarantee). Threshold-encrypted mempools exist (Shutter on Gnosis, per-tx IBE, live since 2024; Aptos, batched threshold encryption, AIP-144 accepted and mainnet rollout pending as of August 2026), but not as a protocol-native EVM implementation: Shutter’s own OP Stack variant (SHOP, Sepolia testnet) deliberately avoids client-level mempool changes - ciphertexts reach an inbox contract as ordinary transactions, with forked op-node/op-geth only for key gossip and top-of-block enforcement. What is missing is an open, trust-minimized reference in the shape the enshrinement EIPs propose for L1 - native transaction type, pool handling, in-protocol decrypt-then-execute - that an OP Stack rollup can study; the recent Flashbots systematization of this space (eprint 2026/1643, AFT 2026) traces the same scheme lineage and names none either - its own framing is that “the Shutterized Gnosis Chain anchors a production baseline, while EIP-8105 and the LUCID headliner are the most advanced in-protocol proposals”. Tacet aims to be exactly that.

Confidentiality as a duty, not a preference. For regulated participants the exposure is not only economic. An institution routing a client order through a public mempool discloses that order - size, direction, and often enough to infer the counterparty - to everyone before it executes, which sits badly with best-execution and client-confidentiality obligations. This is not hypothetical: regulated securities are already being issued and settled on public chains under national frameworks such as Germany’s eWpG, where order flow is fully visible by construction. The remedies available today are trusted private channels, which is the same relocation of trust described above. To be precise about scope: an encrypted mempool protects a transaction until it is included, and once the epoch key is released the transaction is as public as any other. Lasting state confidentiality is a separate and later problem (Phase 2+). What this design removes is the pre-execution disclosure - which is the part those obligations actually turn on.

On L1, the enshrinement effort has meanwhile converged: the EIP-8105 team endorsed EIP-8184 (“LUCID”) in February 2026, and the Encrypt-the-Mempool coalition now advances LUCID as the leading design. But it is an L1 mechanism by construction - a Core EIP that requires FOCIL (EIP-7805) - and FOCIL is itself only scheduled for Hegota, whose meta EIP (8081) is still a draft that lists LUCID neither as scheduled nor as considered; enshrinement is a fork beyond that at the earliest. The rationale does discuss L2s, but to argue the opposite of scope: that “conditions on L2s do not translate to LUCID”, because “in most L2 designs there is no comparable block-level clearing step at the IIB”. Rollups have neither that clearing step nor FOCIL - which is exactly why sequencer MEV on an L2 is not what the enshrinement track addresses. That is the gap this work targets, with an architecture deliberately similar in spirit to what the EIPs propose for L1: a native encrypted transaction type handled inside the protocol, not an application-layer workaround.

Design

  • Threshold encryption. Boneh-Franklin IBE on BLS12-381, using the Shutter library that runs the Gnosis Chain deployment (shcrypto/puredkg) behind a stable CryptoProvider interface. A keyper committee runs a Feldman-VSS DKG with accusation/apology rounds (Shutter’s puredkg) to produce a shared eon public key; users encrypt against (eon key, epoch identity).
  • Encrypt-before-sequencer. A transaction’s real payload (a normal signed EIP-1559 / legacy tx) is encrypted; only cleartext accounting fields (chain id, nonce, gas, fees, sender), the target (eon, epoch) and the ciphertext are visible in the mempool, so the sequencer can order and do nonce/balance accounting without reading contents. This means sender, gas and timing metadata stay visible in Phase 0 (the accounting fields are needed for anti-spam and fee accounting before decryption, the epoch because the pool has to group by it): content is hidden, but the transaction’s silhouette (who, roughly what gas class, which block it is aimed at) still leaks, so an informed observer can place a paid speculative bet rather than a free one. Closing this metadata channel (gas buckets, relayed/meta-transactions, batching for k-anonymity, or ZK admission proofs in the GhostPool style) is explicit Phase 2+ work, not Phase 0.
  • Commit-order-before-decrypt. The sequencer fixes the transaction order (FIFO from the encrypted subpool) while the transactions are still ciphertext. Only then is the epoch decryption key consulted. Once the threshold is reached the keypers combine the key, verify it against the eon public key (a check every node can run) and hand it to the sequencer directly; an on-chain EpochRegistry is the intended public record and second source, and the sequencer repeats the verification on every key it acts on, whichever way it arrived, so a forged key is ignored rather than used. Writing to that registry takes threshold-many keyper attestations of the same key, so a single party cannot occupy - and thereby permanently burn - an epoch’s slot. Phase-0 caveat: only the reading side exists so far. The sequencer reads and verifies the registry, but the keyper prototype does not write to it yet, so direct delivery is in practice the only path today.
  • Decrypt-then-execute. With the verified key, the committed batch is decrypted in the fixed order and fed into the standard EVM. Undecryptable transactions (wrong key) are dropped; the committed order carries through to execution.
  • Phased granularity. Per-block IBE (Phase 0, simplest) → per-tx IBE (Phase 1, closes the per-block pending-tx-privacy gap formalized at USENIX Security 2024) → batched threshold encryption (Phase 2). The stable CryptoProvider interface makes each step a provider swap, not a rewrite. One trade-off worth naming: with a single per-block epoch key the committee can only ever decrypt all-or-nothing - it cannot selectively decrypt or censor individual transactions; per-tx granularity trades that property for pending-tx privacy.

Security properties

Guarantee Mechanism
Sequencer cannot read tx contents threshold IBE (BLS12-381)
Sequencer cannot reorder on content order committed while encrypted (FIFO); the commitment is local in Phase 0, see question 4
Sequencer cannot forge the epoch key verified against the eon public key before use, by the keypers and again by the sequencer; published on-chain as the record
No single keyper can decrypt t-of-n threshold
Sender cannot selectively reveal or withhold decryption is performed by the committee, not the sender - there is no commit-and-reveal optionality
Key cannot be precomputed keypers release shares only after the block deadline (protocol rule; the chain-coupled trigger is devnet wiring)
Late submitter who can already derive the key cannot enter the epoch epochs close before shares are gossiped; the first committed ordering is frozen
No intermediate block between key release and execution the verified key reaches the sequencer directly and the committed batch executes at the top of the first block built afterwards; what remains is a network-latency race at release

The canonical weaknesses catalogued for this pattern are committee capture, pre-decryption metadata leakage, post-quantum exposure, and loss of liveness when fewer than t keypers are available. They fare differently here. Liveness holds for any t honest keypers because decryption shares are verified against each keyper’s eon public key share on receipt, so a keyper that gossips garbage under a valid signature cannot poison the combination. The metadata channel is named explicitly and scoped to Phase 2+. Post-quantum exposure is contained architecturally, not solved: the CryptoProvider interface keeps the scheme out of the protocol logic, so a post-quantum scheme can replace BLS12-381 IBE without a rewrite - but such a scheme does not exist in deployable form yet, which is the same blocker the L1 working group is weighing. Committee capture is not a protocol property and remains open; the recent trustless-bribery argument (a TEE that pays keypers only once it holds threshold-many shares) makes it concrete and cheap, and it is what the first feedback question below is about. It also looks different depending on who the keypers are: in the regulated setting this targets first, the keyper set would be a consortium of identified, legally accountable entities, where a covert share sale is a breach of contract with an identifiable counterparty rather than an anonymous rational trade - which does not remove the problem, but changes its economics.

Implementation status

Working and reproducible (Go, open source):

  • DKG across a keyper committee over libp2p GossipSub; 3 keypers independently derive the same eon public key.
  • Threshold encryption, threshold-share aggregation, epoch-key verification, and a decrypt pipeline that turns a sealed epoch into the committed batch in its frozen order. This half stops at the batch: the keyper prototype hands it to a seam, and it is the op-geth fork below that feeds it to the EVM. docker compose up + a demo script shows DKG → encrypted payloads → threshold shares → an identical decrypted block on every node, and that a single share does not decrypt (threshold safety).
  • KeyperSet and EpochRegistry contracts (Foundry).

Implemented and unit-tested in the op-geth fork (steps toward a real chain):

  • A native EncryptedTx (EIP-2718 type 0x70) transaction type, signed and verified with the standard typed-transaction scheme.
  • An encrypted subpool (txpool.SubPool) that validates cleartext only and groups transactions FIFO by target epoch.
  • A sequencer that commits the ordering before the key exists and then takes the key from either source - delivered directly by the keypers, or read from the on-chain EpochRegistry - verifying it against the eon public key in both cases.
  • Direct key delivery: once the keypers have combined and verified an epoch key they push it to the sequencer over an authenticated JSON-RPC endpoint; the sequencer verifies it again, caches it, and rebuilds the block it is working on if the key arrives mid-way. The on-chain registry is the intended public record and fallback; in Phase 0 the sequencer already reads and verifies it, but nothing writes to it yet.
  • A decrypt pipeline that turns a sealed epoch into an executable batch for the StateProcessor.
  • A top-of-block miner hook: committed epochs are decrypted and placed directly after the forced deposit txs, before the public-pool fill, in the first block built after the key reaches the sequencer. Appending them at the end would let anyone read the pending ciphertexts (the epoch key is necessarily public by inclusion time, since shares are gossiped) and front-run them inside the same block - the sequencer would be assembling the sandwich itself - and executing them one block later would leave an intermediate block in which the key is already public. There is no such block. What remains is a network-latency race at key release, covered by a short wait in the first build, and back-running by whoever observes the shares, which this class of design does not remove; the encrypted path also gets gas priority. The Flashbots SoK’s main objection to the pattern is that it also suppresses the same-block back-run auctions that return value to users; Tacet’s layout keeps the public pool behind the decrypted batch, so back-running - and refund-style auctions on it - remains possible.
  • An epoch roll-over hardened against informed late submitters: epochs close monotonically at head-advance, strictly before decryption shares are gossiped, and the first committed ordering per epoch is frozen against later pool mutations. A transaction submitted after the key became derivable can neither enter the sealed plan nor the closed epoch - the sender must re-encrypt for an open epoch, and the IBE binding prevents re-targeting the old ciphertext.

Not done: converging the standalone keyper prototype onto the canonical shcrypto wire formats, coupling its share release to the chain head (today the release is triggered by the orchestrator) and having it publish the combined key to the registry (the contracts exist; the prototype does not write to them yet); a running OP-Stack devnet; external audit. Phase 0 prototype, solo builder.

Where I would value feedback

  1. Keyper committee. The trust property is only as good as the committee’s decentralization. What is the most credible path to a permissionless / rotating keyper set with slashing, and how have others handled keyper liveness vs. the block deadline - and what, short of social accountability, deters the TEE-brokered share sale that the LUCID discussion has put on the table? For the regulated use case the first committee would be an identified, bonded consortium rather than a permissionless set: is a permissioned set with a permissionless expansion path a credible design, or does it merely defer the question?
  2. Relationship to the enshrinement track (EIP-8105 / EIP-8184 “LUCID”) and the shutterized OP Stack. Both EIPs are deliberately encryption-scheme-agnostic, and the criticism thread identifies sender reveal-optionality as the resulting core weakness, naming threshold decryption by a committee as the structural fix while judging the schemes available for L1 enshrinement not there yet. Since then the committee route has drawn its own critique - a committee can be bribed trustlessly and invisibly through a TEE that reconstructs the key only once threshold-many shares and a payment are in - and a validator-maintained key-publisher whitelist was floated as a middle ground; the LUCID thread’s August update states that no convincing alternative design has emerged and that the main issue is the required post-quantum cryptography. The first set of constraints is L1-specific (validator-set-scale DKG, enshrinement-grade maturity, post-quantum security) and a rollup with an explicit, bonded keyper set does not face it; the TEE-bribery objection is not L1-specific and applies to Tacet’s committee as much as to any other - which is why question 1 is the one I most want answered, and why a committee that is actually running is a useful data point on cost, latency and failure modes rather than an argument from first principles. Where should such an L2 implementation converge with the enshrinement track (envelope formats, key-provider interfaces via the CryptoProvider abstraction), and where is separate L2-native design genuinely warranted, given that LUCID builds on L1 primitives (FOCIL, a slot-level clearing step) that rollups do not have?
  3. Encryption granularity. Per-block IBE has a proven pending-tx-privacy limitation (USENIX 2024). Is the per-block → per-tx → batched-TE migration behind a provider interface the right sequencing, or should a prototype start at per-tx?
  4. Sequencer decentralization. Encryption removes sequencer trust over content, not over liveness/censorship/ordering-commitment. How should the ordering commitment itself be made verifiable (e.g., TEE attestation of “I committed before I decrypted” vs. a purely cryptographic commitment)?
  5. Envelope signature. The outer encrypted-tx envelope is signed with the native typed-tx scheme (chain-id replay protection). For stock-wallet UX this would need EIP-712 typed data instead - is a native type or an EIP-712 envelope the better long-term choice?

Links

Feedback welcome, and if anyone is interested in running a keyper on a testnet, please reach out.