Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 45 additions & 36 deletions algorithms/benches/snark/varuna.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,21 @@ use snarkvm_algorithms::{
AlgebraicSponge,
SNARK,
crypto_hash::PoseidonSponge,
snark::varuna::{CircuitVerifyingKey, TestCircuit, VarunaHidingMode, VarunaSNARK, VarunaVersion, ahp::AHPForR1CS},
snark::varuna::{
CircuitVerifyingKey,
TestCircuit,
UniversalProver,
VarunaHidingMode,
VarunaSNARK,
VarunaVersion,
ahp::AHPForR1CS,
},
};
use snarkvm_curves::bls12_377::{Bls12_377, Fq, Fr};
use snarkvm_utilities::{CanonicalDeserialize, CanonicalSerialize, TestRng};

use criterion::Criterion;
use itertools::Itertools;
use std::{collections::BTreeMap, time::Duration};

type VarunaInst = VarunaSNARK<Bls12_377, FS, VarunaHidingMode>;
Expand Down Expand Up @@ -53,7 +62,8 @@ fn snark_circuit_setup(c: &mut Criterion) {
let mul_depth = 1;
let (circuit, _) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);
c.bench_function(&format!("snark_circuit_setup_{size}"), |b| {
b.iter(|| VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap())
let mut universal_prover = UniversalProver::default();
b.iter(|| VarunaInst::circuit_setup(&universal_srs, &mut universal_prover, &circuit).unwrap())
});
}
}
Expand All @@ -67,25 +77,21 @@ fn snark_prove(c: &mut Criterion) {

let max_degree = AHPForR1CS::<Fr, VarunaHidingMode>::max_degree(1000, 1000, 1000).unwrap();
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let universal_prover = &universal_srs.to_universal_prover().unwrap();
let fs_parameters = FS::sample_parameters();

let (circuit, _) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);

let params = VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap();
let mut universal_prover = UniversalProver::default();
let (pk, _) = VarunaInst::circuit_setup(&universal_srs, &mut universal_prover, &circuit).unwrap();

c.bench_function("snark_prove_v1", |b| {
let varuna_version = VarunaVersion::V1;
b.iter(|| {
VarunaInst::prove(universal_prover, &fs_parameters, &params.0, varuna_version, &circuit, rng).unwrap()
})
b.iter(|| VarunaInst::prove(&universal_prover, &fs_parameters, &pk, varuna_version, &circuit, rng).unwrap())
});

c.bench_function("snark_prove_v2", |b| {
let varuna_version = VarunaVersion::V2;
b.iter(|| {
VarunaInst::prove(universal_prover, &fs_parameters, &params.0, varuna_version, &circuit, rng).unwrap()
})
b.iter(|| VarunaInst::prove(&universal_prover, &fs_parameters, &pk, varuna_version, &circuit, rng).unwrap())
});
}

Expand All @@ -99,16 +105,16 @@ fn snark_batch_prove(c: &mut Criterion) {

let max_degree = AHPForR1CS::<Fr, VarunaHidingMode>::max_degree(1000000, 1000000, 1000000).unwrap();
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let universal_prover = &universal_srs.to_universal_prover().unwrap();
let fs_parameters = FS::sample_parameters();

let circuit_batch_size = 5;
let instance_batch_size = 5;

let mut pks = Vec::with_capacity(circuit_batch_size);
let mut all_circuits = Vec::with_capacity(circuit_batch_size);
let mut keys_to_constraints = BTreeMap::new();

let mut universal_prover = UniversalProver::default();

for i in 0..circuit_batch_size {
let num_constraints = num_constraints_base + i;
let num_variables = num_variables_base + i;
Expand All @@ -119,18 +125,20 @@ fn snark_batch_prove(c: &mut Criterion) {
let (circuit, _) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);
circuits.push(circuit);
}
let (pk, _) = VarunaInst::circuit_setup(&universal_srs, &circuits[0]).unwrap();
pks.push(pk);
all_circuits.push(circuits);
}

let unique_circuits = all_circuits.iter().map(|c| &c[0]).collect_vec();
let circuit_keys =
VarunaInst::batch_circuit_setup(&universal_srs, &mut universal_prover, unique_circuits.as_slice()).unwrap();

for i in 0..circuit_batch_size {
keys_to_constraints.insert(&pks[i], all_circuits[i].as_slice());
keys_to_constraints.insert(&circuit_keys[i].0, all_circuits[i].as_slice());
}

let varuna_version = VarunaVersion::V2;
b.iter(|| {
VarunaInst::prove_batch(universal_prover, &fs_parameters, varuna_version, &keys_to_constraints, rng)
VarunaInst::prove_batch(&universal_prover, &fs_parameters, varuna_version, &keys_to_constraints, rng)
.unwrap()
})
});
Expand All @@ -146,16 +154,16 @@ fn snark_verify(c: &mut Criterion) {

let max_degree = AHPForR1CS::<Fr, VarunaHidingMode>::max_degree(100, 100, 100).unwrap();
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let universal_prover = &universal_srs.to_universal_prover().unwrap();
let universal_verifier = &universal_srs.to_universal_verifier().unwrap();
let fs_parameters = FS::sample_parameters();

let (circuit, public_inputs) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);

let (pk, vk) = VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap();
let mut universal_prover = UniversalProver::default();
let (pk, vk) = VarunaInst::circuit_setup(&universal_srs, &mut universal_prover, &circuit).unwrap();

let varuna_version = VarunaVersion::V2;
let proof = VarunaInst::prove(universal_prover, &fs_parameters, &pk, varuna_version, &circuit, rng).unwrap();
let proof = VarunaInst::prove(&universal_prover, &fs_parameters, &pk, varuna_version, &circuit, rng).unwrap();
b.iter(|| {
let verification = VarunaInst::verify(
universal_verifier,
Expand All @@ -180,15 +188,13 @@ fn snark_batch_verify(c: &mut Criterion) {

let max_degree = AHPForR1CS::<Fr, VarunaHidingMode>::max_degree(1000, 1000, 100).unwrap();
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let universal_prover = &universal_srs.to_universal_prover().unwrap();
let universal_verifier = &universal_srs.to_universal_verifier().unwrap();
let mut universal_prover = UniversalProver::default();
let fs_parameters = FS::sample_parameters();

let circuit_batch_size = 5;
let instance_batch_size = 5;

let mut pks = Vec::with_capacity(circuit_batch_size);
let mut vks = Vec::with_capacity(circuit_batch_size);
let mut all_circuits = Vec::with_capacity(circuit_batch_size);
let mut all_inputs = Vec::with_capacity(circuit_batch_size);
let mut keys_to_constraints = BTreeMap::new();
Expand All @@ -204,21 +210,22 @@ fn snark_batch_verify(c: &mut Criterion) {
circuits.push(circuit);
inputs.push(public_inputs);
}
let (pk, vk) = VarunaInst::circuit_setup(&universal_srs, &circuits[0]).unwrap();
pks.push(pk);
vks.push(vk);
all_circuits.push(circuits);
all_inputs.push(inputs);
}

let unique_circuits = all_circuits.iter().map(|c| &c[0]).collect_vec();
let circuit_keys =
VarunaInst::batch_circuit_setup(&universal_srs, &mut universal_prover, unique_circuits.as_slice()).unwrap();

for i in 0..circuit_batch_size {
keys_to_constraints.insert(&pks[i], all_circuits[i].as_slice());
keys_to_inputs.insert(&vks[i], all_inputs[i].as_slice());
keys_to_constraints.insert(&circuit_keys[i].0, all_circuits[i].as_slice());
keys_to_inputs.insert(&circuit_keys[i].1, all_inputs[i].as_slice());
}

let varuna_version = VarunaVersion::V2;
let proof =
VarunaInst::prove_batch(universal_prover, &fs_parameters, varuna_version, &keys_to_constraints, rng)
VarunaInst::prove_batch(&universal_prover, &fs_parameters, varuna_version, &keys_to_constraints, rng)
.unwrap();
b.iter(|| {
let verification =
Expand Down Expand Up @@ -246,7 +253,8 @@ fn snark_vk_serialize(c: &mut Criterion) {
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let (circuit, _) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);

let (_, vk) = VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap();
let mut universal_prover = UniversalProver::default();
let (_, vk) = VarunaInst::circuit_setup(&universal_srs, &mut universal_prover, &circuit).unwrap();
let mut bytes = Vec::with_capacity(10000);
group.bench_function(name, |b| {
b.iter(|| {
Expand Down Expand Up @@ -281,7 +289,8 @@ fn snark_vk_deserialize(c: &mut Criterion) {
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let (circuit, _) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);

let (_, vk) = VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap();
let mut universal_prover = UniversalProver::default();
let (_, vk) = VarunaInst::circuit_setup(&universal_srs, &mut universal_prover, &circuit).unwrap();
let mut bytes = Vec::with_capacity(10000);
vk.serialize_with_mode(&mut bytes, compress).unwrap();
group.bench_function(name, |b| {
Expand All @@ -300,7 +309,6 @@ fn snark_certificate_prove(c: &mut Criterion) {

let max_degree = AHPForR1CS::<Fr, VarunaHidingMode>::max_degree(100000, 100000, 100000).unwrap();
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let universal_prover = &universal_srs.to_universal_prover().unwrap();
let fs_parameters = FS::sample_parameters();
let fs_p = &fs_parameters;

Expand All @@ -309,10 +317,11 @@ fn snark_certificate_prove(c: &mut Criterion) {
let num_variables = size;
let mul_depth = 1;
let (circuit, _) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);
let (pk, vk) = VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap();
let mut universal_prover = UniversalProver::default();
let (pk, vk) = VarunaInst::circuit_setup(&universal_srs, &mut universal_prover, &circuit).unwrap();

c.bench_function(&format!("snark_certificate_prove_{size}"), |b| {
b.iter(|| VarunaInst::prove_vk(universal_prover, fs_p, &vk, &pk).unwrap())
b.iter(|| VarunaInst::prove_vk(&universal_prover, fs_p, &vk, &pk).unwrap())
});
}
}
Expand All @@ -322,7 +331,6 @@ fn snark_certificate_verify(c: &mut Criterion) {

let max_degree = AHPForR1CS::<Fr, VarunaHidingMode>::max_degree(100_000, 100_000, 100_000).unwrap();
let universal_srs = VarunaInst::universal_setup(max_degree).unwrap();
let universal_prover = &universal_srs.to_universal_prover().unwrap();
let universal_verifier = &universal_srs.to_universal_verifier().unwrap();
let fs_parameters = FS::sample_parameters();
let fs_p = &fs_parameters;
Expand All @@ -332,8 +340,9 @@ fn snark_certificate_verify(c: &mut Criterion) {
let num_variables = size;
let mul_depth = 1;
let (circuit, _) = TestCircuit::gen_rand(mul_depth, num_constraints, num_variables, rng);
let (pk, vk) = VarunaInst::circuit_setup(&universal_srs, &circuit).unwrap();
let certificate = VarunaInst::prove_vk(universal_prover, fs_p, &vk, &pk).unwrap();
let mut universal_prover = UniversalProver::default();
let (pk, vk) = VarunaInst::circuit_setup(&universal_srs, &mut universal_prover, &circuit).unwrap();
let certificate = VarunaInst::prove_vk(&universal_prover, fs_p, &vk, &pk).unwrap();

c.bench_function(&format!("snark_certificate_verify_{size}"), |b| {
b.iter(|| VarunaInst::verify_vk(universal_verifier, fs_p, &circuit, &vk, &certificate).unwrap())
Expand Down
3 changes: 3 additions & 0 deletions algorithms/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub enum SNARKError {

#[error("Public input size was different from the circuit")]
PublicInputSizeMismatch,

#[error("FFT precomputation not found")]
FFTPrecompNotFound,
}

impl From<AHPError> for SNARKError {
Expand Down
10 changes: 7 additions & 3 deletions algorithms/src/polycommit/kzg10/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use super::DegreeInfo;
use crate::{
AlgebraicSponge,
fft::{DensePolynomial, EvaluationDomain},
snark::varuna::UniversalProver,
srs::UniversalVerifier,
};
use snarkvm_curves::{AffineCurve, PairingCurve, PairingEngine, ProjectiveCurve};
use snarkvm_fields::{ConstraintFieldError, ToConstraintField, Zero};
Expand All @@ -28,7 +31,6 @@ use snarkvm_utilities::{
serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate},
};

use crate::srs::{UniversalProver, UniversalVerifier};
use anyhow::Result;
use core::ops::{Add, AddAssign};
use rand::RngCore;
Expand Down Expand Up @@ -98,8 +100,10 @@ impl<E: PairingEngine> UniversalParams<E> {
self.powers.max_num_powers() - 1
}

pub fn to_universal_prover(&self) -> Result<UniversalProver<E>> {
Ok(UniversalProver::<E> { max_degree: self.max_degree(), _unused: None })
pub fn to_universal_prover(&self, degree_info: DegreeInfo) -> Result<UniversalProver<E>> {
let mut universal_prover = UniversalProver::default();
universal_prover.update(self, degree_info)?;
Ok(universal_prover)
}

pub fn to_universal_verifier(&self) -> Result<UniversalVerifier<E>> {
Expand Down
62 changes: 62 additions & 0 deletions algorithms/src/polycommit/kzg10/degree_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) 2019-2026 Provable Inc.
// This file is part of the snarkVM library.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::BTreeSet;

#[derive(Clone, Debug, Default)]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[derive(Clone, Debug, Default)]
/// Degree info specifies information needed to determine which powers to use to build the CommitterKey from the SRS.
#[derive(Clone, Debug, Default)]

pub struct DegreeInfo {
/// The maximum degree of the required SRS to commit to the polynomials.
pub max_degree: usize,
/// The maximum IOP poly degree used for (i)fft_precomputation.
pub max_fft_size: usize,
/// The degree bounds on IOP polynomials.
pub degree_bounds: Option<BTreeSet<usize>>,
/// The hiding bound for polynomial queries.
pub hiding_bound: usize,
/// The supported sizes for the lagrange-basis SRS.
pub lagrange_sizes: Option<BTreeSet<usize>>,
}

impl DegreeInfo {
/// Initializes a new degree info.
pub const fn new(
max_degree: usize,
max_fft_size: usize,
degree_bounds: Option<BTreeSet<usize>>,
hiding_bound: usize,
lagrange_sizes: Option<BTreeSet<usize>>,
) -> Self {
Self { max_degree, max_fft_size, degree_bounds, hiding_bound, lagrange_sizes }
}
}

impl DegreeInfo {
pub fn union(self, other: &Self) -> Self {
let max_degree = self.max_degree.max(other.max_degree);
let max_fft_size = self.max_fft_size.max(other.max_fft_size);
let degree_bounds = match (&self.degree_bounds, &other.degree_bounds) {
(Some(a), Some(b)) => Some(a | b),
(Some(a), None) | (None, Some(a)) => Some(a.clone()),
(None, None) => None,
};
let hiding_bound = self.hiding_bound.max(other.hiding_bound);
let lagrange_sizes = match (&self.lagrange_sizes, &other.lagrange_sizes) {
(Some(a), Some(b)) => Some(a | b),
(Some(a), None) | (None, Some(a)) => Some(a.clone()),
(None, None) => None,
};
Self::new(max_degree, max_fft_size, degree_bounds, hiding_bound, lagrange_sizes)
}
}
3 changes: 3 additions & 0 deletions algorithms/src/polycommit/kzg10/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ use rayon::prelude::*;
mod data_structures;
pub use data_structures::*;

mod degree_info;
pub use degree_info::*;

use super::sonic_pc::LabeledPolynomialWithBasis;

#[derive(Debug, PartialEq, Eq)]
Expand Down
Loading