Skip to content

Commit

Permalink
Boost the verifier (#835)
Browse files Browse the repository at this point in the history
  • Loading branch information
xevisalle authored Aug 8, 2024
1 parent dc1d229 commit 4c345c6
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 52 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Modify the prover to match the paper [#831]
- Modify the verifier to match the paper [#831]
- Rename some variables to match the paper [#831]
- Modify the parallelization to have a faster verifier [#834]

### Removed

Expand Down Expand Up @@ -592,6 +593,7 @@ is necessary since `rkyv/validation` was required as a bound.
- Proof system module.

<!-- ISSUES -->
[#834]: https://github.com/dusk-network/plonk/issues/834
[#831]: https://github.com/dusk-network/plonk/issues/831
[#819]: https://github.com/dusk-network/plonk/issues/819
[#818]: https://github.com/dusk-network/plonk/issues/818
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ as the documentation regarding the data structures that it exports. To check thi
Benchmarks taken on `Apple M1`, for a circuit-size of `2^16` constraints:

- Proving time: `7.871s`
- Verification time: `3.732ms` **(This time does not vary depending on the circuit-size.)**
- Verification time: `2.821ms` **(This time does not vary depending on the circuit-size.)**

For more results, please run `cargo bench` to get a full report of benchmarks in respect of constraint numbers.

Expand Down
111 changes: 60 additions & 51 deletions src/proof_system/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,91 +358,100 @@ pub(crate) mod alloc {
v_coeffs_E.push(v_coeffs_E[V_MAX_DEGREE] * v_w_challenge);
v_coeffs_E.push(v_coeffs_E[V_MAX_DEGREE + 1] * v_w_challenge);

// Coefficients to compute [F]_1
let mut v_coeffs_F = v_coeffs_E[..V_MAX_DEGREE].to_vec();
// Evaluations to compute [E]_1
let E_evals = vec![
self.evaluations.a_eval,
self.evaluations.b_eval,
self.evaluations.c_eval,
self.evaluations.d_eval,
self.evaluations.s_sigma_1_eval,
self.evaluations.s_sigma_2_eval,
self.evaluations.s_sigma_3_eval,
self.evaluations.a_w_eval,
self.evaluations.b_w_eval,
self.evaluations.d_w_eval,
];

// As we include the shifted coefficients when computing [F]_1,
// we group them to save scalar multiplications when multiplying
// by [a]_1, [b]_1, and [d]_1
v_coeffs_F[0] += v_coeffs_E[V_MAX_DEGREE];
v_coeffs_F[1] += v_coeffs_E[V_MAX_DEGREE + 1];
v_coeffs_F[3] += v_coeffs_E[V_MAX_DEGREE + 2];
// Compute E = (-r_0 + (v)a + (v^2)b + (v^3)c + (v^4)d +
// + (v^5)s_sigma_1 + (v^6)s_sigma_2 + (v^7)s_sigma_3 +
// + (u)z_w + (u * v_w)a_w + (u * v_w^2)b_w + (u * v_w^3)d_w)
let mut E_scalar: BlsScalar = E_evals
.iter()
.zip(v_coeffs_E.iter())
.map(|(eval, coeff)| eval * coeff)
.sum();
E_scalar += -r_0_eval + (u_challenge * self.evaluations.z_eval);

// Commitments to compute [F]_1
let F_comms = vec![
// We group all the remaining scalar multiplications in the
// verification process, with the purpose of
// parallelizing them
let scalarmuls_points = vec![
self.a_comm.0,
self.b_comm.0,
self.c_comm.0,
self.d_comm.0,
verifier_key.permutation.s_sigma_1.0,
verifier_key.permutation.s_sigma_2.0,
verifier_key.permutation.s_sigma_3.0,
opening_key.g,
self.w_z_chall_w_comm.0,
self.w_z_chall_comm.0,
self.w_z_chall_w_comm.0,
];

// Compute '[F]_1' in single-core
let mut scalarmuls_scalars = v_coeffs_E[..V_MAX_DEGREE].to_vec();

// As we include the shifted coefficients when computing [F]_1,
// we group them to save scalar multiplications when multiplying
// by [a]_1, [b]_1, and [d]_1
scalarmuls_scalars[0] += v_coeffs_E[V_MAX_DEGREE];
scalarmuls_scalars[1] += v_coeffs_E[V_MAX_DEGREE + 1];
scalarmuls_scalars[3] += v_coeffs_E[V_MAX_DEGREE + 2];

scalarmuls_scalars.push(E_scalar);
scalarmuls_scalars.push(u_challenge);
scalarmuls_scalars.push(z_challenge);
scalarmuls_scalars
.push(u_challenge * z_challenge * domain.group_gen);

// Compute the scalar multiplications in single-core
#[cfg(not(feature = "std"))]
let mut F: G1Projective = F_comms
let scalarmuls: Vec<G1Projective> = scalarmuls_points
.iter()
.zip(v_coeffs_F.iter())
.map(|(poly, coeff)| poly * coeff)
.sum();
.zip(scalarmuls_scalars.iter())
.map(|(point, scalar)| point * scalar)
.collect();

// Compute '[F]_1' in multi-core
// Compute the scalar multiplications in multi-core
#[cfg(feature = "std")]
let mut F: G1Projective = F_comms
let scalarmuls: Vec<G1Projective> = scalarmuls_points
.par_iter()
.zip(v_coeffs_F.par_iter())
.map(|(poly, coeff)| poly * coeff)
.sum();
.zip(scalarmuls_scalars.par_iter())
.map(|(point, scalar)| point * scalar)
.collect();

// [F]_1 = [D]_1 + (v)[a]_1 + (v^2)[b]_1 + (v^3)[c]_1 + (v^4)[d]_1 +
// + (v^5)[s_sigma_1]_1 + (v^6)[s_sigma_2]_1 + (v^7)[s_sigma_3]_1 +
// + (u * v_w)[a]_1 + (u * v_w^2)[b]_1 + (u * v_w^3)[d]_1
let mut F: G1Projective = scalarmuls[..V_MAX_DEGREE].iter().sum();
F += D;

// Evaluations to compute [E]_1
let E_evals = vec![
self.evaluations.a_eval,
self.evaluations.b_eval,
self.evaluations.c_eval,
self.evaluations.d_eval,
self.evaluations.s_sigma_1_eval,
self.evaluations.s_sigma_2_eval,
self.evaluations.s_sigma_3_eval,
self.evaluations.a_w_eval,
self.evaluations.b_w_eval,
self.evaluations.d_w_eval,
];

// Compute '[E]_1' = (-r_0 + (v)a + (v^2)b + (v^3)c + (v^4)d +
// + (v^5)s_sigma_1 + (v^6)s_sigma_2 + (v^7)s_sigma_3 +
// + (u)z_w + (u * v_w)a_w + (u * v_w^2)b_w + (u * v_w^3)d_w)
let mut E: BlsScalar = E_evals
.iter()
.zip(v_coeffs_E.iter())
.map(|(eval, coeff)| eval * coeff)
.sum();
E += -r_0_eval + (u_challenge * self.evaluations.z_eval);

let E = E * opening_key.g;
// [E]_1 = E * G
let E = scalarmuls[V_MAX_DEGREE];

// Compute the G_1 element of the first pairing:
// [W_z]_1 + u * [W_zw]_1
//
// Note that we negate this value to be able to subtract
// the pairings later on, using the multi Miller loop
let left = G1Affine::from(
-(self.w_z_chall_comm.0
+ u_challenge * self.w_z_chall_w_comm.0),
-(self.w_z_chall_comm.0 + scalarmuls[V_MAX_DEGREE + 1]),
);

// Compute the G_1 element of the second pairing:
// z * [W_z]_1 + (u * z * w) * [W_zw]_1 + [F]_1 - [E]_1
let right = G1Affine::from(
z_challenge * self.w_z_chall_comm.0
+ (u_challenge * z_challenge * domain.group_gen)
* self.w_z_chall_w_comm.0
+ F
scalarmuls[V_MAX_DEGREE + 2] + scalarmuls[V_MAX_DEGREE + 3] + F
- E,
);

Expand Down

0 comments on commit 4c345c6

Please sign in to comment.