mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-11 08:31:29 +01:00
move IPA-specific methods to the provider (#138)
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nova-snark"
|
name = "nova-snark"
|
||||||
version = "0.13.0"
|
version = "0.14.0"
|
||||||
authors = ["Srinath Setty <srinath@microsoft.com>"]
|
authors = ["Srinath Setty <srinath@microsoft.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Recursive zkSNARKs without trusted setup"
|
description = "Recursive zkSNARKs without trusted setup"
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ impl<G: Group> fmt::Debug for SatisfyingAssignment<G>
|
|||||||
where
|
where
|
||||||
G::Scalar: PrimeField,
|
G::Scalar: PrimeField,
|
||||||
{
|
{
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt
|
fmt
|
||||||
.debug_struct("SatisfyingAssignment")
|
.debug_struct("SatisfyingAssignment")
|
||||||
.field("a_aux_density", &self.a_aux_density)
|
.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.
|
//! 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(non_snake_case)]
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
#![deny(missing_docs)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
// private modules
|
// private modules
|
||||||
mod bellperson;
|
mod bellperson;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::NovaError,
|
errors::NovaError,
|
||||||
|
provider::pedersen::CommitmentGensExtTrait,
|
||||||
spartan::polynomial::EqPolynomial,
|
spartan::polynomial::EqPolynomial,
|
||||||
traits::{
|
traits::{
|
||||||
commitment::{CommitmentEngineTrait, CommitmentGensTrait, CommitmentTrait},
|
commitment::{CommitmentEngineTrait, CommitmentGensTrait, CommitmentTrait},
|
||||||
@@ -39,7 +40,11 @@ pub struct EvaluationEngine<G: Group> {
|
|||||||
_p: PhantomData<G>,
|
_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 CE = G::CE;
|
||||||
type EvaluationGens = EvaluationGens<G>;
|
type EvaluationGens = EvaluationGens<G>;
|
||||||
type EvaluationArgument = EvaluationArgument<G>;
|
type EvaluationArgument = EvaluationArgument<G>;
|
||||||
@@ -99,7 +104,7 @@ impl<G: Group> EvaluationEngineTrait<G> for EvaluationEngine<G> {
|
|||||||
fn verify_batch(
|
fn verify_batch(
|
||||||
gens: &Self::EvaluationGens,
|
gens: &Self::EvaluationGens,
|
||||||
transcript: &mut Transcript,
|
transcript: &mut Transcript,
|
||||||
comms: &[<Self::CE as CommitmentEngineTrait<G>>::Commitment],
|
comms: &[Commitment<G>],
|
||||||
points: &[Vec<G::Scalar>],
|
points: &[Vec<G::Scalar>],
|
||||||
evals: &[G::Scalar],
|
evals: &[G::Scalar],
|
||||||
arg: &Self::EvaluationArgument,
|
arg: &Self::EvaluationArgument,
|
||||||
@@ -324,7 +329,11 @@ struct InnerProductArgument<G: Group> {
|
|||||||
_p: PhantomData<G>,
|
_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] {
|
fn protocol_name() -> &'static [u8] {
|
||||||
b"inner product argument"
|
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()]),
|
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> {
|
impl<G: Group> CommitmentTrait<G> for Commitment<G> {
|
||||||
@@ -302,3 +216,109 @@ impl<G: Group> CommitmentEngineTrait<G> for CommitmentEngine<G> {
|
|||||||
gens.commit(v)
|
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
|
// 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 {
|
if res_eq && res_comm {
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -301,7 +301,7 @@ impl<G: Group> R1CSShape<G> {
|
|||||||
.map(|(((a, b), c), d)| *a + *b - *c - *d)
|
.map(|(((a, b), c), d)| *a + *b - *c - *d)
|
||||||
.collect::<Vec<G::Scalar>>();
|
.collect::<Vec<G::Scalar>>();
|
||||||
|
|
||||||
let comm_T = gens.gens.commit(&T);
|
let comm_T = CE::<G>::commit(&gens.gens, &T);
|
||||||
|
|
||||||
Ok((T, comm_T))
|
Ok((T, comm_T))
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ impl<G: Group> R1CSWitness<G> {
|
|||||||
|
|
||||||
/// Commits to the witness using the supplied generators
|
/// Commits to the witness using the supplied generators
|
||||||
pub fn commit(&self, gens: &R1CSGens<G>) -> Commitment<G> {
|
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
|
/// Commits to a vector using the commitment key
|
||||||
fn commit(&self, v: &[G::Scalar]) -> Self::Commitment;
|
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
|
/// Defines basic operations on commitments
|
||||||
|
|||||||
Reference in New Issue
Block a user