Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boost verifier #835

Merged
merged 1 commit into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.)**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super!!


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