Crate rsnark

Crate rsnark 

Source
Expand description

§rSnark

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.

§Writing Circuits

Defining a circuit requires two simple steps:

  1. Define the circuit’s inputs and outputs using the #[circuit] attribute.
  2. Implement the Circuit trait to define the circuit’s constraint rules.
use rsnark::{
    Groth16BN254GnarkProver,
    core::{API, Circuit},
    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);
    }
}

§Circuit Macro

The #[circuit] attribute treats Rust’s visibility modifiers as indicators of whether a field is a public input or private input, automatically generating the corresponding structures.

  • Fields without pub are treated as private inputs
  • Fields with pub are treated as public inputs

The macro also automatically generates a Public Witness structure that can be accessed using the PublicWitness.

§Defining Circuit Constraints

Use the Circuit trait to define the circuit’s constraint rules. The define method receives an API object that provides various operations for building constraints.

use rsnark::core::{API, Circuit};
use rsnark::circuit;

#[circuit]
pub struct MultiplyCircuit {
    x: u32,
    y: u32,
    pub result: u32,
}

impl Circuit for MultiplyCircuit {
    fn define(&self, api: &mut impl API) {
        let product = api.mul(&self.x, &self.y);
        api.assert_is_equal(&product, &self.result);
    }
}

§Nested Circuits

Circuits can be easily nested by embedding other circuits as fields in the struct. Sub-circuits can also implement the Circuit trait, but you must manually call the sub-circuit’s define function within the parent circuit’s define function.

Note: Private has higher priority. This means that if you set a sub-circuit (which contains public fields) as private, the public inputs of that sub-circuit will not be treated as public inputs in the parent circuit. However, if you set a sub-circuit as public, its private inputs will still be treated as private inputs.

use rsnark::core::{API, Circuit};

#[circuit]
pub struct AdderCircuit {
    a: u32,
    b: u32,
    pub sum: u32,
}

impl Circuit for AdderCircuit {
    fn define(&self, api: &mut impl API) {
        let result = api.add(&self.a, &self.b);
        api.assert_is_equal(&result, &self.sum);
    }
}

#[circuit]
pub struct MultiplierCircuit {
    x: u32,
    y: u32,
    pub product: u32,
}

impl Circuit for MultiplierCircuit {
    fn define(&self, api: &mut impl API) {
        let result = api.mul(&self.x, &self.y);
        api.assert_is_equal(&result, &self.product);
    }
}

#[circuit]
pub struct CompositeCircuit {
    adder: AdderCircuit,
    pub multiplier: MultiplierCircuit,
    pub final_result: u32,
}

impl Circuit for CompositeCircuit {
    fn define(&self, api: &mut impl API) {
        // Execute sub-circuits
        self.adder.define(api);
        self.multiplier.define(api);

        // Main circuit logic
        let final_sum = api.add(&self.adder.sum, &self.multiplier.product);
        api.assert_is_equal(&final_sum, &self.final_result);
    }
}

§Backend Triple

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:

Modules§

core
Core library to write circuits.
provers
Prover to generate

Type Aliases§

Groth16BLS12_377GnarkProver
Provers with backend triple groth16-bls12-377-gnark
Groth16BLS12_381GnarkProver
Provers with backend triple groth16-bls12-381-gnark
Groth16BLS24_315GnarkProver
Provers with backend triple groth16-bls24-315-gnark
Groth16BLS24_317GnarkProver
Provers with backend triple groth16-bls24-317-gnark
Groth16BN254GnarkProver
Provers with backend triple groth16-bn254-gnark
Groth16BW6_633GnarkProver
Provers with backend triple groth16-bw6-633-gnark
Groth16BW6_761GnarkProver
Provers with backend triple groth16-bw6-761-gnark
PlonkBLS12_377GnarkProver
Provers with backend triple plonk-bls12-377-gnark
PlonkBLS12_381GnarkProver
Provers with backend triple plonk-bls12-381-gnark
PlonkBLS24_315GnarkProver
Provers with backend triple plonk-bls24-315-gnark
PlonkBLS24_317GnarkProver
Provers with backend triple plonk-bls24-317-gnark
PlonkBN254GnarkProver
Provers with backend triple plonk-bn254-gnark
PlonkBW6_633GnarkProver
Provers with backend triple plonk-bw6-633-gnark
PlonkBW6_761GnarkProver
Provers with backend triple plonk-bw6-761-gnark