Crates.io | rsnark-provers-gnark |
lib.rs | rsnark-provers-gnark |
version | 0.1.8 |
created_at | 2025-09-11 19:38:30.872942+00 |
updated_at | 2025-09-18 16:30:05.181696+00 |
description | A Rust library to write Zero-Knowledge circuits for multiple prover systems |
homepage | |
repository | https://github.com/tiannian/rsnark |
max_upload_size | |
id | 1834432 |
size | 229,470 |
Write zero-knowledge circuits in Rust for multiple prover systems.
rSnark is a Rust library for writing zero-knowledge circuits and generating proofs. It provides a core library to write circuits and a provers library to generate proofs using various backend implementations like Gnark.
Add rSnark to your Cargo.toml
:
[dependencies]
rsnark = "0.1"
or use cargo add
:
cargo add rsnark
Defining a circuit requires two simple steps:
#[circuit]
attributeCircuit
trait to define the circuit's constraint rulesUse the following way to define circuit:
use rsnark::{
Groth16BN254GnarkProver,
core::{API, Circuit, CircuitWitness},
circuit,
};
#[circuit]
pub struct TestCircuit {
a: u32, // private input
b: u32, // private input
pub c: u32, // public input
}
impl Circuit for TestCircuit {
fn define(&self, api: &mut impl API) {
let c = api.add(&self.a, &self.b);
api.assert_is_equal(&c, &self.c);
}
}
Use these code to generate proof:
use rsnark_core::Witness;
let prover = Groth16BN254GnarkProver::new();
let circuit_prover = prover.compile_circuit::<TestCircuit>().unwrap();
let (pk, vk) = circuit_prover.setup().unwrap();
let circuit_witness = Witness::<TestCircuit> {
a: 3,
b: 4,
c: 7, // 3 + 4 = 7
};
let proof = circuit_prover.prove(&pk, &circuit_witness).unwrap();
let public_witness = circuit_witness.into_public_witness();
circuit_prover.verify(&vk, &proof, public_witness).unwrap();
The #[circuit]
attribute treats Rust's visibility modifiers as indicators:
pub
are treated as private inputspub
are treated as public inputsNote: Private inputs has higher priority, This will effect with subcircuit struction.
rSnark now supports generic circuits, allowing you to write reusable circuit logic that works with different types:
use rsnark::{
core::{API, Circuit, CircuitElement, CircuitWitness},
circuit,
};
#[circuit]
pub struct GenericAddCircuit<T> {
a: T,
b: T,
pub c: T,
}
impl<T> Circuit for GenericAddCircuit<T>
where
T: CircuitElement,
T::CircuitWitness: CircuitWitness<CircuitElement = CircuitVariable<T>>,
{
fn define(&self, api: &mut impl API) {
let c = api.add(&self.a, &self.b);
api.assert_is_equal(&c, &self.c);
}
}
// Use with different types
fn example() {
let prover = Groth16BN254GnarkProver::new();
// Use with u32
let circuit_prover = prover.compile_circuit::<GenericAddCircuit<u32>>().unwrap();
// Use with u64
let circuit_prover = prover.compile_circuit::<GenericAddCircuit<u64>>().unwrap();
}
This allows you to write circuit logic once and use it with different numeric types.
rSnark supports BigInt constant values directly in circuit operations. You can use literal values as constants:
impl Circuit for MyCircuit {
fn define(&self, api: &mut impl API) {
// Use literal constants directly
let result = api.add(&self.input, &42);
let scaled = api.mul(&result, &1000);
api.assert_is_equal(&scaled, &self.expected);
}
}
All primitive integer types and bool can filled in generic paramters.
// Export solidity contract from verifying key.
let solidity_contract = vk.export_solidity().unwrap();
// Export solidity proof.
let solidity_proof = proof.to_solidity().unwrap();
We will support these following platform:
Similar to compiler target triples, rSnark uses backend triples to define which backend, curve, and proving system to use. The format is: {proving_system}-{curve}-{backend}
.
Currently supported backend triples:
Triple | Description |
---|---|
groth16-bn254-gnark |
Groth16 with BN254 curve using Gnark backend |
groth16-bls12_381-gnark |
Groth16 with BLS12-381 curve using Gnark backend |
groth16-bls12_377-gnark |
Groth16 with BLS12-377 curve using Gnark backend |
groth16-bls24_317-gnark |
Groth16 with BLS24-317 curve using Gnark backend |
groth16-bls24_315-gnark |
Groth16 with BLS24-315 curve using Gnark backend |
groth16-bw6_761-gnark |
Groth16 with BW6-761 curve using Gnark backend |
groth16-bw6_633-gnark |
Groth16 with BW6-633 curve using Gnark backend |
plonk-bn254-gnark |
PLONK with BN254 curve using Gnark backend |
plonk-bls12_381-gnark |
PLONK with BLS12-381 curve using Gnark backend |
plonk-bls12_377-gnark |
PLONK with BLS12-377 curve using Gnark backend |
plonk-bls24_317-gnark |
PLONK with BLS24-317 curve using Gnark backend |
plonk-bls24_315-gnark |
PLONK with BLS24-315 curve using Gnark backend |
plonk-bw6_761-gnark |
PLONK with BW6-761 curve using Gnark backend |
plonk-bw6_633-gnark |
PLONK with BW6-633 curve using Gnark backend |
This workspace contains several crates:
rsnark
- Main library and unified APIrsnark-core
- Core circuit definition and API traitsrsnark-macros
- Derive macros for circuit definitionrsnark-provers-core
- Common prover traits and interfacesrsnark-provers-gnark
- Gnark backend implementationrsnark-provers-mock
- Mock prover for testingCheck out the examples/
directory for more detailed examples of how to use rSnark.
This project is licensed under the MIT License - see the LICENSE file for details.
I'm working on more feature, refer to TODO
Contributions are welcome! Please feel free to submit a Pull Request.