circom-prover

Crates.iocircom-prover
lib.rscircom-prover
version0.1.2
created_at2025-02-06 13:01:39.698979+00
updated_at2025-06-14 04:38:07.16911+00
descriptionCircom prover is a Rust library for generating and verifying proofs for Circom circuits.
homepagehttps://zkmopro.org/
repositoryhttps://github.com/zkmopro/mopro
max_upload_size
id1545517
size108,295
Ya-wen, Jeng (vivianjeng)

documentation

https://zkmopro.org/

README

Circom Prover

Circom prover is a Rust library for generating and verifying proofs for Circom circuits. It is designed to be used in cross-platform applications, and is compatible with the Mopro library.

It supports multiple adapters, allowing you to choose the one that best optimizes performance.

Adapters

Witness Generation

Proof Generation

Performance

It speeds up circom proof by ~100x comparing to arkworks-rs/circom-compat in keccak256 circuits. We will provide more benchmarks with different adapters in the future. And you can also check the Mopro documentation for more benchmarks. We’ve also published a blog post that outlines the pros and cons of each adapter: Comparison of Circom Provers.

Usage

Install circom-prover

cargo add circom-prover

Depends on the witness generation method, build the rust witness function first. Here is how to use the rust-witness generator.

Include the crate in your Cargo.toml:

[dependencies]
rust-witness = "0.1"

[build-dependencies]
rust-witness = "0.1"

In build.rs, add the following code to compile the witness generator wasm sources (.wasm) into a native library and link to it:

rust_witness::transpile::transpile_wasm("../path to directory containing your wasm sources");
// e.g. rust_witness::transpile::transpile_wasm("./test-vectors".to_string());
// The directory should contain the following files:
// - <circuit name>.wasm

Proof Generation

use std::collections::HashMap;
use circom_prover::{prover::ProofLib, witness::WitnessFn, CircomProver};

// Prepare witness generator
rust_witness::witness!(multiplier2);

// Prepare inputs
let inputs = HashMap::from([
    ("a".to_string(), vec!["1".to_string()]),
    ("b".to_string(), vec!["2".to_string()]),
]);
let input_str = serde_json::to_string(&inputs).unwrap();

// Prepare zkey path
let zkey_path = "./test-vectors/multiplier2_final.zkey".to_string();

// Generate proof
let result = CircomProver::prove(
    ProofLib::Arkworks,
    WitnessFn::RustWitness(multiplier2_witness),
    input_str,
    zkey_path.clone(),
).unwrap();

Proof Verification

// Verify proof
let valid = CircomProver::verify(
    ProofLib::Arkworks,
    result,
    zkey_path,
).unwrap();

Advanced usage

circom-prover also supports witnesscalc, circom-witnesscalc and rapidsnark for advanced users. These tools offer better performance but may not be entirely stable.

Below is a tutorial on how to enable witnesscalc, circom-witnesscalc and rapidsnark.

witnesscalc

Setup features flags

[dependencies]
circom-prover = { version = "0.1", default-features = false, features = ["witnesscalc"] }
witnesscalc-adapter = "0.1"

[build-dependencies]
witnesscalc-adapter = "0.1"

Install dependencies:

  • Linux:
sudo apt install build-essential cmake m4 nasm libstdc++6
  • MacOS
brew install nasm

Rust toolchain: cargo 1.81.0 (2dbb1af80 2024-08-20)

In build.rs, add the following code to compile the witness generator cpp and dat sources (.cpp, .dat) into a native library and link to it:

witnesscalc_adapter::build_and_link("../path to directory containing your C++ sources");
// e.g. witnesscalc_adapter::build_and_link("../testdata");
// The directory should contain the following files:
// - <circuit name>.cpp
// - <circuit name>.dat

Usage

let result = CircomProver::prove(
    ProofLib::Arkworks,
    WitnessFn::WitnessCalc(multiplier2_witness), // the witnesscalc calculator
    input_str,
    zkey_path.clone(),
).unwrap();

circom-witnesscalc

Prepare the graph.

Clone the repo: https://github.com/iden3/circom-witnesscalc, go to the directory circom-witnesscalc, and run:

cargo run --package circom-witnesscalc --bin build-circuit <path_to_circuit.circom> <path_to_circuit_graph.bin> [-l <path_to_circom_libs/>]* [-i <inputs_file.json>]

Setup features flags

[dependencies]
circom-prover = { version = "0.1", default-features = false, features = ["circom-witnesscalc"] }

Install dependencies:

  • Linux:
sudo apt install protobuf-compiler

Usage

// import graph path
const GRAPH_PATH: &str = "./test-vectors/circom/multiplier2.bin";
circom_prover::graph!(multiplier2, &GRAPH_PATH);

let result = CircomProver::prove(
    ProofLib::Arkworks,
    WitnessFn::CircomWitnessCalc(multiplier2_witness), // the circom-witnesscalc calculator
    input_str,
    zkey_path.clone(),
).unwrap();

rapidsnark

[dependencies]
circom-prover = { version = "0.1", default-features = false, features = ["rapidsnark"] }

[build-dependencies]
circom-prover = { version = "0.1", default-features = false, features = ["rapidsnark"] }
use circom_prover::{prover::ProofLib, witness::WitnessFn, CircomProver};
use std::collections::HashMap;
use anyhow::Result;

// Prepare witness generator
witnesscalc_adapter::witness!(multiplier2);

// Prepare inputs
let inputs = HashMap::from([
    ("a".to_string(), vec!["1".to_string()]),
    ("b".to_string(), vec!["2".to_string()]),
]);
let input_str = serde_json::to_string(&inputs).unwrap();

// Prepare zkey path
let zkey_path = "./test-vectors/multiplier2_final.zkey".to_string();

// Generate proof
let result = CircomProver::prove(
    ProofLib::Rapidsnark, // The rapidsnark prover
    WitnessFn::WitnessCalc(multiplier2_witness),
    input_str,
    zkey_path.clone(),
)
.unwrap();

Proof Verification

// Verify proof
let valid = CircomProver::verify(
    ProofLib::Rapidsnark, // the rapidsnark verifier
    result,
    zkey_path,
).unwrap();

Community

Acknowledgements

This work is sponsored by PSE.

Commit count: 696

cargo fmt