name: zk-evm description: > Activate when the user works with Tokamak zk-EVM, tokamak-cli, zero-knowledge proofs for Ethereum transactions, the Synthesizer, QAP compiler, subcircuits, Circom circuits, zk-SNARK backend, trusted setup, placementVariables, permutation, or TokamakL2JS. license: MIT metadata: author: tokamak-network version: "1.0.0"
Tokamak zk-EVM
Converts Tokamak L2 transactions into zero-knowledge proofs. The system has two halves: a frontend (TypeScript, compiles transactions → circuits) and a backend (Rust, proves and verifies circuits).
Source: https://github.com/tokamak-network/Tokamak-zk-EVM
Architecture
tokamak-cli (entry point)
│
├── Frontend (compilers)
│ ├── qap-compiler — Circom subcircuit library for EVM opcodes
│ │ Output: subcircuits/library/
│ └── synthesizer — Converts a transaction batch into a circuit
│ Output: placementVariables.json, instance.json,
│ instance_description.json, permutation.json
│
└── Backend (Rust)
├── trusted-setup — Generates reference string from subcircuit library
│ Output: combined_sigma.rkyv, sigma_verify.rkyv
├── prover — Generates zk proof from circuit + setup outputs
│ Output: zk proof file
└── verify — Accepts or rejects the proof
tokamak-cli Commands
The main entry point. All commands run from the repo root:
# 1. Install: deps, compile circuits, trusted setup
./tokamak-cli --install <ALCHEMY_API_KEY | RPC_URL>
# 2. Synthesize: transaction → circuit artifacts
./tokamak-cli --synthesize <path/to/input.json>
# 3. Preprocess: backend preprocess stage
./tokamak-cli --preprocess
# 4. Prove: generate zk proof
./tokamak-cli --prove
# 5. Verify: check proof validity
./tokamak-cli --verify
# 6. Extract proof bundle (optional)
./tokamak-cli --extract-proof <output.zip>
Monorepo Structure
Tokamak-zk-EVM/
├── tokamak-cli # Bash wrapper → scripts/tokamak-cli-core
├── packages/
│ ├── frontend/
│ │ ├── qap-compiler/ # Circom subcircuits (ALU1-5, crypto primitives)
│ │ │ ├── subcircuits/circom/ # Source .circom files
│ │ │ ├── subcircuits/library/ # Compiled output
│ │ │ └── scripts/compile.sh # Build script
│ │ └── synthesizer/ # TypeScript, converts tx → circuit
│ │ ├── src/
│ │ │ ├── synthesizer/ # EVM opcode hooking
│ │ │ ├── circuitGenerator/ # Witness/permutation generation
│ │ │ ├── interface/ # Input helpers (RPC, state)
│ │ │ └── TokamakL2JS/ # L2-specific primitives
│ │ ├── examples/ # L2TONTransfer, L2StateChannel
│ │ └── outputs/ # Generated circuit artifacts
│ └── backend/
│ ├── setup/ # trusted-setup (Rust) + mpc-setup (Rust)
│ ├── prove/ # Prover (Rust, ICICLE GPU acceleration)
│ └── verify/ # Verifier (Rust + Solidity)
├── synthesizer-input-template/ # Template input.json
├── config/ # Lerna/TS configs
└── docs/ # Team formatting rules
Synthesizer Input Format
The transaction config JSON (input.json):
{
"privateKeySeedsL2": ["sender seed", "recipient seed", ...],
"addressListL1": ["0x...", "0x...", ...],
"userStorageSlots": [0],
"senderIndex": 0,
"recipientIndex": 1,
"initStorageKey": "0x07",
"txNonce": 0,
"blockNumber": 23224548,
"contractAddress": "0x2be5e8c109e2197D077D13A82dAead6a9b3433C5",
"amount": "0x4563918244f400000",
"transferSelector": "0xa9059cbb"
}
Template: synthesizer-input-template/input.json
Synthesizer Outputs
After --synthesize, the outputs/ directory contains:
| File | Description | Used By |
|---|---|---|
placementVariables.json |
Subcircuit instances with wire values | Prover |
instance.json |
Public + private input values | Prover, Verifier |
instance_description.json |
Human-readable description of public inputs | Documentation |
permutation.json |
Copy constraints (wiring between subcircuits) | Prover |
QAP Compiler: Subcircuit Library
5 ALUs handle 256-bit EVM operations:
| ALU | Operations |
|---|---|
| ALU1 | ADD, MUL, SUB, SubExp, EQ, ISZERO, NOT |
| ALU2 | DIV, SDIV, MOD, SMOD, ADDMOD, MULMOD |
| ALU3 | SHL, SHR, SAR |
| ALU4 | LT, GT, SLT, SGT |
| ALU5 | SIGNEXTEND, BYTE |
Crypto primitives: Poseidon hash, EdDSA (jubjub + Poseidon) signatures, Merkle tree proofs.
Build the subcircuit library:
cd packages/frontend/qap-compiler
npm install
./scripts/compile.sh
Prerequisites
| Dependency | Purpose |
|---|---|
| Node.js >= 18 | Synthesizer, CLI |
| Circom | Subcircuit compilation |
| Rust | Backend (setup, prove, verify) |
| CMake | Backend build |
| Bun | Synthesizer binary build |
| dos2unix | Line ending conversion |
| Alchemy API key | Ethereum RPC for state queries |
macOS auto-setup: ./scripts/setup-macos.sh
Common Mistakes
| Mistake | Fix |
|---|---|
Running without --install first |
Always run --install before other commands |
| CRLF line endings on tokamak-cli | dos2unix tokamak-cli && chmod +x tokamak-cli |
Forgetting .env with RPC URL |
Create packages/frontend/synthesizer/.env with RPC_URL=... |
| Insufficient buffer sizes in qap-compiler | Increase buffer subcircuit sizes, recompile |
Committing .env with API key |
Delete .env after use, rotate key if exposed |
Code Style
- 120 char line width (not 80)
- Compact code preferred — one info unit = one line
- Prettier:
printWidth: 120, semi: true, singleQuote: true, arrowParens: "avoid" - Format:
npm run format
Full formatting rules: See references/formatting-rules.md
Supported / Unsupported Opcodes
Supported: ADD–SAR, EXP, SIGNEXTEND, ADDRESS–BASEFEE, POP, MLOAD/MSTORE, SLOAD/SSTORE, PUSH0–PUSH32, DUP/SWAP, LOG0–LOG4, CALL/CALLCODE/DELEGATECALL/STATICCALL, RETURN, REVERT
Not supported: KECCAK256, BLOBHASH, BLOBBASEFEE, TLOAD, TSTORE, CREATE, CREATE2, SELFDESTRUCT
Related Skills
- tokamak-contracts: Contract addresses used in synthesizer inputs
- thanos-l2: Thanos L2 where zk-EVM proofs are verified