Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 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