mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-10 16:11:29 +01:00
move IPA-specific methods to the provider (#138)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nova-snark"
|
||||
version = "0.13.0"
|
||||
version = "0.14.0"
|
||||
authors = ["Srinath Setty <srinath@microsoft.com>"]
|
||||
edition = "2021"
|
||||
description = "Recursive zkSNARKs without trusted setup"
|
||||
|
||||
@@ -32,7 +32,7 @@ impl<G: Group> fmt::Debug for SatisfyingAssignment<G>
|
||||
where
|
||||
G::Scalar: PrimeField,
|
||||
{
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt
|
||||
.debug_struct("SatisfyingAssignment")
|
||||
.field("a_aux_density", &self.a_aux_density)
|
||||
|
||||
10
src/lib.rs
10
src/lib.rs
@@ -1,7 +1,15 @@
|
||||
//! This library implements Nova, a high-speed recursive SNARK.
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms,
|
||||
missing_docs
|
||||
)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
#![deny(missing_docs)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
// private modules
|
||||
mod bellperson;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
use crate::{
|
||||
errors::NovaError,
|
||||
provider::pedersen::CommitmentGensExtTrait,
|
||||
spartan::polynomial::EqPolynomial,
|
||||
traits::{
|
||||
commitment::{CommitmentEngineTrait, CommitmentGensTrait, CommitmentTrait},
|
||||
@@ -39,7 +40,11 @@ pub struct EvaluationEngine<G: Group> {
|
||||
_p: PhantomData<G>,
|
||||
}
|
||||
|
||||
impl<G: Group> EvaluationEngineTrait<G> for EvaluationEngine<G> {
|
||||
impl<G> EvaluationEngineTrait<G> for EvaluationEngine<G>
|
||||
where
|
||||
G: Group,
|
||||
CommitmentGens<G>: CommitmentGensExtTrait<G, CE = G::CE>,
|
||||
{
|
||||
type CE = G::CE;
|
||||
type EvaluationGens = EvaluationGens<G>;
|
||||
type EvaluationArgument = EvaluationArgument<G>;
|
||||
@@ -99,7 +104,7 @@ impl<G: Group> EvaluationEngineTrait<G> for EvaluationEngine<G> {
|
||||
fn verify_batch(
|
||||
gens: &Self::EvaluationGens,
|
||||
transcript: &mut Transcript,
|
||||
comms: &[<Self::CE as CommitmentEngineTrait<G>>::Commitment],
|
||||
comms: &[Commitment<G>],
|
||||
points: &[Vec<G::Scalar>],
|
||||
evals: &[G::Scalar],
|
||||
arg: &Self::EvaluationArgument,
|
||||
@@ -324,7 +329,11 @@ struct InnerProductArgument<G: Group> {
|
||||
_p: PhantomData<G>,
|
||||
}
|
||||
|
||||
impl<G: Group> InnerProductArgument<G> {
|
||||
impl<G> InnerProductArgument<G>
|
||||
where
|
||||
G: Group,
|
||||
CommitmentGens<G>: CommitmentGensExtTrait<G, CE = G::CE>,
|
||||
{
|
||||
fn protocol_name() -> &'static [u8] {
|
||||
b"inner product argument"
|
||||
}
|
||||
|
||||
@@ -60,92 +60,6 @@ impl<G: Group> CommitmentGensTrait<G> for CommitmentGens<G> {
|
||||
comm: G::vartime_multiscalar_mul(v, &self.gens[..v.len()]),
|
||||
}
|
||||
}
|
||||
|
||||
fn split_at(&self, n: usize) -> (CommitmentGens<G>, CommitmentGens<G>) {
|
||||
(
|
||||
CommitmentGens {
|
||||
gens: self.gens[0..n].to_vec(),
|
||||
_p: Default::default(),
|
||||
},
|
||||
CommitmentGens {
|
||||
gens: self.gens[n..].to_vec(),
|
||||
_p: Default::default(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn combine(&self, other: &CommitmentGens<G>) -> CommitmentGens<G> {
|
||||
let gens = {
|
||||
let mut c = self.gens.clone();
|
||||
c.extend(other.gens.clone());
|
||||
c
|
||||
};
|
||||
CommitmentGens {
|
||||
gens,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
// combines the left and right halves of `self` using `w1` and `w2` as the weights
|
||||
fn fold(&self, w1: &G::Scalar, w2: &G::Scalar) -> CommitmentGens<G> {
|
||||
let w = vec![*w1, *w2];
|
||||
let (L, R) = self.split_at(self.len() / 2);
|
||||
|
||||
let gens = (0..self.len() / 2)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let gens = CommitmentGens::<G> {
|
||||
gens: [L.gens[i].clone(), R.gens[i].clone()].to_vec(),
|
||||
_p: Default::default(),
|
||||
};
|
||||
gens.commit(&w).comm.preprocessed()
|
||||
})
|
||||
.collect();
|
||||
|
||||
CommitmentGens {
|
||||
gens,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Scales each element in `self` by `r`
|
||||
fn scale(&self, r: &G::Scalar) -> Self {
|
||||
let gens_scaled = self
|
||||
.gens
|
||||
.clone()
|
||||
.into_par_iter()
|
||||
.map(|g| {
|
||||
let gens = CommitmentGens::<G> {
|
||||
gens: vec![g],
|
||||
_p: Default::default(),
|
||||
};
|
||||
gens.commit(&[*r]).comm.preprocessed()
|
||||
})
|
||||
.collect();
|
||||
|
||||
CommitmentGens {
|
||||
gens: gens_scaled,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// reinterprets a vector of commitments as a set of generators
|
||||
fn reinterpret_commitments_as_gens(
|
||||
c: &[CompressedCommitment<G::CompressedGroupElement>],
|
||||
) -> Result<Self, NovaError> {
|
||||
let d = (0..c.len())
|
||||
.into_par_iter()
|
||||
.map(|i| c[i].decompress())
|
||||
.collect::<Result<Vec<Commitment<G>>, NovaError>>()?;
|
||||
let gens = (0..d.len())
|
||||
.into_par_iter()
|
||||
.map(|i| d[i].comm.preprocessed())
|
||||
.collect();
|
||||
Ok(CommitmentGens {
|
||||
gens,
|
||||
_p: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> CommitmentTrait<G> for Commitment<G> {
|
||||
@@ -302,3 +216,109 @@ impl<G: Group> CommitmentEngineTrait<G> for CommitmentEngine<G> {
|
||||
gens.commit(v)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait CommitmentGensExtTrait<G: Group>: CommitmentGensTrait<G> {
|
||||
type CE: CommitmentEngineTrait<G>;
|
||||
|
||||
/// Splits the commitment key into two pieces at a specified point
|
||||
fn split_at(&self, n: usize) -> (Self, Self)
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Combines two commitment keys into one
|
||||
fn combine(&self, other: &Self) -> Self;
|
||||
|
||||
/// Folds the two commitment keys into one using the provided weights
|
||||
fn fold(&self, w1: &G::Scalar, w2: &G::Scalar) -> Self;
|
||||
|
||||
/// Scales the commitment key using the provided scalar
|
||||
fn scale(&self, r: &G::Scalar) -> Self;
|
||||
|
||||
/// Reinterprets commitments as commitment keys
|
||||
fn reinterpret_commitments_as_gens(
|
||||
c: &[<<Self as CommitmentGensExtTrait<G>>::CE as CommitmentEngineTrait<G>>::CompressedCommitment],
|
||||
) -> Result<Self, NovaError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl<G: Group> CommitmentGensExtTrait<G> for CommitmentGens<G> {
|
||||
type CE = CommitmentEngine<G>;
|
||||
|
||||
fn split_at(&self, n: usize) -> (CommitmentGens<G>, CommitmentGens<G>) {
|
||||
(
|
||||
CommitmentGens {
|
||||
gens: self.gens[0..n].to_vec(),
|
||||
_p: Default::default(),
|
||||
},
|
||||
CommitmentGens {
|
||||
gens: self.gens[n..].to_vec(),
|
||||
_p: Default::default(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn combine(&self, other: &CommitmentGens<G>) -> CommitmentGens<G> {
|
||||
let gens = {
|
||||
let mut c = self.gens.clone();
|
||||
c.extend(other.gens.clone());
|
||||
c
|
||||
};
|
||||
CommitmentGens {
|
||||
gens,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
// combines the left and right halves of `self` using `w1` and `w2` as the weights
|
||||
fn fold(&self, w1: &G::Scalar, w2: &G::Scalar) -> CommitmentGens<G> {
|
||||
let w = vec![*w1, *w2];
|
||||
let (L, R) = self.split_at(self.len() / 2);
|
||||
|
||||
let gens = (0..self.len() / 2)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let bases = [L.gens[i].clone(), R.gens[i].clone()].to_vec();
|
||||
G::vartime_multiscalar_mul(&w, &bases).preprocessed()
|
||||
})
|
||||
.collect();
|
||||
|
||||
CommitmentGens {
|
||||
gens,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Scales each element in `self` by `r`
|
||||
fn scale(&self, r: &G::Scalar) -> Self {
|
||||
let gens_scaled = self
|
||||
.gens
|
||||
.clone()
|
||||
.into_par_iter()
|
||||
.map(|g| G::vartime_multiscalar_mul(&[*r], &[g]).preprocessed())
|
||||
.collect();
|
||||
|
||||
CommitmentGens {
|
||||
gens: gens_scaled,
|
||||
_p: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// reinterprets a vector of commitments as a set of generators
|
||||
fn reinterpret_commitments_as_gens(
|
||||
c: &[CompressedCommitment<G::CompressedGroupElement>],
|
||||
) -> Result<Self, NovaError> {
|
||||
let d = (0..c.len())
|
||||
.into_par_iter()
|
||||
.map(|i| c[i].decompress())
|
||||
.collect::<Result<Vec<Commitment<G>>, NovaError>>()?;
|
||||
let gens = (0..d.len())
|
||||
.into_par_iter()
|
||||
.map(|i| d[i].comm.preprocessed())
|
||||
.collect();
|
||||
Ok(CommitmentGens {
|
||||
gens,
|
||||
_p: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ impl<G: Group> R1CSShape<G> {
|
||||
};
|
||||
|
||||
// verify if comm_W is a commitment to W
|
||||
let res_comm: bool = U.comm_W == gens.gens.commit(&W.W);
|
||||
let res_comm: bool = U.comm_W == CE::<G>::commit(&gens.gens, &W.W);
|
||||
|
||||
if res_eq && res_comm {
|
||||
Ok(())
|
||||
@@ -301,7 +301,7 @@ impl<G: Group> R1CSShape<G> {
|
||||
.map(|(((a, b), c), d)| *a + *b - *c - *d)
|
||||
.collect::<Vec<G::Scalar>>();
|
||||
|
||||
let comm_T = gens.gens.commit(&T);
|
||||
let comm_T = CE::<G>::commit(&gens.gens, &T);
|
||||
|
||||
Ok((T, comm_T))
|
||||
}
|
||||
@@ -466,7 +466,7 @@ impl<G: Group> R1CSWitness<G> {
|
||||
|
||||
/// Commits to the witness using the supplied generators
|
||||
pub fn commit(&self, gens: &R1CSGens<G>) -> Commitment<G> {
|
||||
gens.gens.commit(&self.W)
|
||||
CE::<G>::commit(&gens.gens, &self.W)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,25 +29,6 @@ pub trait CommitmentGensTrait<G: Group>:
|
||||
|
||||
/// Commits to a vector using the commitment key
|
||||
fn commit(&self, v: &[G::Scalar]) -> Self::Commitment;
|
||||
|
||||
/// Splits the commitment key into two pieces at a specified point
|
||||
fn split_at(&self, n: usize) -> (Self, Self)
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Combines two commitment keys into one
|
||||
fn combine(&self, other: &Self) -> Self;
|
||||
|
||||
/// Folds the two commitment keys into one using the provided weights
|
||||
fn fold(&self, w1: &G::Scalar, w2: &G::Scalar) -> Self;
|
||||
|
||||
/// Scales the commitment key using the provided scalar
|
||||
fn scale(&self, r: &G::Scalar) -> Self;
|
||||
|
||||
/// Reinterprets commitments as commitment keys
|
||||
fn reinterpret_commitments_as_gens(c: &[Self::CompressedCommitment]) -> Result<Self, NovaError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
/// Defines basic operations on commitments
|
||||
|
||||
Reference in New Issue
Block a user