|
@ -1,4 +1,6 @@ |
|
|
#![allow(clippy::type_complexity)]
|
|
|
#![allow(clippy::type_complexity)]
|
|
|
|
|
|
use crate::commitments::CompressedCommitment;
|
|
|
|
|
|
|
|
|
use super::commitments::{CommitGens, CommitTrait, Commitment};
|
|
|
use super::commitments::{CommitGens, CommitTrait, Commitment};
|
|
|
use super::errors::NovaError;
|
|
|
use super::errors::NovaError;
|
|
|
use super::traits::{Group, PrimeField};
|
|
|
use super::traits::{Group, PrimeField};
|
|
@ -182,7 +184,13 @@ impl R1CSShape { |
|
|
W1: &R1CSWitness<G>,
|
|
|
W1: &R1CSWitness<G>,
|
|
|
U2: &R1CSInstance<G>,
|
|
|
U2: &R1CSInstance<G>,
|
|
|
W2: &R1CSWitness<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 (AZ_1, BZ_1, CZ_1) = {
|
|
|
let Z1 = concat(vec![W1.W.clone(), vec![U1.u], U1.X.clone()]);
|
|
|
let Z1 = concat(vec![W1.W.clone(), vec![U1.u], U1.X.clone()]);
|
|
|
self.multiply_vec(&Z1)?
|
|
|
self.multiply_vec(&Z1)?
|
|
@ -214,7 +222,7 @@ impl R1CSShape { |
|
|
.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 = T.commit(&gens.gens_E);
|
|
|
|
|
|
|
|
|
let comm_T = T.commit(&gens.gens_E).compress();
|
|
|
|
|
|
|
|
|
Ok((T, comm_T))
|
|
|
Ok((T, comm_T))
|
|
|
}
|
|
|
}
|
|
@ -291,9 +299,10 @@ impl R1CSInstance { |
|
|
pub fn fold(
|
|
|
pub fn fold(
|
|
|
&self,
|
|
|
&self,
|
|
|
U2: &R1CSInstance<G>,
|
|
|
U2: &R1CSInstance<G>,
|
|
|
comm_T: &Commitment<G>,
|
|
|
|
|
|
|
|
|
comm_T: &CompressedCommitment<G::CompressedGroupElement>,
|
|
|
r: &G::Scalar,
|
|
|
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) =
|
|
|
let (X1, u1, comm_W_1, comm_E_1) =
|
|
|
(&self.X, &self.u, &self.comm_W.clone(), &self.comm_E.clone());
|
|
|
(&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);
|
|
|
let (X2, u2, comm_W_2, comm_E_2) = (&U2.X, &U2.u, &U2.comm_W, &U2.comm_E);
|
|
@ -304,15 +313,15 @@ impl R1CSInstance { |
|
|
.zip(X2)
|
|
|
.zip(X2)
|
|
|
.map(|(a, b)| *a + *r * *b)
|
|
|
.map(|(a, b)| *a + *r * *b)
|
|
|
.collect::<Vec<G::Scalar>>();
|
|
|
.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;
|
|
|
let u = *u1 + *r * *u2;
|
|
|
|
|
|
|
|
|
R1CSInstance {
|
|
|
|
|
|
|
|
|
Ok(R1CSInstance {
|
|
|
comm_W,
|
|
|
comm_W,
|
|
|
comm_E,
|
|
|
comm_E,
|
|
|
X,
|
|
|
X,
|
|
|
u,
|
|
|
u,
|
|
|
}
|
|
|
|
|
|
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|