ダークプール実装解剖

Codebase Guide — Renegade · Penumbra · Privacy Pools · Aztec 3 · RAILGUN · ZKBob

Overview — Choosing the Right Codebase

For dark pool implementers Only Renegade (MPC P2P matching) and Penumbra (batch auction) implement actual order matching with privacy. Privacy Pools, RAILGUN, and ZKBob are shielded deposit/withdrawal primitives. Aztec 3 is a programmable substrate you build matching on top of.

Full Comparison Matrix

Project Type ZK System ZK Color Circuit Lang Chain Compliance Matching Status Dark Pool?
Renegade Dark Pool colzkSNARK (PLONK) PLONK Rust Arbitrum One None MPC P2P Mainnet 2024-09 Yes
Penumbra Shielded L1 Groth16 Groth16 Rust (arkworks) Cosmos / IBC External バッチオークション (FBA) Mainnet Yes (batch)
Privacy Pools Compliance Pool Groth16 Groth16 Circom Ethereum ASP (assoc. set) N/A Mainnet 2025-03 No
Aztec 3 Smart Contract L2 UltraHONK UltraHONK Noir Ethereum L2 Programmable Programmable Mainnet Nov 2025 Yes (programmable)
RAILGUN Private DeFi Wrapper Groth16 Groth16 Circom Multi-EVM PPOI (post-hoc) N/A Mainnet No
ZKBob Stablecoin Pool Groth16 Groth16 Circom Polygon / ETH / OP CM key (pre-emptive) N/A アクティブ No

ZK System Color Legend

Groth16

Groth16 (BN254)

Smallest proof size (~200 bytes). Requires per-circuit trusted setup. Native EVM precompile support (ecPairing). Used by: Penumbra, Privacy Pools, RAILGUN, ZKBob.

PLONK / colzkSNARK

Collaborative PLONK (BN254)

Universal trusted setup (one per curve). Enables MPC-in-the-head style collaborative proving. Ozdemir-Boneh 2022. Used by: Renegade.

UltraHONK

UltraHONK (barretenberg)

No trusted setup. Recursive. Developed by Aztec Labs. Powers Noir language. Very large gates (millions) feasible. Used by: Aztec 3.

Which Codebase to Fork?

What do you need? Need order matching / price discovery? YES Need EVM settlement? YES Renegade MPC + colzkSNARK + Stylus NO Penumbra バッチオークション + Groth16 NO Need programmable smart contracts? YES Aztec 3 UltraHONK + Noir + L2 NO Need regulator-friendly compliance hook? YES Privacy Pools / ZKBob ASP assoc.set / CM キー Groth16 + Circom NO (just privacy) RAILGUN Private DeFi wrapper 54 Groth16 circuits
Key Trade-off: Liquidity vs. Privacy The fundamental problem all dark pools face: finding a counterparty requires revealing some information about your order. Renegade's IoI (Indication of Interest) mode partially reveals trade direction. Penumbra's batch auction sidesteps this by aggregating all orders. Aztec 3 lets you design your own trade-off.

Renegade — MPC Dark Pool with Collaborative ZK-SNARKs

Mainnet: 2024-09-03 PLONK / colzkSNARK Arbitrum One (Stylus) Rust 99.5% GitHub

ZK / MPC Stack

  • Proof system: PLONK-based collaborative SNARK
  • Curve: BN254 (EVM precompile compatible)
  • MPC: 2-party SPDZ-style (relayer-to-relayer)
  • Hash in circuit: Poseidon
  • Commitment: Pedersen + Poseidon
  • MPC framework: mpc-stark (renegade-fi fork)

Trust Model

  • Relayer holds pk_matchsemi-trusted (Type B)
  • Intra-cluster: Raft fail-stop
  • Inter-cluster: ビザンチン耐性 MPC ハンドシェイク
  • Stylus: censorship resistant; integrity via ZK

Repository Architecture

renegade/
├── crates/
│   ├── circuits/           # ZK circuits + colzkSNARK (most important)
│   │   ├── src/
│   │   │   ├── zk_circuits/
│   │   │   │   ├── valid_commitments.rs
│   │   │   │   ├── valid_reblind.rs
│   │   │   │   ├── valid_commitments_match.rs
│   │   │   │   ├── valid_match_settle.rs
│   │   │   │   ├── valid_wallet_create.rs
│   │   │   │   ├── valid_wallet_update.rs
│   │   │   │   └── valid_offline_fee_settlement.rs
│   │   │   └── mpc_circuits/   # collaborative proving
│   ├── workers/            # actor model: MPC handshake / proof gen / matching engine
│   │   ├── handshake_manager/  # relayer-to-relayer MPC coordination
│   │   ├── proof_manager/      # async proof generation
│   │   └── matching_engine/    # order book + match execution
│   ├── state/              # Raft-like cluster state (fail-stop intra-cluster)
│   ├── darkpool-client/    # RPC client to Stylus on-chain contract
│   ├── system-primitives/  # Wallet, Order types (shared off/on-chain)
│   ├── core/               # core business logic + handshake protocols
│   └── api/                # REST + WebSocket API endpoints
└── contracts/              # Arbitrum Stylus (same Rust code → WASM)
Stylus Advantage Because Arbitrum Stylus compiles Rust to WASM for on-chain execution, Renegade shares the same codebase between off-chain workers and on-chain verifier. This drastically reduces the audit surface area. Gas cost is ~$0.30/settlement vs ETH L1.

7 ZK Circuits (NP Statements)

MPC Handshake Flow (Counterparty Matching)

1
Order Placement User submits signed order to relayer. Relayer stores commitment in local state (Raft replicated). No order details visible on-chain.
2
IoI Broadcast (optional) Relayer sends Indication of Interest to peer relayers. Reveals: trade direction (buy/sell), token pair. Does NOT reveal: size, price, wallet identity.
3
MPC Handshake Initiation Two relayers with potentially matching orders enter SPDZ-style 2PC. They compute VALID COMMITMENTS MATCH collaboratively. Neither learns the other's order unless match is proven.
4
Collaborative Proof Generation Both relayers generate a shared PLONK proof of VALID MATCH SETTLE using colzkSNARK (Ozdemir-Boneh 2022). Each holds one share; neither can reconstruct the full witness alone.
5
On-chain Settlement (Stylus) Aggregated proof submitted to Arbitrum Stylus contract. Contract verifies PLONK proof, updates Merkle commitment tree, emits nullifiers. ~$0.30 gas cost.
6
Wallet State Update Both users' wallets updated (VALID REBLIND + VALID WALLET UPDATE proofs). New commitments inserted, old nullified. User can verify their balance via ZK.
The IoI Problem — Why Renegade is Hard Without IoI mode, users have full privacy but can't find a counterparty — your order sits silently in a relayer with no P2P network formation. IoI mode partially solves this by leaking trade direction to relayers, but that means relayers learn your intent. This bootstrapping problem kept Renegade in testnet for 2+ years. The production system on Arbitrum launched 2024-09-03 with IoI as the default mode.

Penumbra — Fully Shielded L1 with Batch Auction DEX

Mainnet (Cosmos) Groth16 / BLS12-377 Apache-2.0 / MIT dual GitHub

ZK Stack

  • Proof system: Groth16
  • Curve: BLS12-377
  • Internal group: decaf377 (cofactor-clear Edwards)
  • Library: arkworks-rs
  • Consensus: CometBFT (prev. Tendermint)

3-Binary Architecture

  • pd — full node (never holds plaintext)
  • pcli — user wallet CLI
  • pclientd — view daemon (trial-decrypts all notes)
UX Bottleneck pclientd trial-decrypts every note in the chain to find wallet's — O(n) scan cost grows with chain size.

Repository Architecture

penumbra/
├── crates/
│   ├── core/
│   │   ├── component/
│   │   │   ├── shielded-pool/   # ABCI handler for spend/output/notes
│   │   │   ├── dex/             # Batch auction DEX logic
│   │   │   ├── stake/           # Delegation + governance
│   │   │   └── fee/             # Transaction fee handling
│   │   └── crypto/
│   │       ├── decaf377/        # cofactor-clear Edwards curve
│   │       ├── poseidon377/     # Poseidon hash over BLS12-377
│   │       └── pedersen/        # Pedersen commitments (multi-asset)
│   ├── bin/
│   │   ├── pd/                  # Full node binary
│   │   ├── pcli/                # CLI wallet
│   │   └── pclientd/            # View server daemon
│   └── cnidarium-component/     # Custom state framework (replaces Cosmos SDK store)
└── proto/                       # gRPC definitions

7 ZK Circuits

Batch Auction DEX Design (FBA-Style)

Penumbra's DEX does not use a continuous double auction (CDA / order book). Instead it uses a Frequent Batch Auction (FBA) — orders are aggregated per block and cleared at a single uniform price.

1
Order submission (Swap circuit) During block N: user submits Swap proof. Amount committed as Pedersen commitment, trading pair public. Validators include in block without knowing sizes.
2
バッチ集約 End of block: all Swap commitments aggregated. Validators compute aggregate supply/demand curves from commitments (homomorphically).
3
Uniform price clearing Block N+1: batch cleared at single uniform clearing price. All orders executed at same price — eliminates MEV from ordering within batch.
4
SwapClaim circuit User proves their Swap commitment, receives output token notes at clearing price. No front-running possible — price fixed before anyone can react.
Why FBA Eliminates MEV Since all orders at the same price are treated identically and the clearing price is set after all orders are committed, there is no advantage to transaction ordering within a batch. Front-running requires knowing the price before execution — FBA removes this window.

Multi-Asset Privacy

Penumbra uses separate Pedersen generators per asset. Each asset type has its own generator point on decaf377. This prevents cross-asset correlation attacks while allowing homomorphic balance checks.

// Commitment to amount v of asset a:
// C = v * G_a + r * H
// where G_a is asset-specific generator, H is blinding generator
// Different assets use different G_a — cannot aggregate across assets
Production Security Note zkSecurity audit (2024) found 2 high-severity bugs: a double-spend bug and a double-vote bug in circuits. Both were fixed before mainnet. This is the typical ZK production pattern — expect critical bugs in circuit code even after careful design.

Privacy Pools / RAILGUN / ZKBob — Compliance-Oriented Codebases

These are not dark pools — they are shielded deposit/withdrawal primitives. No order matching. But their compliance mechanisms are directly applicable to any dark pool that needs regulatory integration.

Privacy Pools / 0xbow

Mainnet: 2025-03 Groth16 / BN254 TypeScript 55% / Solidity 38% / Circom 1% GitHub

アーキテクチャ

privacy-pools-core/
├── packages/
│   ├── circuits/    # Circom 2.x + snarkjs setup artifacts
│   │   ├── withdraw.circom
│   │   └── ptau/   # Groth16 trusted setup files
│   ├── contracts/   # Solidity
│   │   ├── Entrypoint.sol      # deposit/withdraw router
│   │   ├── PrivacyPool.sol     # per-asset shielded pool
│   │   ├── State.sol           # commitment Merkle tree
│   │   ├── ASPManager.sol      # manages ASP roots
│   │   └── Verifier.sol        # Groth16 on-chain verifier
│   ├── relayer/     # minimal gasless relayer
│   └── sdk/         # TypeScript (dapp integration)

Association Set Provider (ASP) — 核心イノベーション

state_tree = MerkleTree(
  all deposit commitments  // full set
)
asp_tree = MerkleTree(
  approved-only commitments // curated subset
)

// Withdrawal proof requires inclusion in BOTH:
withdrawal_proof {
  private: note, secret, path_in_state_tree, path_in_asp_tree
  public:  state_root, asp_root, nullifier
}

// Semantics:
// "I am SOMEONE in the clean subset"
// (NOT who exactly — subset membership, not identity)
ASP トラストリスク ASP signer (0xbow) can include/exclude commitments from the clean set. ASP compromise = criminals could enter clean subset, but funds are still safe. Trust model: audited centralized curator.

RAILGUN

Multi-chain Mainnet Groth16 / BN254 Circom + TypeScript + Solidity ETH / BSC / Polygon / Arbitrum GitHub Org

Key Design: 54 Specialized Circuits

// [1-10 inputs] × [1-10 outputs] = 100 combinations
// But only valid: inputs ≥ 1, outputs ≥ 1 → 54 circuits
// Each circuit is pre-compiled + trusted-setup'd
// Allows gas-optimal proof for exact tx shape

// Example:
circuit_1_1.zkey   // 1 input, 1 output
circuit_2_3.zkey   // 2 inputs, 3 outputs
// ...
circuit_10_1.zkey  // 10 inputs, 1 output

PPOI — Proof of Innocence (Post-hoc Compliance)

// Public inputs:
txidMerkleRoot         // full Tx Merkle Tree root
blocklistTxidMerkleRoot // blacklist Tx root
blindedCommitment       // hidden commitment

// Circuit proves:
// 1. My Tx IS in the full tree (I am valid user)
// 2. My Tx is NOT in the blacklist tree (I am clean)

// Key: prover does NOT reveal which Tx is theirs
// Semantics: "I can prove I'm not on the blacklist"
// without revealing what I did

Private DeFi Cookbook (Railgun-Community/cookbook)

Pre-built recipes for using any DeFi protocol privately via RAILGUN. Gas paid by Broadcaster (relayer) via RAILGUN internal tokens.

// Example: private Uniswap V3 swap
const recipe = new UniswapV3SwapRecipe(
  tokenIn, tokenOut, amount,
  slippage, deadline
);
const shieldedTx = await railgun.generateShieldedTransaction(recipe);
// → Broadcaster pays gas, receives tip in RAILGUN tokens
// → No on-chain link between user's wallet and UniswapV3 call

ZKBob

アクティブ Groth16 / BN254 Circom 2 + TypeScript Polygon / ETH / Optimism GitHub Org

Compliance Manager Key (Pre-emptive Compliance)

// Every Note includes DUAL encryption:
Note = {
  amount:       encrypted_to_recipient_key,
  audit_log:    encrypted_to_pk_cm,  // ← audit trail
  nullifier:    ...,
  commitment:   ...
}

// Flow:
// Regulator subpoenas exchange
// Exchange → CM → decrypts audit_log for specific Notes
// → reveals specific tx details for that user
// Key: CM can decrypt ALL tx but is trusted not to do so

Universal Transaction Circuit

// ZKBob: 1 universal circuit handles all tx types
// vs RAILGUN: 54 specialized circuits

// Universal circuit inputs:
{
  type: deposit | transfer | withdrawal,
  inputs: Note[],     // max configurable
  outputs: Note[],    // max configurable
  fee: amount,
  cm_audit_log: ...,  // always included
}
// Simpler audit, higher circuit complexity

反構造化コントロール

ZKBob enforces withdrawal limits per period on-chain to prevent structuring (breaking large amounts into small transactions to evade detection). This is a circuit-level constraint, not just policy.

Compliance Mechanism Comparison

Feature Privacy Pools (ASP) RAILGUN (PPOI) ZKBob (CM Key)
Compliance model Subset membership Post-hoc exclusion proof Pre-emptive audit log
Who curates? ASP (0xbow — centralized) ブロックリスト保守者(外部) Compliance Manager key holder
Timing 引き出し時(セットに含まれる) Post-tx (prove not blacklisted) トランザクション作成時(常にログ記録)
Regulator access Set membership only Nothing (user self-proves) Full tx details via CM
Criminal can exit? If ASP approves (fail: ASP compromised) ブロックリストが引き出し証明を防止 Yes, but tx is logged
Token scope Any ERC-20 (per pool) Any ERC-20 USDC / BOB stablecoin
Circuit count 2 (withdraw circuit) 54 specialized 1 universal

Aztec 3 — プログラム可能なプライベートスマートコントラクト L2

Mainnet: Nov 2025 ("Ignition Chain") UltraHONK (barretenberg) Noir language C++ 42% / TypeScript 35% / Noir 10% GitHub
Why Aztec for a dark pool? Aztec 3 gives you a general-purpose private computation substrate. You write the matching logic in Noir, the proof system handles privacy. You can implement any matching mechanism: CDA, batch auction, RFQ, etc. — without compromising on privacy.

Proof System: UltraHONK

  • No trusted setup — transparent SRS
  • Recursive proofs — stack arbitrary depth
  • バックエンド: barretenberg (C++, Aztec Labs)
  • Frontend: Noir DSL → ACIR → barretenberg
  • Very large circuits (millions of gates) feasible

PXE — Private eXecution Environment

The PXE runs on the user's device (or trusted server). It:

  • Holds user's private keys
  • Executes private contract functions locally
  • Generates proofs before submitting to sequencer
  • Trial-decrypts incoming notes (like pclientd in Penumbra)

Sequencer never sees private inputs — only sees the proof and public outputs.

Private Kernel Circuit — 5 Phases

Every private transaction runs through this pipeline on the user's device (PXE). Each phase is a separate proof, recursively accumulated.

1
private_kernel_init — First private function call Initializes the accumulator. Verifies the app circuit's proof for the first private function call in the tx. Sets up the accumulated side-effects structure.
2
private_kernel_inner — Subsequent calls (repeat) For each additional private function call: verifies app circuit proof, accumulates side-effects (note creations, nullifiers, contract calls). Runs once per inner call.
3
private_kernel_reset — Squash transient pairs Squashes transient note/nullifier pairs (note created and consumed in same tx). Enforces max side-effect limits. Reduces accumulated state.
4a
private_kernel_tail — Tail (private-only tx) Sorts side-effects deterministically, converts to rollup format. Final private proof — submitted to public sequencer as opaque blob + public outputs.
4b
private_kernel_tail_to_public — Tail-to-public Splits side-effects into revertible / non-revertible halves. Passes public call requests to sequencer for public execution. Enables hybrid private+public tx.

Gate Counts (Typical 2-Private-Call TX)

Approximate gate counts — actual varies by circuit version and app complexity. Max is private_kernel_inner (~101k gates) × number of inner calls.

SchnorrAccount:entrypoint~22,000 gates
User contract function~14,000 gates
private_kernel_init~46,000 gates
private_kernel_inner (×1)~101,000 gates
private_kernel_reset~200,000 gates
private_kernel_tail~44,000 gates
Total (2-call tx) ~427,000 gates

Noir Language — Writing Private Contracts

// Noir: Rust-like DSL for ZK circuits
// Used for: application contracts, protocol circuits, standalone ZK programs

// Example: private order struct in Noir
struct PrivateOrder {
    amount:     u64,          // private
    price:      u64,          // private
    direction:  bool,         // private (true=buy)
    commitment: Field,        // public output
    nullifier:  Field,        // public output (when consumed)
}

// Private function (runs in PXE, no sequencer visibility)
#[aztec(private)]
fn submit_order(
    order: PrivateOrder,
    context: &mut PrivateContext
) -> Field {
    // Hash order to commitment
    let commitment = pedersen_hash([order.amount, order.price, order.direction]);
    // Emit note to private state
    context.emit_note(OrderNote { commitment, owner: context.msg_sender() });
    commitment
}

// Public matching function (sequencer executes, visible on-chain)
#[aztec(public)]
fn match_orders(
    buyer_nullifier: Field,
    seller_nullifier: Field,
    clearing_price: u64,
) {
    // Verify nullifiers not already used
    assert(!storage.nullifiers.contains(buyer_nullifier));
    assert(!storage.nullifiers.contains(seller_nullifier));
    // ... settlement logic
}
Aztec for Dark Pool Submit order is private (Noir, runs in PXE). Match is public (sequencer). Settlement writes to private notes. This gives you a programmable dark pool where order contents are private but matching is verifiable.

自前ダークプールの構築 — 実装ガイド

開始前に Building a privacy-preserving system without ZK expertise is extremely high-risk. The Penumbra audit found 2 high-severity bugs. Budget 6-18 months for a production-ready system. Consider forking an audited codebase before writing from scratch.

Key Decision Flowchart

D1: Need EVM settlement? (on Ethereum / L2) NO (own chain) D2: Need programmable matching logic? D2b: Want batch auction (FBA)? Fork Penumbra Cosmos + Groth16 + arkworks YES Aztec 3 で構築 Noir + UltraHONK + L2 YES NO (MPC matching) Fork Renegade Rust + colzkSNARK + Stylus D3: Need compliance hooks? (regulator access / audit trail) YES (post-hoc subset) ASP パターン追加 (Privacy Pools model) No compliance (pure privacy) NO YES (pre-emptive audit) CM キーパターン追加 (ZKBob model)

Recommended Stack by Goal

Goal: Fastest to Mainnet

Fork Renegade

  • 監査済みプロダクションコードベース
  • Stylus = shared off/on-chain Rust
  • 7 circuits already implemented
  • MPC framework (mpc-stark) ready
  • EVM settlement day 1

Risk: IoI problem, business-source license

Goal: Maximum Programmability

Aztec 3 で構築

  • Noir DSL — accessible ZK contracts
  • No trusted setup needed
  • Ethereum L2 — existing liquidity
  • Hybrid public/private execution
  • Define your own matching logic

Risk: ecosystem new, higher dev complexity

Goal: Institutional Compliance

Fork Privacy Pools + CM Key

  • ポストホック部分集合証明用 ASP
  • CM key for pre-emptive audit trail
  • Circom + snarkjs — simple tooling
  • Ethereum mainnet ready
  • Regulatory engagement possible

Risk: centralized ASP trust assumption

Step-by-Step Implementation Guide

Phase 1: Define Adversary Model (Week 1-2)

QuestionAnswer defines
Who is your adversary: relayer, sequencer, or both?MPC design, ZK circuit scope
Semi-honest or malicious adversary?SPDZ overhead vs simpler protocols
What leaks on match? (price, size, direction)IoI design, circuit inputs
Regulatory jurisdiction?Compliance hook (ASP vs CM key vs none)
MEV protection needed?バッチオークション対 CDA

Phase 2: Choose Matching Mechanism (Week 2-3)

バッチオークション (FBA) — 推奨

  • Eliminates front-running entirely
  • Uniform clearing price = no order priority MEV
  • Simpler circuit: no real-time matching state
  • Penumbra reference implementation
  • 最適用途: 機関投資家向けダークプール

MPC Continuous Matching

  • Renegade approach: real-time 2PC matching
  • Harder: counterparty discovery problem
  • Requires P2P relayer network
  • IoI leaks partial order info
  • 最適用途: 高頻度/トレーダーUX

Phase 3: Circuit Development (Month 1-4)

# Minimum viable circuit set for a dark pool:

1. DEPOSIT CIRCUIT
   Input:  amount (private), asset (public), nonce (private)
   Output: commitment (public), nullifier_key (private)
   Proves: commitment = hash(amount, asset, nonce)

2. ORDER CIRCUIT (submit)
   Input:  price, size, direction (all private), wallet_commitment (public)
   Output: order_commitment (public), order_nullifier_hint (private)
   Proves: wallet has sufficient balance for order; order params valid

3. MATCH CIRCUIT (collaborative, run via MPC)
   Input:  buyer_order (private-shared), seller_order (private-shared)
   Output: match_exists (public), clearing_price (public if FBA)
   Proves: orders overlap (price_buy >= price_sell, same asset pair)

4. SETTLE CIRCUIT
   Input:  match_proof, buyer_wallet, seller_wallet (all private)
   Output: new_buyer_commitment, new_seller_commitment (public)
           buyer_nullifier, seller_nullifier (public)
   Proves: balances updated correctly, conservation holds

5. WITHDRAW CIRCUIT
   Input:  note (private), nullifier_key (private)
   Output: nullifier (public), amount (public)
   Proves: note valid, not previously spent

# Timeline estimate:
# - Groth16 + Circom: 2-3 months (simpler tooling, less expressive)
# - PLONK + Rust:     3-5 months (more expressive, heavier)
# - Noir + UltraHONK: 2-4 months (easiest DX if using Aztec)

Phase 4: MPC Layer (Month 3-5, if needed)

# For MPC-based matching (Renegade pattern):

# Option A: Use mpc-stark (Renegade's fork)
git clone https://github.com/renegade-fi/mpc-stark
# Implements: SPDZ preprocessing, Beaver triples, authenticated shares
# Interface: MpcFabric::new() → share values → compute circuits jointly

# Option B: MP-SPDZ (academic reference)
git clone https://github.com/data61/MP-SPDZ
# Full SPDZ, MASCOT, LOWGEAR protocols
# More protocols but heavier — good for research

# Minimum MPC design for dark pool:
# - Preprocessing phase: generate Beaver triples offline
# - Online phase: share order values, compute match predicate jointly
# - Output: both parties learn match result (and proof) but not each other's order

Phase 5: Trusted Setup (Groth16 only)

If using Groth16: Trusted Setup is Required and Non-Trivial Each circuit needs its own phase-2 ceremony. Use snarkjs or Hermez's ceremony infrastructure. Compromise of setup → ability to forge proofs. For a production system, run a large public ceremony (100+ participants). Alternatively: switch to PLONK or UltraHONK to avoid this entirely.
# snarkjs ceremony workflow:
# Phase 1 (powers of tau — universal):
snarkjs powersoftau new bn128 20 pot20_0000.ptau
snarkjs powersoftau contribute pot20_0000.ptau pot20_0001.ptau --name="contributor1"
# ... repeat with many contributors
snarkjs powersoftau prepare phase2 pot20_final.ptau pot20_final_pp.ptau

# Phase 2 (circuit-specific):
snarkjs groth16 setup order_circuit.r1cs pot20_final_pp.ptau order_0000.zkey
snarkjs zkey contribute order_0000.zkey order_0001.zkey --name="contributor1"
snarkjs zkey beacon order_0001.zkey order_final.zkey [beacon_hash] 10
snarkjs zkey export verificationkey order_final.zkey verification_key.json

# Export Solidity verifier:
snarkjs zkey export solidityverifier order_final.zkey verifier.sol

Phase 6: Security Audit Checklist

カテゴリCheckTool / Method
Circuit soundness Under-constrained signals → forged proofs Manual review + circom-mutator / Picus
Nullifier uniqueness Double-spend possible? Formal verification (Lean/Coq) or manual
Arithmetic overflow Field arithmetic edge cases Ecne (Trail of Bits) for R1CS
Trusted setup Toxic waste properly destroyed? セレモニートランスクリプトレビュー
MPC protocol 中止/不正行為パーティ回復 Protocol analysis + UC simulation
Smart contract Reentrancy, access control, verifier linkage Slither / Aderyn / manual
Nullifier set Merkle tree soundness, root manipulation ZK circuit audit specialist
Minimum: 2 independent audits Penumbra had 2 high-severity bugs found in first audit. Budget $150k-$400k for professional ZK circuit audit (firms: zkSecurity, Trail of Bits, Least Authority, Veridise).

Phase 7: Launch Strategy

1
Devnet (Month 6-9) Internal test network. Fuzz circuits, test MPC abort scenarios, measure proof generation time on target hardware.
2
Incentivized Testnet (Month 9-14) Public participants. Reward bug reports. Measure latency, gas costs, relayer P2P formation. This is where Renegade spent 2 years.
3
Limited Mainnet with Caps (Month 14-18) Deploy with protocol-level deposit caps ($1M initial). Graduate caps as confidence grows. Monitor on-chain for unexpected state transitions.

Gas Cost Benchmarks (Reference)

SystemSettlement CostProof Verify CostNotes
Renegade (Arbitrum Stylus)~$0.30PLONK on WASMStylus ~10× cheaper than Solidity
Privacy Pools (Ethereum)~$8-15Groth16 ecPairing (~250k gas)EVM precompile
RAILGUN (Ethereum)~$12-25Groth16 × 1 circuitMore inputs/outputs = more gas
Aztec 3 (L2)~$0.10-0.50Rollup amortized多数のトランザクションにわたってバッチ処理
Penumbra (Cosmos)Low fixed feeGroth16 in validatorNo EVM overhead
結論 For a developer ready to ship: fork Renegade for MPC dark pool on EVM, or build on Aztec 3 for programmable privacy. For a researcher: study Penumbra's batch auction design — it solves MEV more cleanly than any CDA system. For compliance: read Privacy Pools' ASP whitepaper (Buterin et al. 2023) before designing your compliance hooks.