Prover
The zkm_sdk crate provides all the necessary tools for proof generation. Key features include the ProverClient
, enabling you to:
- Initialize proving/verifying keys via
setup()
. - Execute your program via
execute()
. - Generate proofs with
prove()
. - Verify proofs through
verify()
.
When generating Groth16 or PLONK proofs, the ProverClient
automatically downloads the pre-generated proving key (pk) from a trusted setup by calling try_install_circuit_artifacts()
.
Example: Fibonacci
The following code is an example of using zkm_sdk in host.
use zkm_sdk::{include_elf, utils, ProverClient, ZKMProofWithPublicValues, ZKMStdin};
/// The ELF we want to execute inside the zkVM.
const ELF: &[u8] = include_elf!("fibonacci");
fn main() {
// Create an input stream and write '1000' to it.
let n = 1000u32;
// The input stream that the guest will read from using `zkm_zkvm::io::read`. Note that the
// types of the elements in the input stream must match the types being read in the program.
let mut stdin = ZKMStdin::new();
stdin.write(&n);
// Create a `ProverClient` method.
let client = ProverClient::new();
// Execute the guest using the `ProverClient.execute` method, without generating a proof.
let (_, report) = client.execute(ELF, stdin.clone()).run().unwrap();
println!("executed program with {} cycles", report.total_instruction_count());
// Generate the proof for the given program and input.
let (pk, vk) = client.setup(ELF);
let mut proof = client.prove(&pk, stdin).run().unwrap();
// Read and verify the output.
//
// Note that this output is read from values committed to in the program using
// `zkm_zkvm::io::commit`.
let n = proof.public_values.read::<u32>();
let a = proof.public_values.read::<u32>();
let b = proof.public_values.read::<u32>();
println!("n: {}", n);
println!("a: {}", a);
println!("b: {}", b);
// Verify proof and public values
client.verify(&proof, &vk).expect("verification failed");
}
Proof Types
zkMIPS provides customizable proof generation options:
Core Proof (Default)
The default prover mode generates a sequence of STARK proofs whose cumulative proof size scales linearly with the execution trace length.
Compressed Proof
The compressed proving mode generates constant-sized STARK proofs, but not suitable for on-chain verification.
Groth16 Proof (Recommended)
The Groth16 proving mode generates succinct SNARK proofs with a compact size of approximately 260 bytes, and features on-chain verification.
PLONK Proof
The PLONK proving mode generates succinct SNARK proofs with a compact size of approximately 868 bytes, while maintaining on-chain verifiability. In contrast to Groth16, PLONK removes the dependency on trusted setup ceremonies.
Hardware Acceleration
zkMIPS provides hardware acceleration support for AVX256/AVX512
on x86 CPUs due to support in Plonky3
.
You can check your CPU's AVX compatibility by running:
grep avx /proc/cpuinfo
Check if you can see avx2
or avx512
in the results.
To activate AVX256 optimization, add these flags to your RUSTFLAGS environment variable:
RUSTFLAGS="-C target-cpu=native" cargo run --release
To activate AVX512 optimization, add these flags to your RUSTFLAGS environment variable:
RUSTFLAGS="-C target-cpu=native -C target-feature=+avx512f" cargo run --release
Network Prover
We support a network prover via the ZKM Proof Network, accessible through our RESTful API.The network prover currently supports only the Groth16 proving mode. >The proving process consists of several stages: queuing, splitting, proving, and finalizing. Each stage may take a different amount of time.
Requirements
- CA certificate:
ca.pem
,ca.key
. These keys are stored here - Register your address to gain access.
- SDK dependency: add
zkm_sdk
from the zkMIPS SDK to yourCargo.toml
:
zkm-sdk = { git = "https://github.com/zkMIPS/zkMIPS", branch = "main" }
Environment Variable Setup
Before running your application, export the following environment variables to enable the network prover:
export ZKM_PRIVATE_KEY=<your_private_key> # Private key corresponding to your registered public key
export CERT_PATH=<path_to_client_certificate> # Path to client certificate
export KEY_PATH=<path_to_client_key> # Path to client key
You can generate the client certificate and key by running the certgen.sh
script.
To host your own network prover, export the following variables to configure your endpoint:
export ENDPOINT=<proof_network_endpoint> # Proof network endpoint (default: https://152.32.186.45:20002)
export CA_CERT_PATH=<path_to_ca_certificate> # Path to CA certificate (default: ca.pem)
export DOMAIN_NAME=<domain_name> # Domain name (default: "stage")
Example
The following example shows how to use the network prover on the host:
use std::env;
use zkm_sdk::{include_elf, ProverClient, ZKMStdin};
const FIBONACCI_ELF: &[u8] = include_elf!("fibonacci");
fn main() {
utils::setup_logger();
let mut stdin = ZKMStdin::new();
stdin.write(&10usize);
let elf = test_artifacts::FIBONACCI_ELF;
// create network client
let client = ProverClient::network();
let (pk, vk) = client.setup(elf);
let proof = client.prove(&pk, stdin).run().unwrap();
client.verify(&proof, &vk).unwrap();
}