diff --git a/src/plonk.rs b/src/plonk.rs index fd72bde..adaf412 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -48,6 +48,7 @@ pub struct Proof { permutation_product_evals: Vec, permutation_product_inv_evals: Vec, permutation_evals: Vec, + advice_shifted_evals: Vec>>, advice_evals: Vec, fixed_evals: Vec, h_evals: Vec, diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index f4081a9..dd1ba5c 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -117,6 +117,33 @@ impl Proof { // Sample x_1 challenge let x_1: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + // Compute [omega^0, omega^1, ..., omega^{params.n - 1}] + let mut omega_powers = Vec::with_capacity(params.n as usize); + { + let mut cur = C::Scalar::one(); + for _ in 0..params.n { + omega_powers.push(cur); + cur *= &srs.domain.get_omega(); + } + } + + let mut advice_shifted_evals = + vec![ + vec![vec![C::Scalar::zero(); params.n as usize]; meta.num_advice_wires]; + meta.permutations.len() + ]; + + for perm_idx in 0..meta.permutations.len() { + for wire_idx in 0..meta.permutations[perm_idx].len() { + for point_idx in 0..params.n { + let mut eval = + eval_polynomial(&advice_polys[wire_idx], omega_powers[point_idx as usize]); + eval += &x_1; + advice_shifted_evals[perm_idx][wire_idx as usize][point_idx as usize] = eval; + } + } + } + // Obtain challenge for keeping all separate gates linearly independent let x_2: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); @@ -379,6 +406,7 @@ impl Proof { permutation_product_evals: vec![C::Scalar::one(); params.n as usize], permutation_product_inv_evals: vec![C::Scalar::one(); params.n as usize], permutation_evals: vec![C::Scalar::one(); params.n as usize], + advice_shifted_evals, advice_evals, fixed_evals, h_evals, diff --git a/src/plonk/srs.rs b/src/plonk/srs.rs index d22ac77..8e7a609 100644 --- a/src/plonk/srs.rs +++ b/src/plonk/srs.rs @@ -164,7 +164,7 @@ impl SRS { deltaomega[permuted_i][permuted_j] }) .collect(); - + // Compute commitment to permutation polynomial commitments.push( params diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index 37083f0..635e180 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -37,16 +37,28 @@ impl Proof { } // For each permutation - for perm in &srs.meta.permutations { - // Check permutation condition on all points - for i in 0..params.n as usize { - let left_perm_eval = self.permutation_product_inv_evals[i]; - let right_perm_eval = self.permutation_product_evals[i]; + for perm_idx in 0..srs.meta.permutations.len() { + // For each X in evaluation domain + for point_idx in 0..params.n as usize { + let point = omega_powers[point_idx]; - for wire in perm { + let mut left_perm_eval = self.permutation_product_inv_evals[point_idx]; + let mut right_perm_eval = self.permutation_product_evals[point_idx]; + let mut cur_delta = C::Scalar::one(); + + for wire_idx in 0..srs.meta.permutations[perm_idx].len() { // z(\omega^{-1} X) (a(X) + \beta X + \gamma) (b(X) + \delta \beta X + \gamma) (c(X) + \delta^2 \beta X + \gamma) + let left_tmp = &(self.advice_shifted_evals[perm_idx][wire_idx][point_idx] + + &(x_0 * &(cur_delta * &point))); + left_perm_eval *= &left_tmp; + + cur_delta *= &C::Scalar::DELTA; // z(X) (a(X) + \beta s_a(X) + \gamma) (b(X) + \beta s_b(X) + \gamma) (c(X) + \beta s_c(X) + \gamma) + let perm_eval = srs.permutation_polys[perm_idx][wire_idx][point_idx]; + let right_tmp = &(self.advice_shifted_evals[perm_idx][wire_idx][point_idx] + + &(x_0 * &perm_eval)); + right_perm_eval *= &right_tmp; } if left_perm_eval != right_perm_eval { return false;