Compile. Execute. Prove. Verify.
One ergonomic Rust API, multiple zero‑knowledge virtual machines.
The current MSRV (minimum supported rust version) is 1.91.
This repository contains the following crates:
ere-compiler-core - Compiler trait and Elf type for compiling guest programsere-prover-core - zkVMProver trait, Input, ProverResource, and CostEstimationere-platform-core - Platform trait for guest programere-verifier-core - zkVMVerifier trait and PublicValuesere-compiler-core (host)
ere-prover-core (host)
ere-platform-core (guest)
ere-verifier-core (lightweight host verifier)
ere-dockerized - Docker wrapper that spawns ere-server containers to run zkVM operations without local SDK installationere-cluster-client-zisk - ZisK distributed-cluster client used by ere-prover-zisk when ProverResource::Cluster is selectedere-codec - Canonical byte codec (Encode/Decode + macros) shared across cratesere-catalog - Catalog of supported zkVMs and compilers (zkVMKind, CompilerKind, SDK versions, Docker image tag)ere-compiler - CLI binary to run Compiler used by ere-dockerizedere-server - Server binary that exposes zkVMProver operations over gRPC (also provides a keygen subcommand)ere-server-api - gRPC wire contract (proto/api.proto and generated prost/twirp types) shared by ere-server and ere-server-clientere-server-client - Client library for ere-server, used by ere-dockerizedere-util-build - Build-time utilities (SDK version + Docker image tag detection)ere-util-compile - Cross-compilation utilities (CargoBuildCmd, RustTarget, toolchain management)ere-util-test - Testing utilities (Program, TestCase, BasicProgram, codec markers)ere-util-tokio - Tokio runtime bridge (block_on) used by sync constructors that call async SDK APIsHost-side traits:
Compiler (from ere-compiler-core)
Compile a guest program into an Elf.
zkVMProver (from ere-prover-core)
Execute, prove and verify. A zkVM prover instance is created for an Elf produced by a Compiler. Elf specific verifying key generation happens in the constructor.
zkVMVerifier (from ere-verifier-core)
zkVM verifier that is created by a succinct ProgramVk for specific Elf produced by zkVMProver. A zkVM verifier instance verifies a Proof and returns PublicValues. Pulled in standalone by verify-only consumers without the prover deps if upstream zkVM SDK provides verifier-only crate.
Guest-side trait (ere-platform-core):
Platform
Provides platform-dependent methods for IO read/write and cycle tracking. It also re-exports the runtime SDK of the zkVM, guaranteed to match the host when ere-prover-{zkvm} and ere-platform-{zkvm} share the same version.
Host and guest communicate through raw bytes. Serialization/deserialization can be done in any way as long as they agree with each other.
The Input structure holds stdin as raw bytes. Set them with Input::new().with_stdin(data), and the guest reads them back via Platform::read_input().
zkVM-specific stdin APIs (e.g., sp1_zkvm::io::read) can also be used directly when finer-grained control is needed.
Public values written in the guest program (via Platform::write_output() or zkVM-specific output APIs) are returned as raw bytes to the host after zkVMProver::execute, zkVMProver::prove and zkVMProver::verify methods.
Different zkVMs handles public values in different approaches:
| zkVM | Size Limit | Note |
|---|---|---|
| OpenVM | 256 bytes | Padded to 256 bytes with zeros |
| SP1 | unlimited | Hashed internally |
| ZisK | 256 bytes |
| zkVM | Version | ISA | GPU | Multi GPU | Cluster |
|---|---|---|---|---|---|
| OpenVM | 2.1.0-preview | RV64IMA | V | ||
| SP1 | 6.6.0 | RV64IMA | V | ||
| ZisK | 1.2.0-alpha | RV64IMA | V | V | V |
Install the required zkVM SDKs locally for better performance and debugging.
Install the SP1 SDK as an example
bash scripts/sdk_installers/install_sp1_sdk.sh
# guest/Cargo.toml
[workspace]
[package]
name = "guest"
edition = "2024"
[dependencies]
ere-platform-sp1 = { git = "https://github.com/eth-act/ere.git" }
// guest/src/main.rs
#![no_main]
use ere_platform_sp1::{sp1_zkvm, Platform, SP1Platform};
sp1_zkvm::entrypoint!(main);
type P = SP1Platform;
pub fn main() {
// Read serialized input and deserialize it.
let input = P::read_input();
let n = u64::from_le_bytes(input.as_slice().try_into().unwrap());
// Compute nth fib.
let fib_n = fib(n);
// Write serialized output.
let output = [input.as_slice(), &fib_n.to_le_bytes()].concat();
P::write_output(&output);
}
fn fib(n: u64) -> u64 {
let mut a = 0;
let mut b = 1;
for _ in 0..n {
let c = a + b;
a = b;
b = c;
}
a
}
# host/Cargo.toml
[workspace]
[package]
name = "host"
edition = "2024"
[dependencies]
ere-prover-core = { git = "https://github.com/eth-act/ere.git" }
ere-prover-sp1 = { git = "https://github.com/eth-act/ere.git" }
// host/src/main.rs
use ere_compiler_core::Compiler;
use ere_compiler_sp1::SP1RustRv64imaCustomized;
use ere_prover_core::{Input, ProverResource, zkVMProver};
use ere_prover_sp1::SP1Prover;
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let guest_directory = Path::new("path/to/guest");
// Compile guest program with SP1 customized toolchain
let compiler = SP1RustRv64imaCustomized;
let elf = compiler.compile(guest_directory, &[])?;
// Create zkVM instance (setup/preprocessing happens here)
let zkvm = SP1Prover::new(elf, ProverResource::Cpu)?;
// Prepare input as raw bytes. The prover handles any framing needed by the SDK.
let stdin = 10u64.to_le_bytes().to_vec();
let input = Input::new().with_stdin(stdin.clone());
let expected_output = [stdin, 55u64.to_le_bytes().to_vec()].concat();
// Execute
let (public_values, execution_duration) = zkvm.execute(&input)?;
assert_eq!(public_values, expected_output);
println!("Execution duration: {execution_duration:?}");
// Prove
let (public_values, proof, proving_time) = zkvm.prove(&input)?;
assert_eq!(public_values, expected_output);
println!("Proving time: {proving_time:?}");
// Verify
let public_values = zkvm.verify(&proof)?;
assert_eq!(public_values, expected_output);
println!("Proof verified successfully!");
Ok(())
}
Use Docker for zkVM operations without installing SDKs locally. Only requires Docker to be installed.
We use the same guest program created above.
# host/Cargo.toml
[workspace]
[package]
name = "host"
edition = "2024"
[dependencies]
ere-prover-core = { git = "https://github.com/eth-act/ere.git" }
ere-dockerized = { git = "https://github.com/eth-act/ere.git" }
// host/src/main.rs
use ere_compiler_core::Compiler;
use ere_dockerized::{
CompilerKind, DockerizedCompiler, DockerizedzkVM, DockerizedzkVMConfig, zkVMKind,
};
use ere_prover_core::{Input, ProverResource, zkVMProver};
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let guest_directory = Path::new("path/to/guest");
// Compile guest program with SP1 customized toolchain (builds Docker images if needed)
let compiler =
DockerizedCompiler::new(zkVMKind::SP1, CompilerKind::RustCustomized, guest_directory)?;
let elf = compiler.compile(guest_directory, &[])?;
// Create zkVM instance (builds Docker images if needed)
// It spawns a container that runs a gRPC server handling zkVM operations
let zkvm = DockerizedzkVM::new(
zkVMKind::SP1,
elf,
ProverResource::Cpu,
DockerizedzkVMConfig::default(),
)?;
// Prepare input as raw bytes. The prover handles any framing needed by the SDK.
let stdin = 10u64.to_le_bytes().to_vec();
let input = Input::new().with_stdin(stdin.clone());
let expected_output = [stdin, 55u64.to_le_bytes().to_vec()].concat();
// Execute
let (public_values, execution_duration) = zkvm.execute(&input)?;
assert_eq!(public_values, expected_output);
println!("Execution duration: {execution_duration:?}");
// Prove
let (public_values, proof, proving_time) = zkvm.prove(&input)?;
assert_eq!(public_values, expected_output);
println!("Proving time: {proving_time:?}");
// Verify
let public_values = zkvm.verify(&proof)?;
assert_eq!(public_values, expected_output);
println!("Proof verified successfully!");
Ok(())
}
| Variable | Description | Default |
|---|---|---|
ERE_IMAGE_REGISTRY | Specifies docker image registry of the images. When specified, it will try to pull image from the registry and possibly skip building. | `` |
ERE_FORCE_REBUILD_DOCKER_IMAGE | Force to rebuild docker images locally even they exist, it also prevents pulling image from registry. | false |
ERE_GPU_DEVICES | Specifies which GPU devices to use when running Docker containers for GPU-enabled zkVMs. The value is passed to Docker's --gpus flag. | all |
ERE_DOCKER_NETWORK | Specifies the Docker network being used (if any) so spawned ere-server-* containers will join that network. | `` |
ERE_ZISK_PROVING_KEY_VOLUME | Volume or absolute host path mounted at the ZisK proving key directory, so the downloaded key persists across containers. | `` |
Example usage:
# Use all GPUs (default)
ere prove ...
# Use specific GPU devices
ERE_GPU_DEVICES="device=0" ere prove ...
# Use multiple specific GPUs
ERE_GPU_DEVICES="device=0,1" ere prove ...
# Can also signal to use any available GPUs
ERE_GPU_DEVICES="4" ere prove ...
ere/
├── crates/ # Rust crates
│ ├── catalog/ # ere-catalog
│ ├── codec/ # ere-codec
│ ├── prover/
│ │ ├── core/ # ere-prover-core
│ │ └── {zkvm}/ # ere-prover-{zkvm}
│ ├── platform/
│ │ ├── core/ # ere-platform-core
│ │ └── {zkvm}/ # ere-platform-{zkvm}
│ ├── verifier/
│ │ ├── core/ # ere-verifier-core
│ │ └── {zkvm}/ # ere-verifier-{zkvm}
│ ├── dockerized/ # ere-dockerized
│ ├── compiler/
│ │ ├── cli/ # ere-compiler
│ │ ├── core/ # ere-compiler-core
│ │ └── {zkvm}/ # ere-compiler-{zkvm}
│ ├── server/
│ │ ├── api/ # ere-server-api
│ │ ├── cli/ # ere-server
│ │ └── client/ # ere-server-client
│ ├── cluster-client/
│ │ └── zisk/ # ere-cluster-client-zisk
│ └── util/
│ ├── build/ # ere-util-build
│ ├── compile/ # ere-util-compile
│ ├── test/ # ere-util-test
│ └── tokio/ # ere-util-tokio
│
├── docker/ # Dockerfile used by ere-dockerized
│ ├── Dockerfile.base # ere-base
│ └── {zkvm}/
│ ├── Dockerfile.base # ere-base-{zkvm}
│ ├── Dockerfile.compiler # ere-compiler-{zkvm}
│ └── Dockerfile.server # ere-server-{zkvm}
│
├── scripts/ # SDK installation scripts per zkVM
└── tests/ # Guest programs per zkVM for integration test
PRs and issues are welcome!
zkVMs evolve quickly; expect breaking changes. Although the API is generic, its primary target is zkEVMs, which may for example, guide the default set of precompiles.
Licensed under either of
at your option.
Rust
90.8%
Assembly
3.5%
Shell
2.5%
Go
2.2%
Linker Script
1.1%
Compile. Execute. Prove. Verify.
One ergonomic Rust API, multiple zero‑knowledge virtual machines.
The current MSRV (minimum supported rust version) is 1.91.
This repository contains the following crates:
ere-compiler-core - Compiler trait and Elf type for compiling guest programsere-prover-core - zkVMProver trait, Input, ProverResource, and CostEstimationere-platform-core - Platform trait for guest programere-verifier-core - zkVMVerifier trait and PublicValuesere-compiler-core (host)
ere-prover-core (host)
ere-platform-core (guest)
ere-verifier-core (lightweight host verifier)
ere-dockerized - Docker wrapper that spawns ere-server containers to run zkVM operations without local SDK installationere-cluster-client-zisk - ZisK distributed-cluster client used by ere-prover-zisk when ProverResource::Cluster is selectedere-codec - Canonical byte codec (Encode/Decode + macros) shared across cratesere-catalog - Catalog of supported zkVMs and compilers (zkVMKind, CompilerKind, SDK versions, Docker image tag)ere-compiler - CLI binary to run Compiler used by ere-dockerizedere-server - Server binary that exposes zkVMProver operations over gRPC (also provides a keygen subcommand)ere-server-api - gRPC wire contract (proto/api.proto and generated prost/twirp types) shared by ere-server and ere-server-clientere-server-client - Client library for ere-server, used by ere-dockerizedere-util-build - Build-time utilities (SDK version + Docker image tag detection)ere-util-compile - Cross-compilation utilities (CargoBuildCmd, RustTarget, toolchain management)ere-util-test - Testing utilities (Program, TestCase, BasicProgram, codec markers)ere-util-tokio - Tokio runtime bridge (block_on) used by sync constructors that call async SDK APIsHost-side traits:
Compiler (from ere-compiler-core)
Compile a guest program into an Elf.
zkVMProver (from ere-prover-core)
Execute, prove and verify. A zkVM prover instance is created for an Elf produced by a Compiler. Elf specific verifying key generation happens in the constructor.
zkVMVerifier (from ere-verifier-core)
zkVM verifier that is created by a succinct ProgramVk for specific Elf produced by zkVMProver. A zkVM verifier instance verifies a Proof and returns PublicValues. Pulled in standalone by verify-only consumers without the prover deps if upstream zkVM SDK provides verifier-only crate.
Guest-side trait (ere-platform-core):
Platform
Provides platform-dependent methods for IO read/write and cycle tracking. It also re-exports the runtime SDK of the zkVM, guaranteed to match the host when ere-prover-{zkvm} and ere-platform-{zkvm} share the same version.
Host and guest communicate through raw bytes. Serialization/deserialization can be done in any way as long as they agree with each other.
The Input structure holds stdin as raw bytes. Set them with Input::new().with_stdin(data), and the guest reads them back via Platform::read_input().
zkVM-specific stdin APIs (e.g., sp1_zkvm::io::read) can also be used directly when finer-grained control is needed.
Public values written in the guest program (via Platform::write_output() or zkVM-specific output APIs) are returned as raw bytes to the host after zkVMProver::execute, zkVMProver::prove and zkVMProver::verify methods.
Different zkVMs handles public values in different approaches:
| zkVM | Size Limit | Note |
|---|---|---|
| OpenVM | 256 bytes | Padded to 256 bytes with zeros |
| SP1 | unlimited | Hashed internally |
| ZisK | 256 bytes |
| zkVM | Version | ISA | GPU | Multi GPU | Cluster |
|---|---|---|---|---|---|
| OpenVM | 2.1.0-preview | RV64IMA | V | ||
| SP1 | 6.6.0 | RV64IMA | V | ||
| ZisK | 1.2.0-alpha | RV64IMA | V | V | V |
Install the required zkVM SDKs locally for better performance and debugging.
Install the SP1 SDK as an example
bash scripts/sdk_installers/install_sp1_sdk.sh
# guest/Cargo.toml
[workspace]
[package]
name = "guest"
edition = "2024"
[dependencies]
ere-platform-sp1 = { git = "https://github.com/eth-act/ere.git" }
// guest/src/main.rs
#![no_main]
use ere_platform_sp1::{sp1_zkvm, Platform, SP1Platform};
sp1_zkvm::entrypoint!(main);
type P = SP1Platform;
pub fn main() {
// Read serialized input and deserialize it.
let input = P::read_input();
let n = u64::from_le_bytes(input.as_slice().try_into().unwrap());
// Compute nth fib.
let fib_n = fib(n);
// Write serialized output.
let output = [input.as_slice(), &fib_n.to_le_bytes()].concat();
P::write_output(&output);
}
fn fib(n: u64) -> u64 {
let mut a = 0;
let mut b = 1;
for _ in 0..n {
let c = a + b;
a = b;
b = c;
}
a
}
# host/Cargo.toml
[workspace]
[package]
name = "host"
edition = "2024"
[dependencies]
ere-prover-core = { git = "https://github.com/eth-act/ere.git" }
ere-prover-sp1 = { git = "https://github.com/eth-act/ere.git" }
// host/src/main.rs
use ere_compiler_core::Compiler;
use ere_compiler_sp1::SP1RustRv64imaCustomized;
use ere_prover_core::{Input, ProverResource, zkVMProver};
use ere_prover_sp1::SP1Prover;
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let guest_directory = Path::new("path/to/guest");
// Compile guest program with SP1 customized toolchain
let compiler = SP1RustRv64imaCustomized;
let elf = compiler.compile(guest_directory, &[])?;
// Create zkVM instance (setup/preprocessing happens here)
let zkvm = SP1Prover::new(elf, ProverResource::Cpu)?;
// Prepare input as raw bytes. The prover handles any framing needed by the SDK.
let stdin = 10u64.to_le_bytes().to_vec();
let input = Input::new().with_stdin(stdin.clone());
let expected_output = [stdin, 55u64.to_le_bytes().to_vec()].concat();
// Execute
let (public_values, execution_duration) = zkvm.execute(&input)?;
assert_eq!(public_values, expected_output);
println!("Execution duration: {execution_duration:?}");
// Prove
let (public_values, proof, proving_time) = zkvm.prove(&input)?;
assert_eq!(public_values, expected_output);
println!("Proving time: {proving_time:?}");
// Verify
let public_values = zkvm.verify(&proof)?;
assert_eq!(public_values, expected_output);
println!("Proof verified successfully!");
Ok(())
}
Use Docker for zkVM operations without installing SDKs locally. Only requires Docker to be installed.
We use the same guest program created above.
# host/Cargo.toml
[workspace]
[package]
name = "host"
edition = "2024"
[dependencies]
ere-prover-core = { git = "https://github.com/eth-act/ere.git" }
ere-dockerized = { git = "https://github.com/eth-act/ere.git" }
// host/src/main.rs
use ere_compiler_core::Compiler;
use ere_dockerized::{
CompilerKind, DockerizedCompiler, DockerizedzkVM, DockerizedzkVMConfig, zkVMKind,
};
use ere_prover_core::{Input, ProverResource, zkVMProver};
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let guest_directory = Path::new("path/to/guest");
// Compile guest program with SP1 customized toolchain (builds Docker images if needed)
let compiler =
DockerizedCompiler::new(zkVMKind::SP1, CompilerKind::RustCustomized, guest_directory)?;
let elf = compiler.compile(guest_directory, &[])?;
// Create zkVM instance (builds Docker images if needed)
// It spawns a container that runs a gRPC server handling zkVM operations
let zkvm = DockerizedzkVM::new(
zkVMKind::SP1,
elf,
ProverResource::Cpu,
DockerizedzkVMConfig::default(),
)?;
// Prepare input as raw bytes. The prover handles any framing needed by the SDK.
let stdin = 10u64.to_le_bytes().to_vec();
let input = Input::new().with_stdin(stdin.clone());
let expected_output = [stdin, 55u64.to_le_bytes().to_vec()].concat();
// Execute
let (public_values, execution_duration) = zkvm.execute(&input)?;
assert_eq!(public_values, expected_output);
println!("Execution duration: {execution_duration:?}");
// Prove
let (public_values, proof, proving_time) = zkvm.prove(&input)?;
assert_eq!(public_values, expected_output);
println!("Proving time: {proving_time:?}");
// Verify
let public_values = zkvm.verify(&proof)?;
assert_eq!(public_values, expected_output);
println!("Proof verified successfully!");
Ok(())
}
| Variable | Description | Default |
|---|---|---|
ERE_IMAGE_REGISTRY | Specifies docker image registry of the images. When specified, it will try to pull image from the registry and possibly skip building. | `` |
ERE_FORCE_REBUILD_DOCKER_IMAGE | Force to rebuild docker images locally even they exist, it also prevents pulling image from registry. | false |
ERE_GPU_DEVICES | Specifies which GPU devices to use when running Docker containers for GPU-enabled zkVMs. The value is passed to Docker's --gpus flag. | all |
ERE_DOCKER_NETWORK | Specifies the Docker network being used (if any) so spawned ere-server-* containers will join that network. | `` |
ERE_ZISK_PROVING_KEY_VOLUME | Volume or absolute host path mounted at the ZisK proving key directory, so the downloaded key persists across containers. | `` |
Example usage:
# Use all GPUs (default)
ere prove ...
# Use specific GPU devices
ERE_GPU_DEVICES="device=0" ere prove ...
# Use multiple specific GPUs
ERE_GPU_DEVICES="device=0,1" ere prove ...
# Can also signal to use any available GPUs
ERE_GPU_DEVICES="4" ere prove ...
ere/
├── crates/ # Rust crates
│ ├── catalog/ # ere-catalog
│ ├── codec/ # ere-codec
│ ├── prover/
│ │ ├── core/ # ere-prover-core
│ │ └── {zkvm}/ # ere-prover-{zkvm}
│ ├── platform/
│ │ ├── core/ # ere-platform-core
│ │ └── {zkvm}/ # ere-platform-{zkvm}
│ ├── verifier/
│ │ ├── core/ # ere-verifier-core
│ │ └── {zkvm}/ # ere-verifier-{zkvm}
│ ├── dockerized/ # ere-dockerized
│ ├── compiler/
│ │ ├── cli/ # ere-compiler
│ │ ├── core/ # ere-compiler-core
│ │ └── {zkvm}/ # ere-compiler-{zkvm}
│ ├── server/
│ │ ├── api/ # ere-server-api
│ │ ├── cli/ # ere-server
│ │ └── client/ # ere-server-client
│ ├── cluster-client/
│ │ └── zisk/ # ere-cluster-client-zisk
│ └── util/
│ ├── build/ # ere-util-build
│ ├── compile/ # ere-util-compile
│ ├── test/ # ere-util-test
│ └── tokio/ # ere-util-tokio
│
├── docker/ # Dockerfile used by ere-dockerized
│ ├── Dockerfile.base # ere-base
│ └── {zkvm}/
│ ├── Dockerfile.base # ere-base-{zkvm}
│ ├── Dockerfile.compiler # ere-compiler-{zkvm}
│ └── Dockerfile.server # ere-server-{zkvm}
│
├── scripts/ # SDK installation scripts per zkVM
└── tests/ # Guest programs per zkVM for integration test
PRs and issues are welcome!
zkVMs evolve quickly; expect breaking changes. Although the API is generic, its primary target is zkEVMs, which may for example, guide the default set of precompiles.
Licensed under either of
at your option.
Rust
90.8%
Assembly
3.5%
Shell
2.5%
Go
2.2%
Linker Script
1.1%