mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-10 16:11:29 +01:00
refactor: bring back compressed snark
and cleanup some group op traits
This commit is contained in:
committed by
Srinath Setty
parent
732d937b09
commit
3ba8fd28aa
@@ -94,8 +94,18 @@ impl<'b, G: Group> MulAssign<&'b G::Scalar> for Commitment<G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, G: Group> Mul<&'b G::Scalar> for &'a Commitment<G> {
|
||||
type Output = Commitment<G>;
|
||||
fn mul(self, scalar: &'b G::Scalar) -> Commitment<G> {
|
||||
Commitment {
|
||||
comm: self.comm * scalar,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> Mul<G::Scalar> for Commitment<G> {
|
||||
type Output = Commitment<G>;
|
||||
|
||||
fn mul(self, scalar: G::Scalar) -> Commitment<G> {
|
||||
Commitment {
|
||||
comm: self.comm * scalar,
|
||||
@@ -119,29 +129,40 @@ impl<'a, 'b, G: Group> Add<&'b Commitment<G>> for &'a Commitment<G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> AddAssign<Commitment<G>> for Commitment<G> {
|
||||
fn add_assign(&mut self, rhs: Commitment<G>) {
|
||||
*self += &rhs;
|
||||
}
|
||||
macro_rules! define_add_variants {
|
||||
(G = $g:path, LHS = $lhs:ty, RHS = $rhs:ty, Output = $out:ty) => {
|
||||
impl<'b, G: $g> Add<&'b $rhs> for $lhs {
|
||||
type Output = $out;
|
||||
fn add(self, rhs: &'b $rhs) -> $out {
|
||||
&self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, G: $g> Add<$rhs> for &'a $lhs {
|
||||
type Output = $out;
|
||||
fn add(self, rhs: $rhs) -> $out {
|
||||
self + &rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: $g> Add<$rhs> for $lhs {
|
||||
type Output = $out;
|
||||
fn add(self, rhs: $rhs) -> $out {
|
||||
&self + &rhs
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<'b, G: Group> Add<&'b Commitment<G>> for Commitment<G> {
|
||||
type Output = Commitment<G>;
|
||||
fn add(self, rhs: &'b Commitment<G>) -> Commitment<G> {
|
||||
&self + rhs
|
||||
}
|
||||
macro_rules! define_add_assign_variants {
|
||||
(G = $g:path, LHS = $lhs:ty, RHS = $rhs:ty) => {
|
||||
impl<G: $g> AddAssign<$rhs> for $lhs {
|
||||
fn add_assign(&mut self, rhs: $rhs) {
|
||||
*self += &rhs;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<'a, G: Group> Add<Commitment<G>> for &'a Commitment<G> {
|
||||
type Output = Commitment<G>;
|
||||
fn add(self, rhs: Commitment<G>) -> Commitment<G> {
|
||||
self + &rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> Add<Commitment<G>> for Commitment<G> {
|
||||
type Output = Commitment<G>;
|
||||
fn add(self, rhs: Commitment<G>) -> Commitment<G> {
|
||||
&self + &rhs
|
||||
}
|
||||
}
|
||||
define_add_assign_variants!(G = Group, LHS = Commitment<G>, RHS = Commitment<G>);
|
||||
define_add_variants!(G = Group, LHS = Commitment<G>, RHS = Commitment<G>, Output = Commitment<G>);
|
||||
|
||||
19
src/lib.rs
19
src/lib.rs
@@ -8,7 +8,9 @@ mod errors;
|
||||
mod r1cs;
|
||||
mod traits;
|
||||
|
||||
use commitments::{AppendToTranscriptTrait, Commitment};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use commitments::{AppendToTranscriptTrait, CompressedCommitment};
|
||||
use errors::NovaError;
|
||||
use merlin::Transcript;
|
||||
use r1cs::{R1CSGens, R1CSInstance, R1CSShape, R1CSWitness};
|
||||
@@ -16,7 +18,8 @@ use traits::{ChallengeTrait, Group};
|
||||
|
||||
/// A SNARK that holds the proof of a step of an incremental computation
|
||||
pub struct StepSNARK<G: Group> {
|
||||
comm_T: Commitment<G>,
|
||||
comm_T: CompressedCommitment<G::CompressedGroupElement>,
|
||||
_p: PhantomData<G>,
|
||||
}
|
||||
|
||||
impl<G: Group> StepSNARK<G> {
|
||||
@@ -52,13 +55,19 @@ impl<G: Group> StepSNARK<G> {
|
||||
let r = G::Scalar::challenge(b"r", transcript);
|
||||
|
||||
// fold the instance using `r` and `comm_T`
|
||||
let U = U1.fold(U2, &comm_T, &r);
|
||||
let U = U1.fold(U2, &comm_T, &r)?;
|
||||
|
||||
// fold the witness using `r` and `T`
|
||||
let W = W1.fold(W2, &T, &r)?;
|
||||
|
||||
// return the folded instance and witness
|
||||
Ok((StepSNARK { comm_T }, (U, W)))
|
||||
Ok((
|
||||
StepSNARK {
|
||||
comm_T,
|
||||
_p: Default::default(),
|
||||
},
|
||||
(U, W),
|
||||
))
|
||||
}
|
||||
|
||||
/// Takes as input two relaxed R1CS instances `U1` and `U2`
|
||||
@@ -82,7 +91,7 @@ impl<G: Group> StepSNARK<G> {
|
||||
let r = G::Scalar::challenge(b"r", transcript);
|
||||
|
||||
// fold the instance using `r` and `comm_T`
|
||||
let U = U1.fold(U2, &self.comm_T, &r);
|
||||
let U = U1.fold(U2, &self.comm_T, &r)?;
|
||||
|
||||
// return the folded instance
|
||||
Ok(U)
|
||||
|
||||
25
src/r1cs.rs
25
src/r1cs.rs
@@ -1,4 +1,6 @@
|
||||
#![allow(clippy::type_complexity)]
|
||||
use crate::commitments::CompressedCommitment;
|
||||
|
||||
use super::commitments::{CommitGens, CommitTrait, Commitment};
|
||||
use super::errors::NovaError;
|
||||
use super::traits::{Group, PrimeField};
|
||||
@@ -182,7 +184,13 @@ impl<G: Group> R1CSShape<G> {
|
||||
W1: &R1CSWitness<G>,
|
||||
U2: &R1CSInstance<G>,
|
||||
W2: &R1CSWitness<G>,
|
||||
) -> Result<(Vec<G::Scalar>, Commitment<G>), NovaError> {
|
||||
) -> Result<
|
||||
(
|
||||
Vec<G::Scalar>,
|
||||
CompressedCommitment<G::CompressedGroupElement>,
|
||||
),
|
||||
NovaError,
|
||||
> {
|
||||
let (AZ_1, BZ_1, CZ_1) = {
|
||||
let Z1 = concat(vec![W1.W.clone(), vec![U1.u], U1.X.clone()]);
|
||||
self.multiply_vec(&Z1)?
|
||||
@@ -214,7 +222,7 @@ impl<G: Group> R1CSShape<G> {
|
||||
.map(|(((a, b), c), d)| *a + *b - *c - *d)
|
||||
.collect::<Vec<G::Scalar>>();
|
||||
|
||||
let comm_T = T.commit(&gens.gens_E);
|
||||
let comm_T = T.commit(&gens.gens_E).compress();
|
||||
|
||||
Ok((T, comm_T))
|
||||
}
|
||||
@@ -291,9 +299,10 @@ impl<G: Group> R1CSInstance<G> {
|
||||
pub fn fold(
|
||||
&self,
|
||||
U2: &R1CSInstance<G>,
|
||||
comm_T: &Commitment<G>,
|
||||
comm_T: &CompressedCommitment<G::CompressedGroupElement>,
|
||||
r: &G::Scalar,
|
||||
) -> R1CSInstance<G> {
|
||||
) -> Result<R1CSInstance<G>, NovaError> {
|
||||
let comm_T_unwrapped = comm_T.decompress()?;
|
||||
let (X1, u1, comm_W_1, comm_E_1) =
|
||||
(&self.X, &self.u, &self.comm_W.clone(), &self.comm_E.clone());
|
||||
let (X2, u2, comm_W_2, comm_E_2) = (&U2.X, &U2.u, &U2.comm_W, &U2.comm_E);
|
||||
@@ -304,15 +313,15 @@ impl<G: Group> R1CSInstance<G> {
|
||||
.zip(X2)
|
||||
.map(|(a, b)| *a + *r * *b)
|
||||
.collect::<Vec<G::Scalar>>();
|
||||
let comm_W = comm_W_1 + *comm_W_2 * *r;
|
||||
let comm_E = *comm_E_1 + *comm_T * *r + *comm_E_2 * *r * *r;
|
||||
let comm_W = comm_W_1 + comm_W_2 * r;
|
||||
let comm_E = *comm_E_1 + comm_T_unwrapped * *r + comm_E_2 * r * *r;
|
||||
let u = *u1 + *r * *u2;
|
||||
|
||||
R1CSInstance {
|
||||
Ok(R1CSInstance {
|
||||
comm_W,
|
||||
comm_E,
|
||||
X,
|
||||
u,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,17 +48,13 @@ pub trait Group:
|
||||
+ Debug
|
||||
+ Eq
|
||||
+ Sized
|
||||
+ Mul<<Self as Group>::Scalar, Output = Self>
|
||||
+ MulAssign<<Self as Group>::Scalar>
|
||||
+ for<'a> MulAssign<&'a <Self as Group>::Scalar>
|
||||
+ for<'a> Mul<&'a <Self as Group>::Scalar, Output = Self>
|
||||
+ Add<Self, Output = Self>
|
||||
+ AddAssign<Self>
|
||||
+ for<'a> AddAssign<&'a Self>
|
||||
+ for<'a> Add<&'a Self, Output = Self>
|
||||
+ GroupOps
|
||||
+ GroupOpsOwned
|
||||
+ ScalarMul<<Self as Group>::Scalar>
|
||||
+ ScalarMulOwned<<Self as Group>::Scalar>
|
||||
{
|
||||
type Scalar: PrimeField + ChallengeTrait;
|
||||
type CompressedGroupElement: CompressedGroup;
|
||||
type CompressedGroupElement: CompressedGroup<GroupElement = Self>;
|
||||
|
||||
fn vartime_multiscalar_mul<I, J>(scalars: I, points: J) -> Self
|
||||
where
|
||||
@@ -86,3 +82,28 @@ pub trait CompressedGroup: Clone + Copy + Debug + Eq + Sized + Send + Sync + 'st
|
||||
pub trait ChallengeTrait {
|
||||
fn challenge(label: &'static [u8], transcript: &mut Transcript) -> Self;
|
||||
}
|
||||
|
||||
/// A helper trait for types with a group operation.
|
||||
pub trait GroupOps<Rhs = Self, Output = Self>:
|
||||
Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, Rhs, Output> GroupOps<Rhs, Output> for T where
|
||||
T: Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
|
||||
{
|
||||
}
|
||||
|
||||
/// A helper trait for references with a group operation.
|
||||
pub trait GroupOpsOwned<Rhs = Self, Output = Self>: for<'r> GroupOps<&'r Rhs, Output> {}
|
||||
impl<T, Rhs, Output> GroupOpsOwned<Rhs, Output> for T where T: for<'r> GroupOps<&'r Rhs, Output> {}
|
||||
|
||||
/// A helper trait for types implementing group scalar multiplication.
|
||||
pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
|
||||
|
||||
impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
|
||||
{}
|
||||
|
||||
/// A helper trait for references implementing group scalar multiplication.
|
||||
pub trait ScalarMulOwned<Rhs, Output = Self>: for<'r> ScalarMul<&'r Rhs, Output> {}
|
||||
impl<T, Rhs, Output> ScalarMulOwned<Rhs, Output> for T where T: for<'r> ScalarMul<&'r Rhs, Output> {}
|
||||
|
||||
Reference in New Issue
Block a user