Documentation Index
Fetch the complete documentation index at: https://mintlify.com/provablehq/snarkvm/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The snark module implements zero-knowledge Succinct Non-interactive Arguments of Knowledge (zkSNARKs). The primary implementation is Varuna, a universal preprocessing zkSNARK that supports batch proving and verification.
Varuna zkSNARK
VarunaSNARK Struct
The main Varuna proof system implementation.
pub struct VarunaSNARK<E: PairingEngine, FS: AlgebraicSponge<E::Fq, 2>, SM: SNARKMode>(
PhantomData<(E, FS, SM)>,
);
The pairing-friendly elliptic curve (typically BLS12-377)
The Fiat-Shamir sponge (typically PoseidonSponge)
The SNARK mode (Recursive or Default)
Type Aliases
type Varuna = VarunaSNARK<Bls12_377, PoseidonSponge<Fq, 2, 1>, DefaultMode>;
type RecursiveVaruna = VarunaSNARK<Bls12_377, PoseidonSponge<Fq, 2, 1>, RecursiveMode>;
SNARK Trait Implementation
Varuna implements the SNARK trait, providing the full proof system interface.
Associated Types
impl<E, FS, SM> SNARK for VarunaSNARK<E, FS, SM> {
type ScalarField = E::Fr;
type BaseField = E::Fq;
type Certificate = Certificate<E>;
type Proof = Proof<E>;
type ProvingKey = CircuitProvingKey<E, SM>;
type VerifyingKey = CircuitVerifyingKey<E>;
type UniversalSRS = UniversalParams<E>;
type UniversalProver = UniversalProver<E>;
type UniversalVerifier = UniversalVerifier<E>;
type VerifierInput = [E::Fr];
type FiatShamirRng = FS;
}
Setup Phase
universal_setup
Generates universal structured reference string (SRS).
pub fn universal_setup(max_degree: usize) -> Result<UniversalSRS<E>>
Maximum polynomial degree supported by the SRS
Universal parameters supporting all circuits up to max_degree
Note: In production, the SRS is loaded from trusted setup parameters, not generated.
Example:
use snarkvm_algorithms::snark::varuna::VarunaSNARK;
use snarkvm_curves::bls12_377::Bls12_377;
type Varuna = VarunaSNARK<Bls12_377, PoseidonSponge<Fq, 2, 1>, DefaultMode>;
// Load SRS (in practice, from trusted setup)
let max_degree = 1 << 20; // Support circuits up to 2^20 constraints
let srs = Varuna::universal_setup(max_degree)?;
circuit_setup
Generates circuit-specific proving and verifying keys.
pub fn circuit_setup<C: ConstraintSynthesizer<E::Fr>>(
srs: &UniversalSRS<E>,
circuit: &C,
) -> Result<(CircuitProvingKey<E, SM>, CircuitVerifyingKey<E>)>
Universal structured reference string
The circuit to generate keys for
return
Result<(CircuitProvingKey, CircuitVerifyingKey)>
Proving key for the prover and verifying key for the verifier
Example:
// Define a circuit
struct MyCircuit { /* ... */ }
impl ConstraintSynthesizer<Fr> for MyCircuit { /* ... */ }
let circuit = MyCircuit::new();
let (proving_key, verifying_key) = Varuna::circuit_setup(&srs, &circuit)?;
batch_circuit_setup
Generates keys for multiple circuits simultaneously.
pub fn batch_circuit_setup<C: ConstraintSynthesizer<E::Fr>>(
universal_srs: &UniversalSRS<E>,
circuits: &[&C],
) -> Result<Vec<(CircuitProvingKey<E, SM>, CircuitVerifyingKey<E>)>>
Slice of circuits to generate keys for
return
Result<Vec<(ProvingKey, VerifyingKey)>>
Vector of proving and verifying key pairs
Proving Phase
prove
Generates a zero-knowledge proof for a single circuit.
pub fn prove<C: ConstraintSynthesizer<E::Fr>, R: Rng + CryptoRng>(
universal_prover: &UniversalProver<E>,
fs_parameters: &FS::Parameters,
proving_key: &CircuitProvingKey<E, SM>,
varuna_version: VarunaVersion,
constraints: &C,
rng: &mut R,
) -> Result<Proof<E>>
Universal prover parameters
Fiat-Shamir sponge parameters
proving_key
&CircuitProvingKey<E, SM>
Circuit-specific proving key
Protocol version (V1 or V2)
The circuit constraints to prove
Cryptographically secure random number generator
Example:
use snarkvm_utilities::rand::TestRng;
let mut rng = TestRng::default();
let universal_prover = srs.to_universal_prover()?;
let fs_params = FS::sample_parameters();
let circuit = MyCircuit { /* ... */ };
let proof = Varuna::prove(
&universal_prover,
&fs_params,
&proving_key,
VarunaVersion::V2,
&circuit,
&mut rng,
)?;
prove_batch
Generates a batch proof for multiple circuit instances.
pub fn prove_batch<C: ConstraintSynthesizer<E::Fr>, R: Rng + CryptoRng>(
universal_prover: &UniversalProver<E>,
fs_parameters: &FS::Parameters,
varuna_version: VarunaVersion,
keys_to_constraints: &BTreeMap<&CircuitProvingKey<E, SM>, &[C]>,
rng: &mut R,
) -> Result<Proof<E>>
keys_to_constraints
&BTreeMap<&ProvingKey, &[C]>
Map from proving keys to constraint instances
Batch proof covering all instances
Example:
use std::collections::BTreeMap;
let mut keys_to_constraints = BTreeMap::new();
keys_to_constraints.insert(&proving_key, &circuits[..]);
let batch_proof = Varuna::prove_batch(
&universal_prover,
&fs_params,
VarunaVersion::V2,
&keys_to_constraints,
&mut rng,
)?;
Verification Phase
verify
Verifies a zero-knowledge proof.
pub fn verify<B: Borrow<[E::Fr]>>(
universal_verifier: &UniversalVerifier<E>,
fs_parameters: &FS::Parameters,
verifying_key: &CircuitVerifyingKey<E>,
varuna_version: VarunaVersion,
input: B,
proof: &Proof<E>,
) -> Result<bool>
Universal verifier parameters
Circuit-specific verifying key
Public input to the circuit
True if the proof is valid, false otherwise
Example:
let universal_verifier = srs.to_universal_verifier()?;
let public_input = vec![Fr::from(42u64)];
let is_valid = Varuna::verify(
&universal_verifier,
&fs_params,
&verifying_key,
VarunaVersion::V2,
&public_input,
&proof,
)?;
assert!(is_valid);
verify_batch
Verifies a batch proof covering multiple instances.
pub fn verify_batch<B: Borrow<[E::Fr]>>(
universal_verifier: &UniversalVerifier<E>,
fs_parameters: &FS::Parameters,
varuna_version: VarunaVersion,
keys_to_inputs: &BTreeMap<&CircuitVerifyingKey<E>, &[B]>,
proof: &Proof<E>,
) -> Result<bool>
keys_to_inputs
&BTreeMap<&VerifyingKey, &[B]>
Map from verifying keys to public inputs
True if the batch proof is valid
Key Structures
CircuitProvingKey
Contains all information needed to generate proofs.
pub struct CircuitProvingKey<E: PairingEngine, SM: SNARKMode> {
pub circuit_commitment: Commitment<E>,
pub circuit: Circuit<E::Fr, SM>,
pub committer_key: CommitterKey<E>,
pub circuit_id: CircuitId,
}
CircuitVerifyingKey
Contains information needed to verify proofs.
pub struct CircuitVerifyingKey<E: PairingEngine> {
pub circuit_commitment: Commitment<E>,
pub circuit_info: CircuitInfo,
pub circuit_id: CircuitId,
}
Proof
The zero-knowledge proof structure.
pub struct Proof<E: PairingEngine> {
pub commitments: Vec<Vec<LabeledCommitment<Commitment<E>>>>,
pub evaluations: Vec<Vec<E::Fr>>,
pub batch_proof: BatchProof<E>,
pub transcript: Vec<u8>,
}
Certificate
Proof that indexing was performed correctly.
pub struct Certificate<E: PairingEngine> {
pub matrix_commitments: Vec<Vec<Commitment<E>>>,
pub w_circ_commitment: Commitment<E>,
}
Algebraic Holographic Proof (AHP)
AHPForR1CS
The AHP compiler that reduces R1CS to polynomial protocols.
pub struct AHPForR1CS<F: PrimeField, SM: SNARKMode> {
// Internal AHP state
}
Key Methods
index
Indexes a circuit for proving.
pub fn index<C: ConstraintSynthesizer<F>>(circuit: &C) -> Result<IndexedCircuit<F, SM>>
prover_rounds
Executes prover rounds of the AHP protocol.
pub fn prover_rounds<C: ConstraintSynthesizer<F>>(
circuit: &IndexedCircuit<F, SM>,
constraints: &C,
fs_rng: &mut FS,
) -> Result<ProverState<F, SM>>
verifier_rounds
Executes verifier rounds of the AHP protocol.
pub fn verifier_rounds(
circuit_info: &CircuitInfo,
public_input: &[F],
fs_rng: &mut FS,
) -> Result<VerifierState<F>>
Protocol Versions
VarunaVersion Enum
pub enum VarunaVersion {
V1,
V2,
}
- V1: Original Varuna protocol
- V2: Optimized version with improved batch verification
SNARKMode Trait
DefaultMode
Standard proving mode.
pub struct DefaultMode;
impl SNARKMode for DefaultMode { /* ... */ }
RecursiveMode
Mode optimized for recursive proof composition.
pub struct RecursiveMode;
impl SNARKMode for RecursiveMode { /* ... */ }
Complete Example
use snarkvm_algorithms::{
crypto_hash::PoseidonSponge,
snark::varuna::{VarunaSNARK, VarunaVersion, DefaultMode},
r1cs::ConstraintSynthesizer,
};
use snarkvm_curves::bls12_377::{Bls12_377, Fq, Fr};
use snarkvm_utilities::rand::TestRng;
type Varuna = VarunaSNARK<Bls12_377, PoseidonSponge<Fq, 2, 1>, DefaultMode>;
type FS = PoseidonSponge<Fq, 2, 1>;
// Define circuit
struct MyCircuit {
a: Option<Fr>,
b: Option<Fr>,
}
impl ConstraintSynthesizer<Fr> for MyCircuit {
fn generate_constraints(&self, cs: &mut impl ConstraintSystem<Fr>) -> Result<()> {
// Add constraints: a * b = c
// ...
Ok(())
}
}
fn main() -> Result<()> {
let mut rng = TestRng::default();
// Setup phase
let max_degree = 1 << 16;
let srs = Varuna::universal_setup(max_degree)?;
let circuit = MyCircuit { a: None, b: None };
let (pk, vk) = Varuna::circuit_setup(&srs, &circuit)?;
// Proving phase
let universal_prover = srs.to_universal_prover()?;
let fs_params = FS::sample_parameters();
let circuit = MyCircuit {
a: Some(Fr::from(3u64)),
b: Some(Fr::from(4u64)),
};
let proof = Varuna::prove(
&universal_prover,
&fs_params,
&pk,
VarunaVersion::V2,
&circuit,
&mut rng,
)?;
// Verification phase
let universal_verifier = srs.to_universal_verifier()?;
let public_input = vec![Fr::from(12u64)]; // c = a * b
let is_valid = Varuna::verify(
&universal_verifier,
&fs_params,
&vk,
VarunaVersion::V2,
&public_input,
&proof,
)?;
assert!(is_valid);
Ok(())
}
- Batch proving amortizes costs across multiple circuit instances
- Parallel prover utilizes all available CPU cores
- Lazy evaluation defers expensive computations until needed
- Memory efficiency uses streaming where possible
See Also