Skip to content
erigontechPublic

About

A fast, modular, optimized ZKEVM core written in C++

Resources

Stars

13 stars

Watchers

0 watching

Forks

Latest commit

 

History

319 Commits

Folders and files

Repository files navigation

Project Logo

A fast, modular, optimized ZKEVM core written in C++

🚧 [ALPHA STAGE: This is in pre-release. Functional for block execution and proof generation, but not yet production-ready.] 🚧

Zilkworm is a prototype implementation of a ZKEVM (Zero-Knowledge Ethereum Virtual Machine) generating ZK proofs that an
Ethereum block was executed correctly, without requiring re-execution of the block itself.

Zilkworm is written in C++ (with a Rust orchestration layer) building on past works within Silkworm and EVMOne to run on zkVM provers with native support for RISC-V targets (e.g. rv32im). At the moment, the zkVM integrated is Succint's SP1 Hypercube.

High-Level Workflow

  1. Fetch — Retrieve a block + its execution witness from an Ethereum RPC node (Reth/Geth)
  2. Execute (dry-run) — Run the EVM inside the zkVM without proof generation (for testing)
  3. Prove — Generate a full ZK proof of correct block execution
  4. Verify — Verify a previously generated proof
  5. Service — Continuously poll a node and prove blocks as they arrive

Architecture

For a high-level overview of the system, see here.

How ZK Ethereum Provers Work Generally

The broader idea: a ZK prover takes an Ethereum block + pre-state witness, re-executes all transactions inside a zkVM and produces a cryptographic proof that the execution was done correctly. This proof can be verified cheaply by anyone on a lighter hardware without re-executing the block. This also enables other applications like light clients, bridges, and rollup verification.

Zilkworm sits alongside other ZKEVM provers in this ecosystem, differentiated by its approach of running a C++ EVM inside the zkVM rather than a Rust one.

How to Run

At the moment building from source requires elaborate setup with conan, linux packages and SP1 Turbo SDK pre-requisites. It's recommended to use the pre-built docker image.

To run with pre-built docker

$ docker run somnergy/z6m_prover --help
Usage: z6m_prover [OPTIONS] [COMMAND]

Commands:
  setup    Run setup to generate proving and verifying keys
  fetch    Fetch block and witness from RPC
  execute  Execute the guest program without proving
  prove    Generate a proof for a block
  verify   Verify a proof using a verification key
  help     Print this message or the help of the given subcommand(s)

Options:
      --service                                      
      --rpc-url <RPC_URL>                            
      --data-dir <DATA_DIR>                          [default: temp]
      --save-all-responses                           
      --prove-every <PROVE_EVERY>                    
      --execute-every <EXECUTE_EVERY>                
      --post-every <POST_EVERY>                      
      --start-block <START_BLOCK>                    
      --end-block <END_BLOCK>                        
      --pk-path <PK_PATH>                            [default: pk.bin]
      --proof-type <PROOF_TYPE>                      [default: compressed]
      --ethproofs-endpoint <ETHPROOFS_ENDPOINT>      
      --ethproofs-token <ETHPROOFS_TOKEN>            
      --ethproofs-cluster-id <ETHPROOFS_CLUSTER_ID>  
  -h, --help  

First Fetch the block

Usage: z6m_prover fetch [OPTIONS]

Options:
      --rpc-url <RPC_URL>            RPC endpoint URL
      --block-number <BLOCK_NUMBER>  Block number to fetch
      --data-dir <DATA_DIR>          Output directory
      --save-all-responses           Whether to save all the json files to disk after download
      --build-eth-test               Whether to create an ethereum/tests format json file too
  -h, --help                         Print help

Dry run execute - just use --block-number for this

Usage: z6m_prover execute [OPTIONS]

Options:
      --block-number <BLOCK_NUMBER>  Block number to execute [default: 0]
      --file-name <FILE_NAME>        Whether the input file is an Ethereum/tests file
      --is-test                      
      --data-dir <DATA_DIR>          Data directory
  -h, --help                         Print help

Fire up the prover

Usage: z6m_prover prove [OPTIONS]
Options:
      --block-number <BLOCK_NUMBER>  JSON file to load ethereum/tests format test from [default: 0]
      --file-name <FILE_NAME>        Whether the input file is an Ethereum/tests file
      --is-test                      
      --data-dir <DATA_DIR>          Data directory
      --pk-path <PK_PATH>            Proving key path [default: pk.bin]
      --proof-path <PROOF_PATH>      Proof output path
      --proof-type <PROOF_TYPE>      Proof type: core, compressed, groth16, plonk [default: compressed]
  -h, --help                         Print help

Test service (offline batch execution)

Execute a range of blocks from disk without RPC or prover key setup:

z6m_prover --test-service \
  --data-dir /path/to/witness_blocks \
  --start-block 24490786 --end-block 24490805 \
  --execute-every 1

Blocks are read from <data-dir>/blocks/<block_number>/unifiedBlockAndStateRlp<block_number>.bin. Missing blocks are skipped with a warning. Results are appended to <data-dir>/executionLogs.log.

Single block execute from disk

z6m_prover execute --file-name /path/to/unifiedBlockAndStateRlp24490786.bin --data-dir /path/to/output

Cycle stats

Install the Python dependencies first:

pip install -r requirements.txt

Plot execution metrics from the log file:

python3 prover/prover_hypercube/src/stats/cycle_stats.py \
  -i /path/to/executionLogs.log \
  -o /path/to/results_plot.png \
  --no-display

NVIDIA CUDA Accelerated proving

First make sure to install NVIDIA drivers and the NVIDIA Container Toolkit https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html

$ user@machine-with-gpu
docker run --gpus all --rm --network host -v "$PWD:/work:rw" -v /var/run/docker.sock:/var/run/docker.sock  -w /work -it --entrypoint bash somnergy/z6m_prover

root@instance-20250919-091229:/work# 
SP1_PROVER=cuda RUST_BACKTRACE=full RUST_LOG=info --prove --n 1 --file-name test.json

Testing

Native build

  1. Download and unpack the latest stable EEST release (tests@<ver>), or just make test-fixtures to fetch the pinned one.
  2. Compiles the C++ EVM natively and runs tests directly with CTest:
    cmake -B build/release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DTESTS_DIR=/path/to/fixtures/blockchain_tests
    cmake --build build/release
  3. Run all tests with CTest:
    ctest --test-dir build/release --parallel
  4. Run specific unified RLP-encoded block file:
    build/release/zilk_core/dev/cli/state_transition temp/blocks/23519000/unifiedBlockAndStateRlp23519000.bin

Acknowledgements

We thank the hard work done by the teams and people behind

  1. Silkworm
  2. EVMOne (especially @chfast)
  3. Succicnt (for SP1 and rsp)
  4. RISCV
  5. C++ Conglomerate
  6. The Rust community

About

A fast, modular, optimized ZKEVM core written in C++

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages