start eliminating excessive commitments
This commit is contained in:
parent
d4dd7d27fa
commit
eaaff874fc
@ -22,11 +22,11 @@ pub struct GrandProductArgument<E: Engine> {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GrandProductProof<E: Engine> {
|
||||
t_opening: E::G1Affine,
|
||||
e_zinv: E::Fr,
|
||||
e_opening: E::G1Affine,
|
||||
f_y: E::Fr,
|
||||
f_opening: E::G1Affine,
|
||||
pub t_opening: E::G1Affine,
|
||||
pub e_zinv: E::Fr,
|
||||
pub e_opening: E::G1Affine,
|
||||
pub f_y: E::Fr,
|
||||
pub f_opening: E::G1Affine,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -43,6 +43,7 @@ pub struct GrandProductSignature<E: Engine> {
|
||||
|
||||
impl<E: Engine> GrandProductArgument<E> {
|
||||
pub fn create_signature(
|
||||
transcript: &mut Transcript,
|
||||
grand_products: Vec<(Vec<E::Fr>, Vec<E::Fr>)>,
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
@ -51,27 +52,27 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
let mut a_commitments = vec![];
|
||||
let mut b_commitments = vec![];
|
||||
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
let mut grand_product_challenges = vec![];
|
||||
|
||||
// TODO: Remove
|
||||
for (a, b) in grand_products.iter() {
|
||||
let (c_a, c_b) = GrandProductArgument::commit_for_individual_products(& a[..], & b[..], &srs);
|
||||
{
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
transcript.commit_point(&c_a);
|
||||
let challenge = transcript.get_challenge_scalar();
|
||||
grand_product_challenges.push(challenge);
|
||||
transcript.commit_point(&c_b);
|
||||
let challenge = transcript.get_challenge_scalar();
|
||||
grand_product_challenges.push(challenge);
|
||||
}
|
||||
a_commitments.push(c_a);
|
||||
b_commitments.push(c_b);
|
||||
transcript.commit_point(&c_a);
|
||||
transcript.commit_point(&c_b);
|
||||
}
|
||||
|
||||
for _ in 0..grand_products.len() {
|
||||
let c = transcript.get_challenge_scalar();
|
||||
grand_product_challenges.push(c);
|
||||
}
|
||||
|
||||
let mut all_polys = vec![];
|
||||
let mut wellformed_challenges = vec![];
|
||||
for c in 0..(grand_products.len()*2) {
|
||||
let c = transcript.get_challenge_scalar();
|
||||
wellformed_challenges.push(c);
|
||||
}
|
||||
|
||||
for p in grand_products.iter() {
|
||||
let (a, b) = p;
|
||||
all_polys.push(a.clone());
|
||||
@ -80,9 +81,22 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
|
||||
let wellformedness_signature = WellformednessArgument::create_signature(
|
||||
all_polys,
|
||||
wellformed_challenges,
|
||||
&srs
|
||||
);
|
||||
|
||||
// sanity check
|
||||
for (j, (a, b)) in a_commitments.iter()
|
||||
.zip(b_commitments.iter())
|
||||
.enumerate()
|
||||
{
|
||||
let a_corr = wellformedness_signature.commitments[2*j];
|
||||
let b_corr = wellformedness_signature.commitments[2*j + 1];
|
||||
|
||||
assert!(a_corr == *a);
|
||||
assert!(b_corr == *b);
|
||||
}
|
||||
|
||||
|
||||
let mut grand_product_argument = GrandProductArgument::new(grand_products);
|
||||
let c_commitments = grand_product_argument.commit_to_individual_c_polynomials(&srs);
|
||||
@ -121,7 +135,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
// c_3 = a_3 * c_2 = a_3 * a_2 * a_1
|
||||
// ...
|
||||
// c_n = a_n * c_{n-1} = \prod a_i
|
||||
// a_{n+1} = c_{n-1}^-1
|
||||
// a_{n+1} = c_{n}^-1
|
||||
// c_{n+1} = 1
|
||||
// c_{n+1} = a_{n+2} * c_{n+1} = a_{n+2}
|
||||
// ...
|
||||
@ -144,8 +158,14 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
}
|
||||
assert_eq!(c_poly.len(), n);
|
||||
a_poly.extend(p0);
|
||||
assert_eq!(a_poly.len(), n);
|
||||
// v = a_{n+1} = c_{n}^-1
|
||||
let v = c_poly[n-1].inverse().unwrap();
|
||||
// let v = c_poly[n-1].inverse().unwrap();
|
||||
let v = c_coeff.inverse().unwrap();
|
||||
// ! IMPORTANT
|
||||
// This line is indeed assigning a_{n+1} to zero instead of v
|
||||
// for the practical purpose later we manually evaluate T polynomial
|
||||
// and assign v to the term X^{n+1}
|
||||
a_poly.push(E::Fr::zero());
|
||||
// a_poly.push(v);
|
||||
// add c_{n+1}
|
||||
@ -160,6 +180,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
a_poly.extend(p1);
|
||||
|
||||
assert_eq!(c_poly[n-1], c_poly[2*n]);
|
||||
assert_eq!(c_poly[n], E::Fr::one());
|
||||
|
||||
a_polynomials.push(a_poly);
|
||||
c_polynomials.push(c_poly);
|
||||
@ -280,7 +301,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
.zip(challenges.iter())
|
||||
{
|
||||
let mut a_xy = a.clone();
|
||||
let mut c_xy = c.clone();
|
||||
let c_xy = c.clone();
|
||||
let v = *v;
|
||||
|
||||
assert_eq!(a_xy.len(), 2*n + 1);
|
||||
@ -356,7 +377,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
|
||||
val.add_assign(&E::Fr::one());
|
||||
|
||||
// subtract at constant term
|
||||
// subtract a constant term
|
||||
assert_eq!(t[2*n+1], val);
|
||||
|
||||
t[2*n+1].sub_assign(&val);
|
||||
|
@ -25,6 +25,7 @@ pub struct SpecializedSRS<E: Engine> {
|
||||
#[derive(Clone)]
|
||||
pub struct PermutationArgument<E: Engine> {
|
||||
non_permuted_coefficients: Vec<Vec<E::Fr>>,
|
||||
non_permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
||||
permuted_coefficients: Vec<Vec<E::Fr>>,
|
||||
permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
||||
permutations: Vec<Vec<usize>>,
|
||||
@ -96,6 +97,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
PermutationArgument {
|
||||
non_permuted_coefficients: coefficients,
|
||||
non_permuted_at_y_coefficients: vec![vec![]],
|
||||
permuted_coefficients: vec![vec![]],
|
||||
permuted_at_y_coefficients: vec![vec![]],
|
||||
permutations: permutations,
|
||||
@ -166,6 +168,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
let n = self.non_permuted_coefficients[0].len();
|
||||
|
||||
let mut non_permuted_at_y_coefficients = vec![];
|
||||
let mut permuted_coefficients = vec![];
|
||||
let mut permuted_at_y_coefficients = vec![];
|
||||
|
||||
@ -206,7 +209,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
mut_distribute_consequitive_powers(&mut non_permuted_at_y[..], y, y);
|
||||
// and commit to S'
|
||||
let s_prime = multiexp(srs.g_positive_x_alpha[0..n].iter(), non_permuted_at_y.iter()).into_affine();
|
||||
drop(non_permuted_at_y);
|
||||
|
||||
// this construction has already moved coeff[i] to the corresponding constraint k, so term is coeff[i]*Y^{K} for place K
|
||||
mut_distribute_consequitive_powers(&mut permuted_at_y[..], y, y);
|
||||
@ -219,10 +221,12 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
result.push((s, s_prime));
|
||||
|
||||
non_permuted_at_y_coefficients.push(non_permuted_at_y);
|
||||
permuted_coefficients.push(permuted);
|
||||
permuted_at_y_coefficients.push(permuted_at_y);
|
||||
}
|
||||
|
||||
self.non_permuted_at_y_coefficients = non_permuted_at_y_coefficients;
|
||||
self.permuted_coefficients = permuted_coefficients;
|
||||
self.permuted_at_y_coefficients = permuted_at_y_coefficients;
|
||||
|
||||
@ -573,7 +577,8 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
permutations: Vec<Vec<usize>>,
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>
|
||||
srs: &SRS<E>,
|
||||
specialized_srs: &SpecializedSRS<E>,
|
||||
) -> SignatureOfCorrectComputation<E> {
|
||||
let mut argument = PermutationArgument::new(coefficients, permutations);
|
||||
let commitments = argument.commit(y, &srs);
|
||||
@ -597,24 +602,46 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
}
|
||||
|
||||
let z_prime = transcript.get_challenge_scalar();
|
||||
// TODO: create better way to get few distinct challenges from the transcript
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
transcript.commit_scalar(&z_prime);
|
||||
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
transcript.commit_scalar(&beta);
|
||||
let gamma: E::Fr = transcript.get_challenge_scalar();
|
||||
|
||||
let s_prime_commitments_opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs);
|
||||
|
||||
let (proof, grand_product_signature) = {
|
||||
// TODO: create better way to get few distinct challenges from the transcript
|
||||
|
||||
let (proof, grand_product_signature) = argument.make_argument_with_transcript(
|
||||
beta,
|
||||
gamma,
|
||||
&mut transcript,
|
||||
y,
|
||||
z,
|
||||
&srs
|
||||
);
|
||||
|
||||
(proof, grand_product_signature)
|
||||
};
|
||||
|
||||
// TODO: sanity check for now,
|
||||
// later eliminate a and b commitments
|
||||
// for (j, (((a, b), s), s_prime)) in grand_product_signature.a_commitments.iter()
|
||||
// .zip(grand_product_signature.b_commitments.iter())
|
||||
// .zip(s_commitments.iter())
|
||||
// .zip(s_prime_commitments.iter())
|
||||
// .enumerate()
|
||||
// {
|
||||
// // Sj(P4j)β(P1j)γ
|
||||
// let mut lhs = s.into_projective();
|
||||
// lhs.add_assign(&specialized_srs.p_4[j].mul(beta.into_repr()));
|
||||
// lhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
||||
|
||||
// assert!(lhs.into_affine() == *a);
|
||||
|
||||
// // Sj′(P3j)β(P1j)γ
|
||||
|
||||
// let mut rhs = s_prime.into_projective();
|
||||
// rhs.add_assign(&specialized_srs.p_3.mul(beta.into_repr()));
|
||||
// rhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
||||
|
||||
// assert!(rhs.into_affine() == *b);
|
||||
// }
|
||||
|
||||
SignatureOfCorrectComputation {
|
||||
s_commitments,
|
||||
s_prime_commitments,
|
||||
@ -627,12 +654,14 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
// Argument a permutation argument. Current implementation consumes, cause extra arguments are required
|
||||
pub fn make_argument_with_transcript(self,
|
||||
beta: E::Fr,
|
||||
gamma: E::Fr,
|
||||
transcript: &mut Transcript,
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>
|
||||
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>) {
|
||||
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||
let gamma: E::Fr = transcript.get_challenge_scalar();
|
||||
|
||||
// Sj(P4j)β(P1j)γ is equal to the product of the coefficients of Sj′(P3j)β(P1j)γ
|
||||
// also open s = \sum self.permuted_coefficients(X, y) at z
|
||||
|
||||
@ -679,13 +708,22 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
let mut grand_products = vec![];
|
||||
|
||||
for (i, ((non_permuted, permuted), permutation)) in self.non_permuted_coefficients.into_iter()
|
||||
// TODO: Check the validity!
|
||||
|
||||
for ((non_permuted, permuted), permutation) in self.non_permuted_coefficients.into_iter()
|
||||
.zip(self.permuted_coefficients.into_iter())
|
||||
.zip(self.permutations.into_iter()).enumerate()
|
||||
.zip(self.permutations.into_iter())
|
||||
|
||||
// for ((non_permuted, permuted), permutation) in self.non_permuted_at_y_coefficients.into_iter()
|
||||
// .zip(self.permuted_at_y_coefficients.into_iter())
|
||||
// .zip(self.permutations.into_iter())
|
||||
|
||||
{
|
||||
// \prod si+βσi+γ = \prod s'i + β*i + γ
|
||||
|
||||
// s combination is coeff[sigma(i)]*Y^{sigma(i)} + beta*sigma(i) + gamma
|
||||
let mut s_j_combination = non_permuted;
|
||||
// let mut s_j_combination = permuted;
|
||||
{
|
||||
let p_4_values: Vec<E::Fr> = permutation.into_iter().map(|el| {
|
||||
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
||||
@ -699,15 +737,35 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
}
|
||||
|
||||
let mut s_prime_j_combination = permuted;
|
||||
// let mut s_prime_j_combination = non_permuted;
|
||||
// s' combination is coeff[i]*Y^{i} + beta*i + gamma
|
||||
|
||||
{
|
||||
mul_add_polynomials(&mut s_prime_j_combination[..], & p_3_values[..], beta);
|
||||
mul_add_polynomials(&mut s_prime_j_combination[..], & p_1_values[..], gamma);
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
let product = s_j_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
||||
{
|
||||
sum.mul_assign(&x);
|
||||
|
||||
sum
|
||||
});
|
||||
let product_prime = s_prime_j_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
||||
{
|
||||
sum.mul_assign(&x);
|
||||
|
||||
sum
|
||||
});
|
||||
|
||||
assert_eq!(product, product_prime);
|
||||
|
||||
grand_products.push((s_j_combination, s_prime_j_combination));
|
||||
}
|
||||
|
||||
let grand_product_signature = GrandProductArgument::create_signature(
|
||||
transcript,
|
||||
grand_products,
|
||||
y,
|
||||
z,
|
||||
|
@ -335,6 +335,25 @@ impl<E: Engine> PermutationStructure<E> {
|
||||
specialized_srs
|
||||
}
|
||||
|
||||
pub fn make_signature(&self, y: E::Fr, z: E::Fr, srs: &SRS<E>) {
|
||||
let (non_permuted_coeffs, permutations) = self.create_permutation_vectors();
|
||||
|
||||
let specialized_srs = PermutationArgument::make_specialized_srs(
|
||||
&non_permuted_coeffs,
|
||||
&permutations,
|
||||
&srs
|
||||
);
|
||||
|
||||
let signature = PermutationArgument::make_signature(
|
||||
non_permuted_coeffs,
|
||||
permutations,
|
||||
y,
|
||||
z,
|
||||
&srs,
|
||||
&specialized_srs
|
||||
);
|
||||
}
|
||||
|
||||
pub fn create_permutation_arguments<R: Rng>(&self, y: E::Fr, z: E::Fr, rng: &mut R, srs: &SRS<E>)
|
||||
-> (Vec<(E::G1Affine, E::G1Affine)>, Vec<E::Fr>, PermutationProof<E>, PermutationArgumentProof<E>, E::Fr, usize, E::Fr)
|
||||
{
|
||||
@ -496,6 +515,7 @@ fn test_simple_succinct_sonic() {
|
||||
|
||||
let perm_structure = create_permutation_structure::<Bls12, _>(&MyCircuit);
|
||||
perm_structure.create_permutation_arguments(x, y, rng, &srs);
|
||||
perm_structure.make_signature(x, y, &srs);
|
||||
let s2 = S2Eval::new(perm_structure.n);
|
||||
let s2 = s2.evaluate(x, y, &srs);
|
||||
let mut s2_value = s2.c_value;
|
||||
@ -521,13 +541,8 @@ fn test_simple_succinct_sonic() {
|
||||
|
||||
expected_s2_value.add_assign(&p2);
|
||||
|
||||
println!("s2 value = {}", s2_value);
|
||||
println!("expected s2 value = {}", expected_s2_value);
|
||||
|
||||
assert!(expected_s2_value == s2_value);
|
||||
|
||||
|
||||
|
||||
println!("N = {}, Q = {}", perm_structure.n, perm_structure.q);
|
||||
}
|
||||
}
|
@ -30,21 +30,23 @@ impl<E: Engine> WellformednessArgument<E> {
|
||||
|
||||
pub fn create_signature(
|
||||
all_polys: Vec<Vec<E::Fr>>,
|
||||
wellformed_challenges: Vec<E::Fr>,
|
||||
srs: &SRS<E>
|
||||
) -> WellformednessSignature<E> {
|
||||
let j = all_polys.len();
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
let wellformed_argument = WellformednessArgument::new(all_polys);
|
||||
let commitments = wellformed_argument.commit(&srs);
|
||||
let mut wellformed_challenges = vec![];
|
||||
for c in commitments.iter() {
|
||||
transcript.commit_point(c);
|
||||
}
|
||||
// let mut wellformed_challenges = vec![];
|
||||
// for c in commitments.iter() {
|
||||
// transcript.commit_point(c);
|
||||
// }
|
||||
|
||||
for _ in 0..j {
|
||||
let challenge = transcript.get_challenge_scalar();
|
||||
wellformed_challenges.push(challenge);
|
||||
}
|
||||
// // TODO
|
||||
// for _ in 0..j {
|
||||
// let challenge = transcript.get_challenge_scalar();
|
||||
// wellformed_challenges.push(challenge);
|
||||
// }
|
||||
|
||||
let proof = wellformed_argument.make_argument(wellformed_challenges, &srs);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user