diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b2f2e1..70d05fc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Changed +### Changed + +- Modify the prover to match the paper [#831] +- Modify the verifier to match the paper [#831] +- Rename some variables to match the paper [#831] + +### Removed - Remove docs [#819] +- Remove unused `Evaluations` struct ## [0.19.2] - 2024-03-27 @@ -585,6 +592,7 @@ is necessary since `rkyv/validation` was required as a bound. - Proof system module. +[#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 [#815]: https://github.com/dusk-network/plonk/issues/815 diff --git a/README.md b/README.md index 9c946cfd..4cc6acc3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ _This is a pure Rust implementation of the PLONK proving system over BLS12-381._ -This library contains a modular implementation of KZG10 as the default polynomial commitment scheme. +This library contains a modular implementation of KZG10 as the default polynomial commitment scheme. Moreover, it includes custom gates for efficiency purposes. The details on our specific implementation can be found [here](docs/dusk-plonk-specs.pdf). **DISCLAIMER**: This library is currently unstable and still needs to undergo an exhaustive security analysis. Use at your own risk. @@ -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: `7.643ms` **(This time does not vary depending on the circuit-size.)** +- Verification time: `3.732ms` **(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. diff --git a/docs/dusk-plonk-specs.pdf b/docs/dusk-plonk-specs.pdf new file mode 100644 index 00000000..378d592e Binary files /dev/null and b/docs/dusk-plonk-specs.pdf differ diff --git a/src/commitment_scheme/kzg10/key.rs b/src/commitment_scheme/kzg10/key.rs index 457a8521..82078b79 100644 --- a/src/commitment_scheme/kzg10/key.rs +++ b/src/commitment_scheme/kzg10/key.rs @@ -191,13 +191,11 @@ impl CommitKey { /// We apply the same optimization mentioned in when computing each witness; /// removing f(z). pub(crate) fn compute_aggregate_witness( - &self, polynomials: &[Polynomial], point: &BlsScalar, - transcript: &mut Transcript, + v_challenge: &BlsScalar, ) -> Polynomial { - let v_challenge = transcript.challenge_scalar(b"v_challenge"); - let powers = util::powers_of(&v_challenge, polynomials.len() - 1); + let powers = util::powers_of(v_challenge, polynomials.len() - 1); assert_eq!(powers.len(), polynomials.len()); @@ -227,15 +225,15 @@ pub struct OpeningKey { /// The generator of G2. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub(crate) h: G2Affine, - /// \beta times the above generator of G2. + /// 'x' times the above generator of G2. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) beta_h: G2Affine, + pub(crate) x_h: G2Affine, /// The generator of G2, prepared for use in pairings. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub(crate) prepared_h: G2Prepared, - /// \beta times the above generator of G2, prepared for use in pairings. + /// 'x' times the above generator of G2, prepared for use in pairings. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) prepared_beta_h: G2Prepared, + pub(crate) prepared_x_h: G2Prepared, } impl Serializable<{ G1Affine::SIZE + G2Affine::SIZE * 2 }> for OpeningKey { @@ -248,7 +246,7 @@ impl Serializable<{ G1Affine::SIZE + G2Affine::SIZE * 2 }> for OpeningKey { // This can't fail therefore we don't care about the Result nor use it. writer.write(&self.g.to_bytes()); writer.write(&self.h.to_bytes()); - writer.write(&self.beta_h.to_bytes()); + writer.write(&self.x_h.to_bytes()); buf } @@ -264,24 +262,21 @@ impl Serializable<{ G1Affine::SIZE + G2Affine::SIZE * 2 }> for OpeningKey { } impl OpeningKey { - pub(crate) fn new( - g: G1Affine, - h: G2Affine, - beta_h: G2Affine, - ) -> OpeningKey { + pub(crate) fn new(g: G1Affine, h: G2Affine, x_h: G2Affine) -> OpeningKey { let prepared_h = G2Prepared::from(h); - let prepared_beta_h = G2Prepared::from(beta_h); + let prepared_x_h = G2Prepared::from(x_h); OpeningKey { g, h, - beta_h, + x_h, prepared_h, - prepared_beta_h, + prepared_x_h, } } /// Checks whether a batch of polynomials evaluated at different points, /// returned their specified value. + #[allow(dead_code)] pub(crate) fn batch_check( &self, points: &[BlsScalar], @@ -315,7 +310,7 @@ impl OpeningKey { let affine_total_c = G1Affine::from(total_c); let pairing = dusk_bls12_381::multi_miller_loop(&[ - (&affine_total_w, &self.prepared_beta_h), + (&affine_total_w, &self.prepared_x_h), (&affine_total_c, &self.prepared_h), ]) .final_exponentiation(); @@ -345,7 +340,7 @@ mod test { - (op_key.g * proof.evaluated_point)) .into(); - let inner_b: G2Affine = (op_key.beta_h - (op_key.h * point)).into(); + let inner_b: G2Affine = (op_key.x_h - (op_key.h * point)).into(); let prepared_inner_b = G2Prepared::from(-inner_b); let pairing = dusk_bls12_381::multi_miller_loop(&[ @@ -391,9 +386,14 @@ mod test { polynomial_commitments.push(ck.commit(poly)?) } + let v_challenge = transcript.challenge_scalar(b"v_challenge"); + // Compute the aggregate witness for polynomials - let witness_poly = - ck.compute_aggregate_witness(polynomials, point, transcript); + let witness_poly = CommitKey::compute_aggregate_witness( + polynomials, + point, + &v_challenge, + ); // Commit to witness polynomial let witness_commitment = ck.commit(&witness_poly)?; @@ -482,13 +482,13 @@ mod test { let poly_b = Polynomial::rand(26 + 1, &mut OsRng); let poly_b_eval = poly_b.evaluate(&point); - let poly_o = Polynomial::rand(27, &mut OsRng); - let poly_o_eval = poly_o.evaluate(&point); + let poly_c = Polynomial::rand(27, &mut OsRng); + let poly_c_eval = poly_c.evaluate(&point); open_multiple( &ck, - &[poly_a, poly_b, poly_o], - vec![poly_a_eval, poly_b_eval, poly_o_eval], + &[poly_a, poly_b, poly_c], + vec![poly_a_eval, poly_b_eval, poly_c_eval], &point, &mut Transcript::new(b"agg_flatten"), )? @@ -496,8 +496,9 @@ mod test { // Verifier's View let ok = { - let flattened_proof = - aggregated_proof.flatten(&mut Transcript::new(b"agg_flatten")); + let transcript = &mut Transcript::new(b"agg_flatten"); + let v_challenge = transcript.challenge_scalar(b"v_challenge"); + let flattened_proof = aggregated_proof.flatten(&v_challenge); check(&opening_key, point, flattened_proof) }; @@ -521,16 +522,16 @@ mod test { let poly_b = Polynomial::rand(26, &mut OsRng); let poly_b_eval = poly_b.evaluate(&point_a); - let poly_o = Polynomial::rand(27, &mut OsRng); - let poly_o_eval = poly_o.evaluate(&point_a); + let poly_c = Polynomial::rand(27, &mut OsRng); + let poly_c_eval = poly_c.evaluate(&point_a); let poly_d = Polynomial::rand(28, &mut OsRng); let poly_d_eval = poly_d.evaluate(&point_b); let aggregated_proof = open_multiple( &ck, - &[poly_a, poly_b, poly_o], - vec![poly_a_eval, poly_b_eval, poly_o_eval], + &[poly_a, poly_b, poly_c], + vec![poly_a_eval, poly_b_eval, poly_c_eval], &point_a, &mut Transcript::new(b"agg_batch"), )?; @@ -544,7 +545,8 @@ mod test { // Verifier's View let mut transcript = Transcript::new(b"agg_batch"); - let flattened_proof = aggregated_proof.flatten(&mut transcript); + let v_challenge = transcript.challenge_scalar(b"v_challenge"); + let flattened_proof = aggregated_proof.flatten(&v_challenge); opening_key.batch_check( &[point_a, point_b], diff --git a/src/commitment_scheme/kzg10/proof.rs b/src/commitment_scheme/kzg10/proof.rs index afd7fa5d..58fffb63 100644 --- a/src/commitment_scheme/kzg10/proof.rs +++ b/src/commitment_scheme/kzg10/proof.rs @@ -24,18 +24,17 @@ pub(crate) struct Proof { #[cfg(feature = "alloc")] pub(crate) mod alloc { use super::*; - use crate::transcript::TranscriptProtocol; use crate::util::powers_of; #[rustfmt::skip] use ::alloc::vec::Vec; use dusk_bls12_381::G1Projective; - use merlin::Transcript; #[cfg(feature = "std")] use rayon::prelude::*; /// Proof that multiple polynomials were correctly evaluated at a point `z`, /// each producing their respective evaluated points p_i(z). #[derive(Debug)] + #[allow(dead_code)] pub(crate) struct AggregateProof { /// This is a commitment to the aggregated witness polynomial. pub(crate) commitment_to_witness: Commitment, @@ -47,6 +46,7 @@ pub(crate) mod alloc { pub(crate) commitments_to_polynomials: Vec, } + #[allow(dead_code)] impl AggregateProof { /// Initializes an `AggregatedProof` with the commitment to the witness. pub(crate) fn with_witness(witness: Commitment) -> AggregateProof { @@ -65,12 +65,9 @@ pub(crate) mod alloc { } /// Flattens an `AggregateProof` into a `Proof`. - /// The transcript must have the same view as the transcript that was - /// used to aggregate the witness in the proving stage. - pub(crate) fn flatten(&self, transcript: &mut Transcript) -> Proof { - let v_challenge = transcript.challenge_scalar(b"v_challenge"); + pub(crate) fn flatten(&self, v_challenge: &BlsScalar) -> Proof { let powers = powers_of( - &v_challenge, + v_challenge, self.commitments_to_polynomials.len() - 1, ); diff --git a/src/commitment_scheme/kzg10/srs.rs b/src/commitment_scheme/kzg10/srs.rs index 55a18595..709df97c 100644 --- a/src/commitment_scheme/kzg10/srs.rs +++ b/src/commitment_scheme/kzg10/srs.rs @@ -230,7 +230,7 @@ mod test { assert_eq!(got_pp.commit_key.powers_of_g, pp.commit_key.powers_of_g); assert_eq!(got_pp.opening_key.g, pp.opening_key.g); assert_eq!(got_pp.opening_key.h, pp.opening_key.h); - assert_eq!(got_pp.opening_key.beta_h, pp.opening_key.beta_h); + assert_eq!(got_pp.opening_key.x_h, pp.opening_key.x_h); } #[test] @@ -245,6 +245,6 @@ mod test { assert_eq!(pp.commit_key, pp_p.commit_key); assert_eq!(pp.opening_key.g, pp_p.opening_key.g); assert_eq!(pp.opening_key.h, pp_p.opening_key.h); - assert_eq!(pp.opening_key.beta_h, pp_p.opening_key.beta_h); + assert_eq!(pp.opening_key.x_h, pp_p.opening_key.x_h); } } diff --git a/src/compiler.rs b/src/compiler.rs index 8dbfe431..e1dacf26 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -108,7 +108,7 @@ impl Compiler { let mut q_l = vec![BlsScalar::zero(); size]; let mut q_r = vec![BlsScalar::zero(); size]; let mut q_o = vec![BlsScalar::zero(); size]; - let mut q_4 = vec![BlsScalar::zero(); size]; + let mut q_f = vec![BlsScalar::zero(); size]; let mut q_c = vec![BlsScalar::zero(); size]; let mut q_arith = vec![BlsScalar::zero(); size]; let mut q_range = vec![BlsScalar::zero(); size]; @@ -116,25 +116,29 @@ impl Compiler { let mut q_fixed_group_add = vec![BlsScalar::zero(); size]; let mut q_variable_group_add = vec![BlsScalar::zero(); size]; - prover.constraints.iter().enumerate().for_each(|(i, c)| { - q_m[i] = c.q_m; - q_l[i] = c.q_l; - q_r[i] = c.q_r; - q_o[i] = c.q_o; - q_4[i] = c.q_4; - q_c[i] = c.q_c; - q_arith[i] = c.q_arith; - q_range[i] = c.q_range; - q_logic[i] = c.q_logic; - q_fixed_group_add[i] = c.q_fixed_group_add; - q_variable_group_add[i] = c.q_variable_group_add; - }); + prover + .constraints + .iter() + .enumerate() + .for_each(|(i, constraint)| { + q_m[i] = constraint.q_m; + q_l[i] = constraint.q_l; + q_r[i] = constraint.q_r; + q_o[i] = constraint.q_o; + q_f[i] = constraint.q_f; + q_c[i] = constraint.q_c; + q_arith[i] = constraint.q_arith; + q_range[i] = constraint.q_range; + q_logic[i] = constraint.q_logic; + q_fixed_group_add[i] = constraint.q_fixed_group_add; + q_variable_group_add[i] = constraint.q_variable_group_add; + }); let q_m_poly = domain.ifft(&q_m); let q_l_poly = domain.ifft(&q_l); let q_r_poly = domain.ifft(&q_r); let q_o_poly = domain.ifft(&q_o); - let q_4_poly = domain.ifft(&q_4); + let q_f_poly = domain.ifft(&q_f); let q_c_poly = domain.ifft(&q_c); let q_arith_poly = domain.ifft(&q_arith); let q_range_poly = domain.ifft(&q_range); @@ -146,7 +150,7 @@ impl Compiler { let q_l_poly = Polynomial::from_coefficients_vec(q_l_poly); let q_r_poly = Polynomial::from_coefficients_vec(q_r_poly); let q_o_poly = Polynomial::from_coefficients_vec(q_o_poly); - let q_4_poly = Polynomial::from_coefficients_vec(q_4_poly); + let q_f_poly = Polynomial::from_coefficients_vec(q_f_poly); let q_c_poly = Polynomial::from_coefficients_vec(q_c_poly); let q_arith_poly = Polynomial::from_coefficients_vec(q_arith_poly); let q_range_poly = Polynomial::from_coefficients_vec(q_range_poly); @@ -160,72 +164,69 @@ impl Compiler { let [s_sigma_1_poly, s_sigma_2_poly, s_sigma_3_poly, s_sigma_4_poly] = perm.compute_sigma_polynomials(size, &domain); - let q_m_poly_commit = commit_key.commit(&q_m_poly).unwrap_or_default(); - let q_l_poly_commit = commit_key.commit(&q_l_poly).unwrap_or_default(); - let q_r_poly_commit = commit_key.commit(&q_r_poly).unwrap_or_default(); - let q_o_poly_commit = commit_key.commit(&q_o_poly).unwrap_or_default(); - let q_4_poly_commit = commit_key.commit(&q_4_poly).unwrap_or_default(); - let q_c_poly_commit = commit_key.commit(&q_c_poly).unwrap_or_default(); - let q_arith_poly_commit = - commit_key.commit(&q_arith_poly).unwrap_or_default(); - let q_range_poly_commit = - commit_key.commit(&q_range_poly).unwrap_or_default(); - let q_logic_poly_commit = - commit_key.commit(&q_logic_poly).unwrap_or_default(); - let q_fixed_group_add_poly_commit = commit_key + let q_m_comm = commit_key.commit(&q_m_poly).unwrap_or_default(); + let q_l_comm = commit_key.commit(&q_l_poly).unwrap_or_default(); + let q_r_comm = commit_key.commit(&q_r_poly).unwrap_or_default(); + let q_o_comm = commit_key.commit(&q_o_poly).unwrap_or_default(); + let q_f_comm = commit_key.commit(&q_f_poly).unwrap_or_default(); + let q_c_comm = commit_key.commit(&q_c_poly).unwrap_or_default(); + let q_arith_comm = commit_key.commit(&q_arith_poly).unwrap_or_default(); + let q_range_comm = commit_key.commit(&q_range_poly).unwrap_or_default(); + let q_logic_comm = commit_key.commit(&q_logic_poly).unwrap_or_default(); + let q_fixed_group_add_comm = commit_key .commit(&q_fixed_group_add_poly) .unwrap_or_default(); - let q_variable_group_add_poly_commit = commit_key + let q_variable_group_add_comm = commit_key .commit(&q_variable_group_add_poly) .unwrap_or_default(); - let s_sigma_1_poly_commit = commit_key.commit(&s_sigma_1_poly)?; - let s_sigma_2_poly_commit = commit_key.commit(&s_sigma_2_poly)?; - let s_sigma_3_poly_commit = commit_key.commit(&s_sigma_3_poly)?; - let s_sigma_4_poly_commit = commit_key.commit(&s_sigma_4_poly)?; + let s_sigma_1_comm = commit_key.commit(&s_sigma_1_poly)?; + let s_sigma_2_comm = commit_key.commit(&s_sigma_2_poly)?; + let s_sigma_3_comm = commit_key.commit(&s_sigma_3_poly)?; + let s_sigma_4_comm = commit_key.commit(&s_sigma_4_poly)?; // verifier Key for arithmetic circuits let arithmetic_verifier_key = widget::arithmetic::VerifierKey { - q_m: q_m_poly_commit, - q_l: q_l_poly_commit, - q_r: q_r_poly_commit, - q_o: q_o_poly_commit, - q_4: q_4_poly_commit, - q_c: q_c_poly_commit, - q_arith: q_arith_poly_commit, + q_m: q_m_comm, + q_l: q_l_comm, + q_r: q_r_comm, + q_o: q_o_comm, + q_f: q_f_comm, + q_c: q_c_comm, + q_arith: q_arith_comm, }; // verifier Key for range circuits let range_verifier_key = widget::range::VerifierKey { - q_range: q_range_poly_commit, + q_range: q_range_comm, }; // verifier Key for logic circuits let logic_verifier_key = widget::logic::VerifierKey { - q_c: q_c_poly_commit, - q_logic: q_logic_poly_commit, + q_c: q_c_comm, + q_logic: q_logic_comm, }; // verifier Key for ecc circuits let ecc_verifier_key = widget::ecc::scalar_mul::fixed_base::VerifierKey { - q_l: q_l_poly_commit, - q_r: q_r_poly_commit, - q_fixed_group_add: q_fixed_group_add_poly_commit, + q_l: q_l_comm, + q_r: q_r_comm, + q_fixed_group_add: q_fixed_group_add_comm, }; // verifier Key for curve addition circuits let curve_addition_verifier_key = widget::ecc::curve_addition::VerifierKey { - q_variable_group_add: q_variable_group_add_poly_commit, + q_variable_group_add: q_variable_group_add_comm, }; // verifier Key for permutation argument let permutation_verifier_key = widget::permutation::VerifierKey { - s_sigma_1: s_sigma_1_poly_commit, - s_sigma_2: s_sigma_2_poly_commit, - s_sigma_3: s_sigma_3_poly_commit, - s_sigma_4: s_sigma_4_poly_commit, + s_sigma_1: s_sigma_1_comm, + s_sigma_2: s_sigma_2_comm, + s_sigma_3: s_sigma_3_comm, + s_sigma_4: s_sigma_4_comm, }; let verifier_key = widget::VerifierKey { @@ -243,7 +244,7 @@ impl Compiler { q_l: q_l_poly, q_r: q_r_poly, q_o: q_o_poly, - q_4: q_4_poly, + q_f: q_f_poly, q_c: q_c_poly, q_arith: q_arith_poly, q_range: q_range_poly, @@ -282,8 +283,8 @@ impl Compiler { domain_8n.coset_fft(&selectors.q_c), domain_8n, ); - let q_4_eval_8n = Evaluations::from_vec_and_domain( - domain_8n.coset_fft(&selectors.q_4), + let q_f_eval_8n = Evaluations::from_vec_and_domain( + domain_8n.coset_fft(&selectors.q_f), domain_8n, ); let q_arith_eval_8n = Evaluations::from_vec_and_domain( @@ -334,7 +335,7 @@ impl Compiler { q_l: (selectors.q_l.clone(), q_l_eval_8n.clone()), q_r: (selectors.q_r.clone(), q_r_eval_8n.clone()), q_o: (selectors.q_o, q_o_eval_8n), - q_4: (selectors.q_4, q_4_eval_8n), + q_f: (selectors.q_f, q_f_eval_8n), q_c: (selectors.q_c.clone(), q_c_eval_8n.clone()), q_arith: (selectors.q_arith, q_arith_eval_8n), }; diff --git a/src/compiler/prover.rs b/src/compiler/prover.rs index 0b0d09ca..b3f5152c 100644 --- a/src/compiler/prover.rs +++ b/src/compiler/prover.rs @@ -14,11 +14,11 @@ use merlin::Transcript; use rand_core::{CryptoRng, RngCore}; use crate::commitment_scheme::CommitKey; +use crate::compiler::prover::linearization_poly::ProofEvaluations; use crate::error::Error; use crate::fft::{EvaluationDomain, Polynomial}; -use crate::proof_system::proof::Proof; use crate::proof_system::{ - linearization_poly, quotient_poly, ProverKey, VerifierKey, + linearization_poly, proof::Proof, quotient_poly, ProverKey, VerifierKey, }; use crate::transcript::TranscriptProtocol; @@ -254,35 +254,39 @@ impl Prover { // round 1 // convert wires to padded scalars - let mut a_w_scalar = vec![BlsScalar::zero(); size]; - let mut b_w_scalar = vec![BlsScalar::zero(); size]; - let mut o_w_scalar = vec![BlsScalar::zero(); size]; - let mut d_w_scalar = vec![BlsScalar::zero(); size]; - - prover.constraints.iter().enumerate().for_each(|(i, c)| { - a_w_scalar[i] = prover[c.w_a]; - b_w_scalar[i] = prover[c.w_b]; - o_w_scalar[i] = prover[c.w_o]; - d_w_scalar[i] = prover[c.w_d]; - }); - - let a_w_poly = Self::blind_poly(rng, &a_w_scalar, 1, &domain); - let b_w_poly = Self::blind_poly(rng, &b_w_scalar, 1, &domain); - let o_w_poly = Self::blind_poly(rng, &o_w_scalar, 1, &domain); - let d_w_poly = Self::blind_poly(rng, &d_w_scalar, 1, &domain); + let mut a_scalars = vec![BlsScalar::zero(); size]; + let mut b_scalars = vec![BlsScalar::zero(); size]; + let mut c_scalars = vec![BlsScalar::zero(); size]; + let mut d_scalars = vec![BlsScalar::zero(); size]; + + prover + .constraints + .iter() + .enumerate() + .for_each(|(i, constraint)| { + a_scalars[i] = prover[constraint.a]; + b_scalars[i] = prover[constraint.b]; + c_scalars[i] = prover[constraint.c]; + d_scalars[i] = prover[constraint.d]; + }); + + let a_poly = Self::blind_poly(rng, &a_scalars, 1, &domain); + let b_poly = Self::blind_poly(rng, &b_scalars, 1, &domain); + let c_poly = Self::blind_poly(rng, &c_scalars, 1, &domain); + let d_poly = Self::blind_poly(rng, &d_scalars, 1, &domain); // commit to wire polynomials // ([a(x)]_1, [b(x)]_1, [c(x)]_1, [d(x)]_1) - let a_w_poly_commit = self.commit_key.commit(&a_w_poly)?; - let b_w_poly_commit = self.commit_key.commit(&b_w_poly)?; - let o_w_poly_commit = self.commit_key.commit(&o_w_poly)?; - let d_w_poly_commit = self.commit_key.commit(&d_w_poly)?; + let a_comm = self.commit_key.commit(&a_poly)?; + let b_comm = self.commit_key.commit(&b_poly)?; + let c_comm = self.commit_key.commit(&c_poly)?; + let d_comm = self.commit_key.commit(&d_poly)?; // Add wire polynomial commitments to transcript - transcript.append_commitment(b"a_w", &a_w_poly_commit); - transcript.append_commitment(b"b_w", &b_w_poly_commit); - transcript.append_commitment(b"o_w", &o_w_poly_commit); - transcript.append_commitment(b"d_w", &d_w_poly_commit); + transcript.append_commitment(b"a_comm", &a_comm); + transcript.append_commitment(b"b_comm", &b_comm); + transcript.append_commitment(b"c_comm", &c_comm); + transcript.append_commitment(b"d_comm", &d_comm); // round 2 // permutation challenges @@ -297,18 +301,18 @@ impl Prover { &self.prover_key.permutation.s_sigma_4.0, ]; let wires = [ - a_w_scalar.as_slice(), - b_w_scalar.as_slice(), - o_w_scalar.as_slice(), - d_w_scalar.as_slice(), + a_scalars.as_slice(), + b_scalars.as_slice(), + c_scalars.as_slice(), + d_scalars.as_slice(), ]; let permutation = prover .perm .compute_permutation_vec(&domain, wires, &beta, &gamma, sigma); let z_poly = Self::blind_poly(rng, &permutation, 2, &domain); - let z_poly_commit = self.commit_key.commit(&z_poly)?; - transcript.append_commitment(b"z", &z_poly_commit); + let z_comm = self.commit_key.commit(&z_poly)?; + transcript.append_commitment(b"z_comm", &z_comm); // round 3 // compute quotient challenge alpha @@ -327,7 +331,7 @@ impl Prover { let pi_poly = Polynomial::from_coefficients_vec(pi_poly); // compute quotient polynomial - let wires = (&a_w_poly, &b_w_poly, &o_w_poly, &d_w_poly); + let wires = (&a_poly, &b_poly, &c_poly, &d_poly); let args = &( alpha, beta, @@ -352,52 +356,134 @@ impl Prover { let mut t_low_vec = t_poly[0..domain_size].to_vec(); let mut t_mid_vec = t_poly[domain_size..2 * domain_size].to_vec(); let mut t_high_vec = t_poly[2 * domain_size..3 * domain_size].to_vec(); - let mut t_4_vec = t_poly[3 * domain_size..].to_vec(); + let mut t_fourth_vec = t_poly[3 * domain_size..].to_vec(); // select 3 blinding factors for the quotient splitted polynomials - let b_10 = BlsScalar::random(&mut *rng); - let b_11 = BlsScalar::random(&mut *rng); let b_12 = BlsScalar::random(&mut *rng); + let b_13 = BlsScalar::random(&mut *rng); + let b_14 = BlsScalar::random(&mut *rng); - // t_low'(X) + b_10*X^n - t_low_vec.push(b_10); + // t_low'(X) + b_12*X^n + t_low_vec.push(b_12); - // t_mid'(X) - b_10 + b_11*X^n - t_mid_vec[0] -= b_10; - t_mid_vec.push(b_11); + // t_mid'(X) - b_12 + b_13*X^n + t_mid_vec[0] -= b_12; + t_mid_vec.push(b_13); - // t_high'(X) - b_11 + b_12*X^n - t_high_vec[0] -= b_11; - t_high_vec.push(b_12); + // t_high'(X) - b_13 + b_14*X^n + t_high_vec[0] -= b_13; + t_high_vec.push(b_14); - // t_4'(X) - b_12 - t_4_vec[0] -= b_12; + // t_fourth'(X) - b_14 + t_fourth_vec[0] -= b_14; let t_low_poly = Polynomial::from_coefficients_vec(t_low_vec); let t_mid_poly = Polynomial::from_coefficients_vec(t_mid_vec); let t_high_poly = Polynomial::from_coefficients_vec(t_high_vec); - let t_4_poly = Polynomial::from_coefficients_vec(t_4_vec); + let t_fourth_poly = Polynomial::from_coefficients_vec(t_fourth_vec); // commit to split quotient polynomial - let t_low_commit = self.commit_key.commit(&t_low_poly)?; - let t_mid_commit = self.commit_key.commit(&t_mid_poly)?; - let t_high_commit = self.commit_key.commit(&t_high_poly)?; - let t_4_commit = self.commit_key.commit(&t_4_poly)?; + let t_low_comm = self.commit_key.commit(&t_low_poly)?; + let t_mid_comm = self.commit_key.commit(&t_mid_poly)?; + let t_high_comm = self.commit_key.commit(&t_high_poly)?; + let t_fourth_comm = self.commit_key.commit(&t_fourth_poly)?; // add quotient polynomial commitments to transcript - transcript.append_commitment(b"t_low", &t_low_commit); - transcript.append_commitment(b"t_mid", &t_mid_commit); - transcript.append_commitment(b"t_high", &t_high_commit); - transcript.append_commitment(b"t_4", &t_4_commit); + transcript.append_commitment(b"t_low_comm", &t_low_comm); + transcript.append_commitment(b"t_mid_comm", &t_mid_comm); + transcript.append_commitment(b"t_high_comm", &t_high_comm); + transcript.append_commitment(b"t_fourth_comm", &t_fourth_comm); // round 4 // compute evaluation challenge 'z' let z_challenge = transcript.challenge_scalar(b"z_challenge"); + // compute opening evaluations + let a_eval = a_poly.evaluate(&z_challenge); + let b_eval = b_poly.evaluate(&z_challenge); + let c_eval = c_poly.evaluate(&z_challenge); + let d_eval = d_poly.evaluate(&z_challenge); + + let s_sigma_1_eval = self + .prover_key + .permutation + .s_sigma_1 + .0 + .evaluate(&z_challenge); + let s_sigma_2_eval = self + .prover_key + .permutation + .s_sigma_2 + .0 + .evaluate(&z_challenge); + let s_sigma_3_eval = self + .prover_key + .permutation + .s_sigma_3 + .0 + .evaluate(&z_challenge); + + let z_eval = z_poly.evaluate(&(z_challenge * domain.group_gen)); + + // add opening evaluations to transcript. + transcript.append_scalar(b"a_eval", &a_eval); + transcript.append_scalar(b"b_eval", &b_eval); + transcript.append_scalar(b"c_eval", &c_eval); + transcript.append_scalar(b"d_eval", &d_eval); + + transcript.append_scalar(b"s_sigma_1_eval", &s_sigma_1_eval); + transcript.append_scalar(b"s_sigma_2_eval", &s_sigma_2_eval); + transcript.append_scalar(b"s_sigma_3_eval", &s_sigma_3_eval); + + transcript.append_scalar(b"z_eval", &z_eval); + + // compute shifted evaluations + let a_w_eval = a_poly.evaluate(&(z_challenge * domain.group_gen)); + let b_w_eval = b_poly.evaluate(&(z_challenge * domain.group_gen)); + let d_w_eval = d_poly.evaluate(&(z_challenge * domain.group_gen)); + + // compute selector evaluations + let q_arith_eval = + self.prover_key.arithmetic.q_arith.0.evaluate(&z_challenge); + let q_c_eval = self.prover_key.logic.q_c.0.evaluate(&z_challenge); + let q_l_eval = self.prover_key.fixed_base.q_l.0.evaluate(&z_challenge); + let q_r_eval = self.prover_key.fixed_base.q_r.0.evaluate(&z_challenge); + + // add shifted evaluations to transcript + transcript.append_scalar(b"a_w_eval", &a_w_eval); + transcript.append_scalar(b"b_w_eval", &b_w_eval); + transcript.append_scalar(b"d_w_eval", &d_w_eval); + + // add selector evaluations to transcript. + transcript.append_scalar(b"q_arith_eval", &q_arith_eval); + transcript.append_scalar(b"q_c_eval", &q_c_eval); + transcript.append_scalar(b"q_l_eval", &q_l_eval); + transcript.append_scalar(b"q_r_eval", &q_r_eval); + + let evaluations = ProofEvaluations { + a_eval, + b_eval, + c_eval, + d_eval, + a_w_eval, + b_w_eval, + d_w_eval, + q_arith_eval, + q_c_eval, + q_l_eval, + q_r_eval, + s_sigma_1_eval, + s_sigma_2_eval, + s_sigma_3_eval, + z_eval, + }; + // round 5 + // compute the challenge 'v' + let v_challenge = transcript.challenge_scalar(b"v_challenge"); + // compute linearization polynomial - let (r_poly, evaluations) = linearization_poly::compute( - &domain, + let r_poly = linearization_poly::compute( &self.prover_key, &( alpha, @@ -409,106 +495,62 @@ impl Prover { var_base_sep_challenge, z_challenge, ), - &a_w_poly, - &b_w_poly, - &o_w_poly, - &d_w_poly, - &t_poly, &z_poly, + &evaluations, + &domain, + &t_low_poly, + &t_mid_poly, + &t_high_poly, + &t_fourth_poly, + &public_inputs, ); - // add evaluations to transcript. - transcript.append_scalar(b"a_eval", &evaluations.proof.a_eval); - transcript.append_scalar(b"b_eval", &evaluations.proof.b_eval); - transcript.append_scalar(b"o_eval", &evaluations.proof.o_eval); - transcript.append_scalar(b"d_eval", &evaluations.proof.d_eval); - transcript - .append_scalar(b"a_next_eval", &evaluations.proof.a_next_eval); - transcript - .append_scalar(b"b_next_eval", &evaluations.proof.b_next_eval); - transcript - .append_scalar(b"d_next_eval", &evaluations.proof.d_next_eval); - transcript.append_scalar( - b"s_sigma_1_eval", - &evaluations.proof.s_sigma_1_eval, - ); - transcript.append_scalar( - b"s_sigma_2_eval", - &evaluations.proof.s_sigma_2_eval, - ); - transcript.append_scalar( - b"s_sigma_3_eval", - &evaluations.proof.s_sigma_3_eval, - ); - transcript - .append_scalar(b"q_arith_eval", &evaluations.proof.q_arith_eval); - transcript.append_scalar(b"q_c_eval", &evaluations.proof.q_c_eval); - transcript.append_scalar(b"q_l_eval", &evaluations.proof.q_l_eval); - transcript.append_scalar(b"q_r_eval", &evaluations.proof.q_r_eval); - transcript.append_scalar(b"perm_eval", &evaluations.proof.perm_eval); - transcript.append_scalar(b"t_eval", &evaluations.t_eval); - transcript.append_scalar(b"r_eval", &evaluations.proof.r_poly_eval); - - // compute Openings using KZG10 - let z_n = z_challenge.pow(&[domain_size as u64, 0, 0, 0]); - let z_two_n = z_challenge.pow(&[2 * domain_size as u64, 0, 0, 0]); - let z_three_n = z_challenge.pow(&[3 * domain_size as u64, 0, 0, 0]); - - let a = &t_low_poly; - let b = &t_mid_poly * &z_n; - let c = &t_high_poly * &z_two_n; - let d = &t_4_poly * &z_three_n; - let abc = &(a + &b) + &c; - - let quot = &abc + &d; - - // compute aggregate witness to polynomials evaluated at the evaluation - // challenge z. The challenge v is selected inside - let aggregate_witness = self.commit_key.compute_aggregate_witness( + // compute the opening proof polynomial 'W_z(X)' + let aggregate_witness = CommitKey::compute_aggregate_witness( &[ - quot, r_poly, - a_w_poly.clone(), - b_w_poly.clone(), - o_w_poly, - d_w_poly.clone(), + a_poly.clone(), + b_poly.clone(), + c_poly, + d_poly.clone(), self.prover_key.permutation.s_sigma_1.0.clone(), self.prover_key.permutation.s_sigma_2.0.clone(), self.prover_key.permutation.s_sigma_3.0.clone(), ], &z_challenge, - &mut transcript, + &v_challenge, ); let w_z_chall_comm = self.commit_key.commit(&aggregate_witness)?; - // compute aggregate witness to polynomials evaluated at the shifted - // evaluation challenge - let shifted_aggregate_witness = - self.commit_key.compute_aggregate_witness( - &[z_poly, a_w_poly, b_w_poly, d_w_poly], - &(z_challenge * domain.group_gen), - &mut transcript, - ); + // compute the shifted challenge 'v_w' + let v_w_challenge = transcript.challenge_scalar(b"v_w_challenge"); + + // compute the shifted opening proof polynomial 'W_zw(X)' + let shifted_aggregate_witness = CommitKey::compute_aggregate_witness( + &[z_poly, a_poly, b_poly, d_poly], + &(z_challenge * domain.group_gen), + &v_w_challenge, + ); let w_z_chall_w_comm = self.commit_key.commit(&shifted_aggregate_witness)?; let proof = Proof { - a_comm: a_w_poly_commit, - b_comm: b_w_poly_commit, - o_comm: o_w_poly_commit, - d_comm: d_w_poly_commit, + a_comm, + b_comm, + c_comm, + d_comm, - z_comm: z_poly_commit, + z_comm, - t_low_comm: t_low_commit, - t_mid_comm: t_mid_commit, - t_high_comm: t_high_commit, - t_4_comm: t_4_commit, + t_low_comm, + t_mid_comm, + t_high_comm, + t_fourth_comm, w_z_chall_comm, w_z_chall_w_comm, - evaluations: evaluations.proof, + evaluations, }; Ok((proof, public_inputs)) diff --git a/src/composer.rs b/src/composer.rs index 6a441d5b..45227ed6 100644 --- a/src/composer.rs +++ b/src/composer.rs @@ -103,16 +103,16 @@ impl Composer { fn append_custom_gate_internal(&mut self, constraint: Constraint) { let n = self.constraints.len(); - let w_a = constraint.witness(WiredWitness::A); - let w_b = constraint.witness(WiredWitness::B); - let w_o = constraint.witness(WiredWitness::O); - let w_d = constraint.witness(WiredWitness::D); + let a = constraint.witness(WiredWitness::A); + let b = constraint.witness(WiredWitness::B); + let c = constraint.witness(WiredWitness::C); + let d = constraint.witness(WiredWitness::D); let q_m = *constraint.coeff(Selector::Multiplication); let q_l = *constraint.coeff(Selector::Left); let q_r = *constraint.coeff(Selector::Right); let q_o = *constraint.coeff(Selector::Output); - let q_4 = *constraint.coeff(Selector::Fourth); + let q_f = *constraint.coeff(Selector::Fourth); let q_c = *constraint.coeff(Selector::Constant); let q_arith = *constraint.coeff(Selector::Arithmetic); @@ -127,17 +127,17 @@ impl Composer { q_l, q_r, q_o, - q_4, + q_f, q_c, q_arith, q_range, q_logic, q_fixed_group_add, q_variable_group_add, - w_a, - w_b, - w_o, - w_d, + a, + b, + c, + d, }; self.constraints.push(gate); @@ -148,7 +148,7 @@ impl Composer { self.public_inputs.insert(n, pi); } - self.perm.add_witnesses_to_map(w_a, w_b, w_o, w_d, n); + self.perm.add_witnesses_to_map(a, b, c, d, n); } /// PLONK runtime controller @@ -204,7 +204,7 @@ impl Composer { .a(six) .b(seven) .d(one) - .o(min_twenty); + .c(min_twenty); self.append_gate(constraint); @@ -218,7 +218,7 @@ impl Composer { .output(1) .a(min_twenty) .b(six) - .o(seven); + .c(seven); self.append_gate(constraint); } @@ -345,7 +345,7 @@ impl Composer { let wit_c = self.append_witness(prod_quad_bls); let wit_d = self.append_witness(out_acc); - constraint = constraint.o(wit_c); + constraint = constraint.c(wit_c); self.append_custom_gate(constraint); @@ -494,7 +494,7 @@ impl Composer { .constant(wnaf_round.xy_beta) .a(wnaf_round.acc_x) .b(wnaf_round.acc_y) - .o(wnaf_round.xy_alpha) + .c(wnaf_round.xy_alpha) .d(wnaf_round.accumulated_bit); self.append_custom_gate(constraint) @@ -528,7 +528,7 @@ impl Composer { /// Append a new width-4 gate/constraint. /// /// The constraint added will enforce the following: - /// `q_m · a · b + q_l · a + q_r · b + q_o · o + q_4 · d + q_c + PI = 0`. + /// `q_M · a · b + q_L · a + q_R · b + q_O · o + q_F · d + q_C + PI = 0`. pub fn append_gate(&mut self, constraint: Constraint) { let constraint = Constraint::arithmetic(&constraint); @@ -553,18 +553,18 @@ impl Composer { let qm = s.coeff(Selector::Multiplication); let ql = s.coeff(Selector::Left); let qr = s.coeff(Selector::Right); - let qd = s.coeff(Selector::Fourth); + let qf = s.coeff(Selector::Fourth); let qc = s.coeff(Selector::Constant); let pi = s.coeff(Selector::PublicInput); - let x = qm * a * b + ql * a + qr * b + qd * d + qc + pi; + let x = qm * a * b + ql * a + qr * b + qf * d + qc + pi; let y = s.coeff(Selector::Output); - // Invert is an expensive operation; in most cases, `qo` is going to be + // Invert is an expensive operation; in most cases, `q_O` is going to be // either 1 or -1, so we can optimize these #[allow(dead_code)] - let o = { + let c = { const ONE: BlsScalar = BlsScalar::one(); const MINUS_ONE: BlsScalar = BlsScalar([ 0xfffffffd00000003, @@ -584,7 +584,7 @@ impl Composer { } }; - o.map(|o| self.append_witness(o)) + c.map(|c| self.append_witness(c)) } /// Constrain a scalar into the circuit description and return an allocated @@ -780,7 +780,7 @@ impl Composer { let y_3 = self.append_witness(y_3); // Add the rest of the prepared points into the composer - let constraint = Constraint::new().a(x_1).b(y_1).o(x_2).d(y_2); + let constraint = Constraint::new().a(x_1).b(y_1).c(x_2).d(y_2); let constraint = Constraint::group_add_variable_base(&constraint); self.append_custom_gate(constraint); @@ -806,7 +806,7 @@ impl Composer { .output(-BlsScalar::one()) .a(a) .b(a) - .o(a) + .c(a) .d(zero); self.append_gate(constraint); @@ -956,7 +956,7 @@ impl Composer { .constant(1) .a(bit) .b(value) - .o(f_x); + .c(f_x); self.append_gate(constraint); @@ -1077,7 +1077,7 @@ impl Composer { let idx = i / 4; let witness = match i % 4 { 0 => WiredWitness::D, - 1 => WiredWitness::O, + 1 => WiredWitness::C, 2 => WiredWitness::B, 3 => WiredWitness::A, _ => unreachable!(), @@ -1117,36 +1117,36 @@ impl Composer { /// Evaluate and return `o` by appending a new constraint into the circuit. /// - /// Set `q_o = (-1)` and override the output of the constraint with: - /// `o := q_l · a + q_r · b + q_4 · d + q_c + PI` + /// Set `q_O = (-1)` and override the output of the constraint with: + /// `c := q_L · a + q_R · b + q_F · d + q_C + PI` pub fn gate_add(&mut self, s: Constraint) -> Witness { let s = Constraint::arithmetic(&s).output(-BlsScalar::one()); - let o = self + let c = self .append_evaluated_output(s) .expect("output selector is -1"); - let s = s.o(o); + let s = s.c(c); self.append_gate(s); - o + c } - /// Evaluate and return `o` by appending a new constraint into the circuit. + /// Evaluate and return `c` by appending a new constraint into the circuit. /// - /// Set `q_o = (-1)` and override the output of the constraint with: - /// `o := q_m · a · b + q_4 · d + q_c + PI` + /// Set `q_O = (-1)` and override the output of the constraint with: + /// `c := q_M · a · b + q_F · d + q_C + PI` pub fn gate_mul(&mut self, s: Constraint) -> Witness { let s = Constraint::arithmetic(&s).output(-BlsScalar::one()); - let o = self + let c = self .append_evaluated_output(s) .expect("output selector is -1"); - let s = s.o(o); + let s = s.c(c); self.append_gate(s); - o + c } /// Prove a circuit with a composer initialized with dummy gates diff --git a/src/composer/compress.rs b/src/composer/compress.rs index 58030296..e442a305 100644 --- a/src/composer/compress.rs +++ b/src/composer/compress.rs @@ -19,10 +19,10 @@ mod hades; )] pub struct CompressedConstraint { pub polynomial: usize, - pub w_a: usize, - pub w_b: usize, - pub w_o: usize, - pub w_d: usize, + pub a: usize, + pub b: usize, + pub c: usize, + pub d: usize, } #[derive( @@ -33,7 +33,7 @@ pub struct CompressedPolynomial { pub q_l: usize, pub q_r: usize, pub q_o: usize, - pub q_4: usize, + pub q_f: usize, pub q_c: usize, pub q_arith: usize, pub q_range: usize, @@ -99,17 +99,17 @@ impl CompressedCircuit { q_l, q_r, q_o, - q_4, + q_f, q_c, q_arith, q_range, q_logic, q_fixed_group_add, q_variable_group_add, - w_a, - w_b, - w_o, - w_d, + a, + b, + c, + d, }| { let len = scalars.len(); let q_m = *scalars.entry(q_m).or_insert(len); @@ -120,7 +120,7 @@ impl CompressedCircuit { let len = scalars.len(); let q_o = *scalars.entry(q_o).or_insert(len); let len = scalars.len(); - let q_4 = *scalars.entry(q_4).or_insert(len); + let q_f = *scalars.entry(q_f).or_insert(len); let len = scalars.len(); let q_c = *scalars.entry(q_c).or_insert(len); let len = scalars.len(); @@ -140,7 +140,7 @@ impl CompressedCircuit { q_l, q_r, q_o, - q_4, + q_f, q_c, q_arith, q_range, @@ -155,10 +155,10 @@ impl CompressedCircuit { CompressedConstraint { polynomial, - w_a: w_a.index(), - w_b: w_b.index(), - w_o: w_o.index(), - w_d: w_d.index(), + a: a.index(), + b: b.index(), + c: c.index(), + d: d.index(), } }, ) @@ -241,10 +241,10 @@ impl CompressedCircuit { i, CompressedConstraint { polynomial, - w_a, - w_b, - w_o, - w_d, + a, + b, + c, + d, }, ) in constraints.into_iter().enumerate() { @@ -253,7 +253,7 @@ impl CompressedCircuit { q_l, q_r, q_o, - q_4, + q_f, q_c, q_arith, q_range, @@ -281,8 +281,8 @@ impl CompressedCircuit { .get(q_o) .copied() .ok_or(Error::InvalidCompressedCircuit)?; - let q_4 = scalars - .get(q_4) + let q_f = scalars + .get(q_f) .copied() .ok_or(Error::InvalidCompressedCircuit)?; let q_c = scalars @@ -310,27 +310,27 @@ impl CompressedCircuit { .copied() .ok_or(Error::InvalidCompressedCircuit)?; - let w_a = Witness::new(w_a); - let w_b = Witness::new(w_b); - let w_o = Witness::new(w_o); - let w_d = Witness::new(w_d); + let a = Witness::new(a); + let b = Witness::new(b); + let c = Witness::new(c); + let d = Witness::new(d); let mut constraint = Constraint::default() .set(Selector::Multiplication, q_m) .set(Selector::Left, q_l) .set(Selector::Right, q_r) .set(Selector::Output, q_o) - .set(Selector::Fourth, q_4) + .set(Selector::Fourth, q_f) .set(Selector::Constant, q_c) .set(Selector::Arithmetic, q_arith) .set(Selector::Range, q_range) .set(Selector::Logic, q_logic) .set(Selector::GroupAddFixedBase, q_fixed_group_add) .set(Selector::GroupAddVariableBase, q_variable_group_add) - .a(w_a) - .b(w_b) - .o(w_o) - .d(w_d); + .a(a) + .b(b) + .c(c) + .d(d); if let Some(idx) = public_inputs.get(pi) { if idx == &i { diff --git a/src/composer/constraint_system/constraint.rs b/src/composer/constraint_system/constraint.rs index 11b6e23f..4f8bb961 100644 --- a/src/composer/constraint_system/constraint.rs +++ b/src/composer/constraint_system/constraint.rs @@ -10,19 +10,19 @@ use dusk_bls12_381::BlsScalar; /// Selectors used to address a coefficient inside of a [`Constraint`] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum Selector { - /// Multiplication coefficient `q_m` + /// Multiplication coefficient `q_M` Multiplication = 0x00, - /// Left coefficient `q_l` + /// Left coefficient `q_L` Left = 0x01, - /// Right coefficient `q_r` + /// Right coefficient `q_R` Right = 0x02, - /// Output coefficient `q_o` + /// Output coefficient `q_O` Output = 0x03, - /// Fourth advice coefficient `q_4` + /// Fourth advice coefficient `q_F` Fourth = 0x04, - /// Constant expression `q_c` + /// Constant expression `q_C` Constant = 0x05, - /// Public input `pi` + /// Public input `PI` PublicInput = 0x06, /// Arithmetic coefficient (internal use) @@ -44,8 +44,8 @@ pub(crate) enum WiredWitness { A = 0x00, /// `B` witness B = 0x01, - /// `O` witness - O = 0x02, + /// `C` witness + C = 0x02, /// `D` witness D = 0x03, } @@ -196,9 +196,9 @@ impl Constraint { self } - /// Set witness `o` wired to `qO` - pub fn o(mut self, w: Witness) -> Self { - self.set_witness(WiredWitness::O, w); + /// Set witness `c` wired to `qO` + pub fn c(mut self, w: Witness) -> Self { + self.set_witness(WiredWitness::C, w); self } diff --git a/src/composer/gate.rs b/src/composer/gate.rs index 31d6dab6..a47069e2 100644 --- a/src/composer/gate.rs +++ b/src/composer/gate.rs @@ -21,7 +21,7 @@ pub struct Gate { /// Output wire selector pub(crate) q_o: BlsScalar, /// Fourth wire selector - pub(crate) q_4: BlsScalar, + pub(crate) q_f: BlsScalar, /// Constant wire selector pub(crate) q_c: BlsScalar, /// Arithmetic wire selector @@ -36,11 +36,11 @@ pub struct Gate { pub(crate) q_variable_group_add: BlsScalar, /// Left wire witness. - pub(crate) w_a: Witness, + pub(crate) a: Witness, /// Right wire witness. - pub(crate) w_b: Witness, + pub(crate) b: Witness, /// Output wire witness. - pub(crate) w_o: Witness, + pub(crate) c: Witness, /// Fourth wire witness. - pub(crate) w_d: Witness, + pub(crate) d: Witness, } diff --git a/src/composer/permutation.rs b/src/composer/permutation.rs index 32f5fc81..f5494c26 100644 --- a/src/composer/permutation.rs +++ b/src/composer/permutation.rs @@ -222,8 +222,8 @@ impl Permutation { // Constants defining cosets H, k1H, k2H, etc let ks = vec![BlsScalar::one(), K1, K2, K3]; - // Transpose wires and sigma values to get "rows" in the form [a_w_i, - // b_w_i, o_w_i, d_w_i] where each row contains the wire and sigma + // Transpose wires and sigma values to get "rows" in the form [a_i, + // b_i, c_i, d_i] where each row contains the wire and sigma // values for a single gate let gatewise_wires = izip!(wires[0], wires[1], wires[2], wires[3]) .map(|(w0, w1, w2, w3)| vec![w0, w1, w2, w3]); @@ -309,10 +309,10 @@ mod test { #[allow(dead_code)] fn compute_fast_permutation_poly( domain: &EvaluationDomain, - a_w: &[BlsScalar], - b_w: &[BlsScalar], - o_w: &[BlsScalar], - d_w: &[BlsScalar], + a: &[BlsScalar], + b: &[BlsScalar], + c: &[BlsScalar], + d: &[BlsScalar], beta: &BlsScalar, gamma: &BlsScalar, (s_sigma_1_poly, s_sigma_2_poly, s_sigma_3_poly, s_sigma_4_poly): ( @@ -356,24 +356,24 @@ mod test { common_roots.iter().map(|x| x * K3).collect(); // Compute left_wire + gamma - let a_w_gamma: Vec<_> = a_w.iter().map(|a_w| a_w + gamma).collect(); + let a_gamma: Vec<_> = a.iter().map(|a| a + gamma).collect(); // Compute right_wire + gamma - let b_w_gamma: Vec<_> = b_w.iter().map(|b_w| b_w + gamma).collect(); + let b_gamma: Vec<_> = b.iter().map(|b| b + gamma).collect(); // Compute out_wire + gamma - let o_w_gamma: Vec<_> = o_w.iter().map(|o_w| o_w + gamma).collect(); + let c_gamma: Vec<_> = c.iter().map(|c| c + gamma).collect(); // Compute fourth_wire + gamma - let d_w_gamma: Vec<_> = d_w.iter().map(|d_w| d_w + gamma).collect(); + let d_gamma: Vec<_> = d.iter().map(|d| d + gamma).collect(); // Compute 6 accumulator components // Parallelizable let accumulator_components_without_l1: Vec<_> = izip!( - a_w_gamma, - b_w_gamma, - o_w_gamma, - d_w_gamma, + a_gamma, + b_gamma, + c_gamma, + d_gamma, common_roots, beta_roots_k1, beta_roots_k2, @@ -385,10 +385,10 @@ mod test { ) .map( |( - a_w_gamma, - b_w_gamma, - o_w_gamma, - d_w_gamma, + a_gamma, + b_gamma, + c_gamma, + d_gamma, beta_root, beta_root_k1, beta_root_k2, @@ -399,28 +399,28 @@ mod test { beta_s_sigma_4, )| { // w_j + beta * root^j-1 + gamma - let ac1 = a_w_gamma + beta_root; + let ac1 = a_gamma + beta_root; // w_{n+j} + beta * K1 * root^j-1 + gamma - let ac2 = b_w_gamma + beta_root_k1; + let ac2 = b_gamma + beta_root_k1; // w_{2n+j} + beta * K2 * root^j-1 + gamma - let ac3 = o_w_gamma + beta_root_k2; + let ac3 = c_gamma + beta_root_k2; // w_{3n+j} + beta * K3 * root^j-1 + gamma - let ac4 = d_w_gamma + beta_root_k3; + let ac4 = d_gamma + beta_root_k3; // 1 / w_j + beta * sigma(j) + gamma - let ac5 = (a_w_gamma + beta_s_sigma_1).invert().unwrap(); + let ac5 = (a_gamma + beta_s_sigma_1).invert().unwrap(); // 1 / w_{n+j} + beta * sigma(n+j) + gamma - let ac6 = (b_w_gamma + beta_s_sigma_2).invert().unwrap(); + let ac6 = (b_gamma + beta_s_sigma_2).invert().unwrap(); // 1 / w_{2n+j} + beta * sigma(2n+j) + gamma - let ac7 = (o_w_gamma + beta_s_sigma_3).invert().unwrap(); + let ac7 = (c_gamma + beta_s_sigma_3).invert().unwrap(); // 1 / w_{3n+j} + beta * sigma(3n+j) + gamma - let ac8 = (d_w_gamma + beta_s_sigma_4).invert().unwrap(); + let ac8 = (d_gamma + beta_s_sigma_4).invert().unwrap(); [ac1, ac2, ac3, ac4, ac5, ac6, ac7, ac8] }, @@ -470,10 +470,10 @@ mod test { fn compute_slow_permutation_poly( domain: &EvaluationDomain, - a_w: I, - b_w: I, - o_w: I, - d_w: I, + a: I, + b: I, + c: I, + d: I, beta: &BlsScalar, gamma: &BlsScalar, (s_sigma_1_poly, s_sigma_2_poly, s_sigma_3_poly, s_sigma_4_poly): ( @@ -516,16 +516,16 @@ mod test { let beta_roots_k3_iter = domain.elements().map(|root| K3 * beta * root); // Compute left_wire + gamma - let a_w_gamma: Vec<_> = a_w.map(|w| w + gamma).collect(); + let a_gamma: Vec<_> = a.map(|w| w + gamma).collect(); // Compute right_wire + gamma - let b_w_gamma: Vec<_> = b_w.map(|w| w + gamma).collect(); + let b_gamma: Vec<_> = b.map(|w| w + gamma).collect(); // Compute out_wire + gamma - let o_w_gamma: Vec<_> = o_w.map(|w| w + gamma).collect(); + let c_gamma: Vec<_> = c.map(|w| w + gamma).collect(); // Compute fourth_wire + gamma - let d_w_gamma: Vec<_> = d_w.map(|w| w + gamma).collect(); + let d_gamma: Vec<_> = d.map(|w| w + gamma).collect(); let mut numerator_partial_components: Vec = Vec::with_capacity(n); @@ -542,35 +542,35 @@ mod test { // Compute numerator coefficients for ( - a_w_gamma, - b_w_gamma, - o_w_gamma, - d_w_gamma, + a_gamma, + b_gamma, + c_gamma, + d_gamma, beta_root, beta_root_k1, beta_root_k2, beta_root_k3, ) in izip!( - a_w_gamma.iter(), - b_w_gamma.iter(), - o_w_gamma.iter(), - d_w_gamma.iter(), + a_gamma.iter(), + b_gamma.iter(), + c_gamma.iter(), + d_gamma.iter(), beta_roots_iter, beta_roots_k1_iter, beta_roots_k2_iter, beta_roots_k3_iter, ) { - // (a_w + beta * root + gamma) - let prod_a = beta_root + a_w_gamma; + // (a + beta * root + gamma) + let prod_a = beta_root + a_gamma; - // (b_w + beta * root * k_1 + gamma) - let prod_b = beta_root_k1 + b_w_gamma; + // (b + beta * root * k_1 + gamma) + let prod_b = beta_root_k1 + b_gamma; - // (o_w + beta * root * k_2 + gamma) - let prod_c = beta_root_k2 + o_w_gamma; + // (c + beta * root * k_2 + gamma) + let prod_c = beta_root_k2 + c_gamma; - // (d_w + beta * root * k_3 + gamma) - let prod_d = beta_root_k3 + d_w_gamma; + // (d + beta * root * k_3 + gamma) + let prod_d = beta_root_k3 + d_gamma; let mut prod = prod_a * prod_b * prod_c * prod_d; @@ -583,35 +583,35 @@ mod test { // Compute denominator coefficients for ( - a_w_gamma, - b_w_gamma, - o_w_gamma, - d_w_gamma, + a_gamma, + b_gamma, + c_gamma, + d_gamma, beta_s_sigma_1, beta_s_sigma_2, beta_s_sigma_3, beta_s_sigma_4, ) in izip!( - a_w_gamma, - b_w_gamma, - o_w_gamma, - d_w_gamma, + a_gamma, + b_gamma, + c_gamma, + d_gamma, beta_s_sigma_1_iter, beta_s_sigma_2_iter, beta_s_sigma_3_iter, beta_s_sigma_4_iter, ) { - // (a_w + beta * s_sigma_1 + gamma) - let prod_a = beta_s_sigma_1 + a_w_gamma; + // (a + beta * s_sigma_1 + gamma) + let prod_a = beta_s_sigma_1 + a_gamma; - // (b_w + beta * s_sigma_2 + gamma) - let prod_b = beta_s_sigma_2 + b_w_gamma; + // (b + beta * s_sigma_2 + gamma) + let prod_b = beta_s_sigma_2 + b_gamma; - // (o_w + beta * s_sigma_3 + gamma) - let prod_c = beta_s_sigma_3 + o_w_gamma; + // (c + beta * s_sigma_3 + gamma) + let prod_c = beta_s_sigma_3 + c_gamma; - // (d_w + beta * s_sigma_4 + gamma) - let prod_d = beta_s_sigma_4 + d_w_gamma; + // (d + beta * s_sigma_4 + gamma) + let prod_d = beta_s_sigma_4 + d_gamma; let mut prod = prod_a * prod_b * prod_c * prod_d; @@ -797,25 +797,25 @@ mod test { assert_eq!(encoded_s_sigma_4[2], w_cubed * K3); assert_eq!(encoded_s_sigma_4[3], K3); - let a_w = vec![ + let a = vec![ BlsScalar::from(2), BlsScalar::from(2), BlsScalar::from(2), BlsScalar::from(2), ]; - let b_w = vec![ + let b = vec![ BlsScalar::from(2), BlsScalar::one(), BlsScalar::one(), BlsScalar::one(), ]; - let o_w = vec![ + let c = vec![ BlsScalar::one(), BlsScalar::one(), BlsScalar::one(), BlsScalar::one(), ]; - let d_w = vec![ + let d = vec![ BlsScalar::one(), BlsScalar::one(), BlsScalar::one(), @@ -826,10 +826,10 @@ mod test { num_wire_mappings, perm, &domain, - a_w, - b_w, - o_w, - d_w, + a, + b, + c, + d, ); } @@ -953,19 +953,19 @@ mod test { perm.add_witnesses_to_map(var_one, var_two, var_three, var_four, 0); perm.add_witnesses_to_map(var_three, var_two, var_one, var_four, 1); - let a_w: Vec<_> = vec![BlsScalar::one(), BlsScalar::from(3)]; - let b_w: Vec<_> = vec![BlsScalar::from(2), BlsScalar::from(2)]; - let o_w: Vec<_> = vec![BlsScalar::from(3), BlsScalar::one()]; - let d_w: Vec<_> = vec![BlsScalar::one(), BlsScalar::one()]; + let a: Vec<_> = vec![BlsScalar::one(), BlsScalar::from(3)]; + let b: Vec<_> = vec![BlsScalar::from(2), BlsScalar::from(2)]; + let c: Vec<_> = vec![BlsScalar::from(3), BlsScalar::one()]; + let d: Vec<_> = vec![BlsScalar::one(), BlsScalar::one()]; test_correct_permutation_poly( num_wire_mappings, perm, &domain, - a_w, - b_w, - o_w, - d_w, + a, + b, + c, + d, ); } @@ -981,10 +981,10 @@ mod test { n: usize, mut perm: Permutation, domain: &EvaluationDomain, - a_w: Vec, - b_w: Vec, - o_w: Vec, - d_w: Vec, + a: Vec, + b: Vec, + c: Vec, + d: Vec, ) { // 0. Generate beta and gamma challenges // @@ -998,10 +998,10 @@ mod test { let (z_vec, numerator_components, denominator_components) = compute_slow_permutation_poly( domain, - a_w.clone().into_iter(), - b_w.clone().into_iter(), - o_w.clone().into_iter(), - d_w.clone().into_iter(), + a.clone().into_iter(), + b.clone().into_iter(), + c.clone().into_iter(), + d.clone().into_iter(), &beta, &gamma, ( @@ -1014,10 +1014,10 @@ mod test { let fast_z_vec = compute_fast_permutation_poly( domain, - &a_w, - &b_w, - &o_w, - &d_w, + &a, + &b, + &c, + &d, &beta, &gamma, ( diff --git a/src/debugger.rs b/src/debugger.rs index 5131e35d..c426cc33 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -80,89 +80,90 @@ impl Debugger { EncodableWitness::new(id, None, value, source) }); - let constraints = - self.constraints - .iter() - .enumerate() - .map(|(id, (source, c))| { - let source = source.clone(); - - let qm = c.coeff(Selector::Multiplication); - let ql = c.coeff(Selector::Left); - let qr = c.coeff(Selector::Right); - let qd = c.coeff(Selector::Fourth); - let qc = c.coeff(Selector::Constant); - let qo = c.coeff(Selector::Output); - let pi = c.coeff(Selector::PublicInput); - let qarith = c.coeff(Selector::Arithmetic); - let qlogic = c.coeff(Selector::Logic); - let qrange = c.coeff(Selector::Range); - let qgroup_variable = - c.coeff(Selector::GroupAddVariableBase); - let qfixed_add = c.coeff(Selector::GroupAddFixedBase); - - let witnesses = WiredWitnesses { - a: c.witness(WiredWitness::A).index(), - b: c.witness(WiredWitness::B).index(), - d: c.witness(WiredWitness::D).index(), - o: c.witness(WiredWitness::O).index(), - }; - - let wa = self - .witnesses - .get(witnesses.a) - .map(|(_, _, v)| *v) - .unwrap_or_default(); - - let wb = self - .witnesses - .get(witnesses.b) - .map(|(_, _, v)| *v) - .unwrap_or_default(); - - let wd = self - .witnesses - .get(witnesses.d) - .map(|(_, _, v)| *v) - .unwrap_or_default(); - - let wo = self - .witnesses - .get(witnesses.o) - .map(|(_, _, v)| *v) - .unwrap_or_default(); - - // TODO check arith, range, logic & ecc wires - let evaluation = qm * wa * wb - + ql * wa - + qr * wb - + qd * wd - + qo * wo - + qc - + pi; - - let evaluation = evaluation == BlsScalar::zero(); - - let selectors = Selectors { - qm: qm.to_bytes().into(), - ql: ql.to_bytes().into(), - qr: qr.to_bytes().into(), - qd: qd.to_bytes().into(), - qc: qc.to_bytes().into(), - qo: qo.to_bytes().into(), - pi: pi.to_bytes().into(), - qarith: qarith.to_bytes().into(), - qlogic: qlogic.to_bytes().into(), - qrange: qrange.to_bytes().into(), - qgroup_variable: qgroup_variable.to_bytes().into(), - qfixed_add: qfixed_add.to_bytes().into(), - }; - - let polynomial = - Polynomial::new(selectors, witnesses, evaluation); - - EncodableConstraint::new(id, polynomial, source) - }); + let constraints = self.constraints.iter().enumerate().map( + |(id, (source, constraint))| { + let source = source.clone(); + + let qm = constraint.coeff(Selector::Multiplication); + let ql = constraint.coeff(Selector::Left); + let qr = constraint.coeff(Selector::Right); + let qo = constraint.coeff(Selector::Output); + let qf = constraint.coeff(Selector::Fourth); + let qc = constraint.coeff(Selector::Constant); + let pi = constraint.coeff(Selector::PublicInput); + let qarith = constraint.coeff(Selector::Arithmetic); + let qlogic = constraint.coeff(Selector::Logic); + let qrange = constraint.coeff(Selector::Range); + let qgroup_variable = + constraint.coeff(Selector::GroupAddVariableBase); + let qfixed_add = constraint.coeff(Selector::GroupAddFixedBase); + + let witnesses = WiredWitnesses { + a: constraint.witness(WiredWitness::A).index(), + b: constraint.witness(WiredWitness::B).index(), + // TODO: change by 'c' in debugger crate + o: constraint.witness(WiredWitness::C).index(), + d: constraint.witness(WiredWitness::D).index(), + }; + + let wa = self + .witnesses + .get(witnesses.a) + .map(|(_, _, v)| *v) + .unwrap_or_default(); + + let wb = self + .witnesses + .get(witnesses.b) + .map(|(_, _, v)| *v) + .unwrap_or_default(); + + let wc = self + .witnesses + // TODO: change by 'c' in debugger crate + .get(witnesses.o) + .map(|(_, _, v)| *v) + .unwrap_or_default(); + + let wd = self + .witnesses + .get(witnesses.d) + .map(|(_, _, v)| *v) + .unwrap_or_default(); + + // TODO check arith, range, logic & ecc wires + let evaluation = qm * wa * wb + + ql * wa + + qr * wb + + qo * wc + + qf * wd + + qc + + pi; + + let evaluation = evaluation == BlsScalar::zero(); + + let selectors = Selectors { + qm: qm.to_bytes().into(), + ql: ql.to_bytes().into(), + qr: qr.to_bytes().into(), + qo: qo.to_bytes().into(), + // TODO: change by 'qf' in debugger crate + qd: qf.to_bytes().into(), + qc: qc.to_bytes().into(), + pi: pi.to_bytes().into(), + qarith: qarith.to_bytes().into(), + qlogic: qlogic.to_bytes().into(), + qrange: qrange.to_bytes().into(), + qgroup_variable: qgroup_variable.to_bytes().into(), + qfixed_add: qfixed_add.to_bytes().into(), + }; + + let polynomial = + Polynomial::new(selectors, witnesses, evaluation); + + EncodableConstraint::new(id, polynomial, source) + }, + ); if let Err(e) = Config::load() .and_then(|config| { diff --git a/src/fft/polynomial.rs b/src/fft/polynomial.rs index 68fdfb7b..e718ffe5 100644 --- a/src/fft/polynomial.rs +++ b/src/fft/polynomial.rs @@ -128,7 +128,7 @@ impl Polynomial { let powers = util::powers_of(value, self.len()); // Multiply the powers of the value by the coefficients - let mul_coeff = self.iter().zip(powers.into_iter()).map(|(c, p)| p * c); + let mul_coeff = self.iter().zip(powers).map(|(c, p)| p * c); // Sum it all up let mut sum = BlsScalar::zero(); diff --git a/src/proof_system/linearization_poly.rs b/src/proof_system/linearization_poly.rs index 03f9cc3a..7d095a35 100644 --- a/src/proof_system/linearization_poly.rs +++ b/src/proof_system/linearization_poly.rs @@ -7,7 +7,7 @@ #[cfg(feature = "alloc")] use crate::{ fft::{EvaluationDomain, Polynomial}, - proof_system::ProverKey, + proof_system::{proof, ProverKey}, }; use dusk_bls12_381::BlsScalar; @@ -21,14 +21,6 @@ use rkyv::{ Archive, Deserialize, Serialize, }; -/// Evaluations at points `z` or and `z * root of unity` -#[allow(dead_code)] -pub(crate) struct Evaluations { - pub(crate) proof: ProofEvaluations, - // Evaluation of the linearization sigma polynomial at `z` - pub(crate) t_eval: BlsScalar, -} - /// Subset of all of the evaluations. These evaluations /// are added to the [`Proof`](super::Proof). #[derive(Debug, Eq, PartialEq, Clone, Default)] @@ -47,20 +39,20 @@ pub(crate) struct ProofEvaluations { pub(crate) b_eval: BlsScalar, // Evaluation of the witness polynomial for the output wire at `z` #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) o_eval: BlsScalar, + pub(crate) c_eval: BlsScalar, // Evaluation of the witness polynomial for the fourth wire at `z` #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub(crate) d_eval: BlsScalar, // #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) a_next_eval: BlsScalar, + pub(crate) a_w_eval: BlsScalar, // #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) b_next_eval: BlsScalar, + pub(crate) b_w_eval: BlsScalar, // Evaluation of the witness polynomial for the fourth wire at `z * root of // unity` #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) d_next_eval: BlsScalar, + pub(crate) d_w_eval: BlsScalar, // Evaluation of the arithmetic selector polynomial at `z` #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub(crate) q_arith_eval: BlsScalar, @@ -84,18 +76,14 @@ pub(crate) struct ProofEvaluations { #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub(crate) s_sigma_3_eval: BlsScalar, - // Evaluation of the linearization sigma polynomial at `z` - #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) r_poly_eval: BlsScalar, - // (Shifted) Evaluation of the permutation polynomial at `z * root of // unity` #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) perm_eval: BlsScalar, + pub(crate) z_eval: BlsScalar, } -// The struct ProofEvaluations has 16 BlsScalars -impl Serializable<{ 16 * BlsScalar::SIZE }> for ProofEvaluations { +// The struct ProofEvaluations has 15 BlsScalars +impl Serializable<{ 15 * BlsScalar::SIZE }> for ProofEvaluations { type Error = dusk_bytes::Error; #[allow(unused_must_use)] @@ -106,11 +94,11 @@ impl Serializable<{ 16 * BlsScalar::SIZE }> for ProofEvaluations { let mut writer = &mut buf[..]; writer.write(&self.a_eval.to_bytes()); writer.write(&self.b_eval.to_bytes()); - writer.write(&self.o_eval.to_bytes()); + writer.write(&self.c_eval.to_bytes()); writer.write(&self.d_eval.to_bytes()); - writer.write(&self.a_next_eval.to_bytes()); - writer.write(&self.b_next_eval.to_bytes()); - writer.write(&self.d_next_eval.to_bytes()); + writer.write(&self.a_w_eval.to_bytes()); + writer.write(&self.b_w_eval.to_bytes()); + writer.write(&self.d_w_eval.to_bytes()); writer.write(&self.q_arith_eval.to_bytes()); writer.write(&self.q_c_eval.to_bytes()); writer.write(&self.q_l_eval.to_bytes()); @@ -118,8 +106,7 @@ impl Serializable<{ 16 * BlsScalar::SIZE }> for ProofEvaluations { writer.write(&self.s_sigma_1_eval.to_bytes()); writer.write(&self.s_sigma_2_eval.to_bytes()); writer.write(&self.s_sigma_3_eval.to_bytes()); - writer.write(&self.r_poly_eval.to_bytes()); - writer.write(&self.perm_eval.to_bytes()); + writer.write(&self.z_eval.to_bytes()); buf } @@ -130,11 +117,11 @@ impl Serializable<{ 16 * BlsScalar::SIZE }> for ProofEvaluations { let mut buffer = &buf[..]; let a_eval = BlsScalar::from_reader(&mut buffer)?; let b_eval = BlsScalar::from_reader(&mut buffer)?; - let o_eval = BlsScalar::from_reader(&mut buffer)?; + let c_eval = BlsScalar::from_reader(&mut buffer)?; let d_eval = BlsScalar::from_reader(&mut buffer)?; - let a_next_eval = BlsScalar::from_reader(&mut buffer)?; - let b_next_eval = BlsScalar::from_reader(&mut buffer)?; - let d_next_eval = BlsScalar::from_reader(&mut buffer)?; + let a_w_eval = BlsScalar::from_reader(&mut buffer)?; + let b_w_eval = BlsScalar::from_reader(&mut buffer)?; + let d_w_eval = BlsScalar::from_reader(&mut buffer)?; let q_arith_eval = BlsScalar::from_reader(&mut buffer)?; let q_c_eval = BlsScalar::from_reader(&mut buffer)?; let q_l_eval = BlsScalar::from_reader(&mut buffer)?; @@ -142,17 +129,16 @@ impl Serializable<{ 16 * BlsScalar::SIZE }> for ProofEvaluations { let s_sigma_1_eval = BlsScalar::from_reader(&mut buffer)?; let s_sigma_2_eval = BlsScalar::from_reader(&mut buffer)?; let s_sigma_3_eval = BlsScalar::from_reader(&mut buffer)?; - let r_poly_eval = BlsScalar::from_reader(&mut buffer)?; - let perm_eval = BlsScalar::from_reader(&mut buffer)?; + let z_eval = BlsScalar::from_reader(&mut buffer)?; Ok(ProofEvaluations { a_eval, b_eval, - o_eval, + c_eval, d_eval, - a_next_eval, - b_next_eval, - d_next_eval, + a_w_eval, + b_w_eval, + d_w_eval, q_arith_eval, q_c_eval, q_l_eval, @@ -160,8 +146,7 @@ impl Serializable<{ 16 * BlsScalar::SIZE }> for ProofEvaluations { s_sigma_1_eval, s_sigma_2_eval, s_sigma_3_eval, - r_poly_eval, - perm_eval, + z_eval, }) } } @@ -172,7 +157,6 @@ impl Serializable<{ 16 * BlsScalar::SIZE }> for ProofEvaluations { // TODO: Improve the method signature #[allow(clippy::type_complexity)] pub(crate) fn compute( - domain: &EvaluationDomain, prover_key: &ProverKey, ( alpha, @@ -193,37 +177,15 @@ pub(crate) fn compute( BlsScalar, BlsScalar, ), - a_w_poly: &Polynomial, - b_w_poly: &Polynomial, - o_w_poly: &Polynomial, - d_w_poly: &Polynomial, - t_x_poly: &Polynomial, z_poly: &Polynomial, -) -> (Polynomial, Evaluations) { - // Compute evaluations - let t_eval = t_x_poly.evaluate(z_challenge); - let a_eval = a_w_poly.evaluate(z_challenge); - let b_eval = b_w_poly.evaluate(z_challenge); - let o_eval = o_w_poly.evaluate(z_challenge); - let d_eval = d_w_poly.evaluate(z_challenge); - - let s_sigma_1_eval = - prover_key.permutation.s_sigma_1.0.evaluate(z_challenge); - let s_sigma_2_eval = - prover_key.permutation.s_sigma_2.0.evaluate(z_challenge); - let s_sigma_3_eval = - prover_key.permutation.s_sigma_3.0.evaluate(z_challenge); - - let q_arith_eval = prover_key.arithmetic.q_arith.0.evaluate(z_challenge); - let q_c_eval = prover_key.logic.q_c.0.evaluate(z_challenge); - let q_l_eval = prover_key.fixed_base.q_l.0.evaluate(z_challenge); - let q_r_eval = prover_key.fixed_base.q_r.0.evaluate(z_challenge); - - let a_next_eval = a_w_poly.evaluate(&(z_challenge * domain.group_gen)); - let b_next_eval = b_w_poly.evaluate(&(z_challenge * domain.group_gen)); - let d_next_eval = d_w_poly.evaluate(&(z_challenge * domain.group_gen)); - let perm_eval = z_poly.evaluate(&(z_challenge * domain.group_gen)); - + evaluations: &ProofEvaluations, + domain: &EvaluationDomain, + t_low_poly: &Polynomial, + t_mid_poly: &Polynomial, + t_high_poly: &Polynomial, + t_fourth_poly: &Polynomial, + pub_inputs: &[BlsScalar], +) -> Polynomial { let f_1 = compute_circuit_satisfiability( ( range_separation_challenge, @@ -231,58 +193,55 @@ pub(crate) fn compute( fixed_base_separation_challenge, var_base_separation_challenge, ), - &a_eval, - &b_eval, - &o_eval, - &d_eval, - &a_next_eval, - &b_next_eval, - &d_next_eval, - &q_arith_eval, - &q_c_eval, - &q_l_eval, - &q_r_eval, + evaluations, prover_key, ); + let pi_eval = + proof::alloc::compute_barycentric_eval(pub_inputs, z_challenge, domain); + + let f_1 = &f_1 + &pi_eval; + let f_2 = prover_key.permutation.compute_linearization( z_challenge, (alpha, beta, gamma), - (&a_eval, &b_eval, &o_eval, &d_eval), - (&s_sigma_1_eval, &s_sigma_2_eval, &s_sigma_3_eval), - &perm_eval, + ( + &evaluations.a_eval, + &evaluations.b_eval, + &evaluations.c_eval, + &evaluations.d_eval, + ), + ( + &evaluations.s_sigma_1_eval, + &evaluations.s_sigma_2_eval, + &evaluations.s_sigma_3_eval, + ), + &evaluations.z_eval, z_poly, ); - let r_poly = &f_1 + &f_2; + let domain_size = domain.size(); - // Evaluate linearization polynomial at challenge `z` - let r_poly_eval = r_poly.evaluate(z_challenge); + let z_n = z_challenge.pow(&[domain_size as u64, 0, 0, 0]); + let z_two_n = z_challenge.pow(&[2 * domain_size as u64, 0, 0, 0]); + let z_three_n = z_challenge.pow(&[3 * domain_size as u64, 0, 0, 0]); - ( - r_poly, - Evaluations { - proof: ProofEvaluations { - a_eval, - b_eval, - o_eval, - d_eval, - a_next_eval, - b_next_eval, - d_next_eval, - q_arith_eval, - q_c_eval, - q_l_eval, - q_r_eval, - s_sigma_1_eval, - s_sigma_2_eval, - s_sigma_3_eval, - r_poly_eval, - perm_eval, - }, - t_eval, - }, - ) + let a = t_low_poly; + let b = t_mid_poly * &z_n; + let c = t_high_poly * &z_two_n; + let d = t_fourth_poly * &z_three_n; + let abc = &(a + &b) + &c; + + let quot = &abc + &d; + + let z_h_eval = -domain.evaluate_vanishing_polynomial(z_challenge); + + let quot = " * &z_h_eval; + + let f = &f_1 + &f_2; + + // r_poly + &f + " } #[cfg(feature = "alloc")] @@ -293,72 +252,26 @@ fn compute_circuit_satisfiability( fixed_base_separation_challenge, var_base_separation_challenge, ): (&BlsScalar, &BlsScalar, &BlsScalar, &BlsScalar), - a_eval: &BlsScalar, - b_eval: &BlsScalar, - o_eval: &BlsScalar, - d_eval: &BlsScalar, - a_next_eval: &BlsScalar, - b_next_eval: &BlsScalar, - d_next_eval: &BlsScalar, - q_arith_eval: &BlsScalar, - q_c_eval: &BlsScalar, - q_l_eval: &BlsScalar, - q_r_eval: &BlsScalar, + evaluations: &ProofEvaluations, prover_key: &ProverKey, ) -> Polynomial { - let a = prover_key.arithmetic.compute_linearization( - a_eval, - b_eval, - o_eval, - d_eval, - q_arith_eval, - ); + let a = prover_key.arithmetic.compute_linearization(evaluations); - let b = prover_key.range.compute_linearization( - range_separation_challenge, - a_eval, - b_eval, - o_eval, - d_eval, - d_next_eval, - ); + let b = prover_key + .range + .compute_linearization(range_separation_challenge, evaluations); - let c = prover_key.logic.compute_linearization( - logic_separation_challenge, - a_eval, - a_next_eval, - b_eval, - b_next_eval, - o_eval, - d_eval, - d_next_eval, - q_c_eval, - ); + let c = prover_key + .logic + .compute_linearization(logic_separation_challenge, evaluations); - let d = prover_key.fixed_base.compute_linearization( - fixed_base_separation_challenge, - a_eval, - a_next_eval, - b_eval, - b_next_eval, - o_eval, - d_eval, - d_next_eval, - q_l_eval, - q_r_eval, - q_c_eval, - ); + let d = prover_key + .fixed_base + .compute_linearization(fixed_base_separation_challenge, evaluations); - let e = prover_key.variable_base.compute_linearization( - var_base_separation_challenge, - a_eval, - a_next_eval, - b_eval, - b_next_eval, - o_eval, - d_eval, - d_next_eval, - ); + let e = prover_key + .variable_base + .compute_linearization(var_base_separation_challenge, evaluations); let mut linearization_poly = &a + &b; linearization_poly += &c; diff --git a/src/proof_system/preprocess.rs b/src/proof_system/preprocess.rs index 91560f80..72c8a34c 100644 --- a/src/proof_system/preprocess.rs +++ b/src/proof_system/preprocess.rs @@ -15,12 +15,9 @@ pub(crate) struct Polynomials { pub(crate) q_l: Polynomial, pub(crate) q_r: Polynomial, pub(crate) q_o: Polynomial, + pub(crate) q_f: Polynomial, // for 3-input gates pub(crate) q_c: Polynomial, - // additional selector for 3-input gates added for efficiency of - // implementation - pub(crate) q_4: Polynomial, - // additional selectors for different kinds of circuits added for // efficiency of implementation pub(crate) q_arith: Polynomial, // arithmetic circuits @@ -33,5 +30,5 @@ pub(crate) struct Polynomials { pub(crate) s_sigma_1: Polynomial, pub(crate) s_sigma_2: Polynomial, pub(crate) s_sigma_3: Polynomial, - pub(crate) s_sigma_4: Polynomial, // for q_4 + pub(crate) s_sigma_4: Polynomial, // for q_F } diff --git a/src/proof_system/proof.rs b/src/proof_system/proof.rs index da7036a9..e434eb28 100644 --- a/src/proof_system/proof.rs +++ b/src/proof_system/proof.rs @@ -12,6 +12,11 @@ use crate::commitment_scheme::Commitment; use dusk_bytes::{DeserializableSlice, Serializable}; +#[cfg(feature = "std")] +use rayon::prelude::*; + +const V_MAX_DEGREE: usize = 7; + #[cfg(feature = "rkyv-impl")] use crate::util::check_field; #[cfg(feature = "rkyv-impl")] @@ -49,7 +54,7 @@ pub struct Proof { pub(crate) b_comm: Commitment, /// Commitment to the witness polynomial for the output wires. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) o_comm: Commitment, + pub(crate) c_comm: Commitment, /// Commitment to the witness polynomial for the fourth wires. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub(crate) d_comm: Commitment, @@ -69,7 +74,7 @@ pub struct Proof { pub(crate) t_high_comm: Commitment, /// Commitment to the quotient polynomial. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub(crate) t_4_comm: Commitment, + pub(crate) t_fourth_comm: Commitment, /// Commitment to the opening polynomial. #[cfg_attr(feature = "rkyv-impl", omit_bounds)] @@ -92,7 +97,7 @@ impl CheckBytes for ArchivedProof { ) -> Result<&'a Self, Self::Error> { check_field(&(*value).a_comm, context, "a_comm")?; check_field(&(*value).b_comm, context, "b_comm")?; - check_field(&(*value).o_comm, context, "o_comm")?; + check_field(&(*value).c_comm, context, "c_comm")?; check_field(&(*value).d_comm, context, "d_comm")?; check_field(&(*value).z_comm, context, "z_comm")?; @@ -100,7 +105,7 @@ impl CheckBytes for ArchivedProof { check_field(&(*value).t_low_comm, context, "t_low_comm")?; check_field(&(*value).t_mid_comm, context, "t_mid_comm")?; check_field(&(*value).t_high_comm, context, "t_high_comm")?; - check_field(&(*value).t_4_comm, context, "t_4_comm")?; + check_field(&(*value).t_fourth_comm, context, "t_fourth_comm")?; check_field(&(*value).w_z_chall_comm, context, "w_z_chall_comm")?; check_field(&(*value).w_z_chall_w_comm, context, "w_z_chall_w_comm")?; @@ -124,13 +129,13 @@ impl Serializable<{ 11 * Commitment::SIZE + ProofEvaluations::SIZE }> let mut writer = &mut buf[..]; writer.write(&self.a_comm.to_bytes()); writer.write(&self.b_comm.to_bytes()); - writer.write(&self.o_comm.to_bytes()); + writer.write(&self.c_comm.to_bytes()); writer.write(&self.d_comm.to_bytes()); writer.write(&self.z_comm.to_bytes()); writer.write(&self.t_low_comm.to_bytes()); writer.write(&self.t_mid_comm.to_bytes()); writer.write(&self.t_high_comm.to_bytes()); - writer.write(&self.t_4_comm.to_bytes()); + writer.write(&self.t_fourth_comm.to_bytes()); writer.write(&self.w_z_chall_comm.to_bytes()); writer.write(&self.w_z_chall_w_comm.to_bytes()); writer.write(&self.evaluations.to_bytes()); @@ -143,13 +148,13 @@ impl Serializable<{ 11 * Commitment::SIZE + ProofEvaluations::SIZE }> let a_comm = Commitment::from_reader(&mut buffer)?; let b_comm = Commitment::from_reader(&mut buffer)?; - let o_comm = Commitment::from_reader(&mut buffer)?; + let c_comm = Commitment::from_reader(&mut buffer)?; let d_comm = Commitment::from_reader(&mut buffer)?; let z_comm = Commitment::from_reader(&mut buffer)?; let t_low_comm = Commitment::from_reader(&mut buffer)?; let t_mid_comm = Commitment::from_reader(&mut buffer)?; let t_high_comm = Commitment::from_reader(&mut buffer)?; - let t_4_comm = Commitment::from_reader(&mut buffer)?; + let t_fourth_comm = Commitment::from_reader(&mut buffer)?; let w_z_chall_comm = Commitment::from_reader(&mut buffer)?; let w_z_chall_w_comm = Commitment::from_reader(&mut buffer)?; let evaluations = ProofEvaluations::from_reader(&mut buffer)?; @@ -157,13 +162,13 @@ impl Serializable<{ 11 * Commitment::SIZE + ProofEvaluations::SIZE }> Ok(Proof { a_comm, b_comm, - o_comm, + c_comm, d_comm, z_comm, t_low_comm, t_mid_comm, t_high_comm, - t_4_comm, + t_fourth_comm, w_z_chall_comm, w_z_chall_w_comm, evaluations, @@ -172,6 +177,7 @@ impl Serializable<{ 11 * Commitment::SIZE + ProofEvaluations::SIZE }> } #[cfg(feature = "alloc")] +#[allow(unused_imports)] pub(crate) mod alloc { use super::*; use crate::{ @@ -185,7 +191,7 @@ pub(crate) mod alloc { #[rustfmt::skip] use ::alloc::vec::Vec; use dusk_bls12_381::{ - multiscalar_mul::msm_variable_base, BlsScalar, G1Affine, + multiscalar_mul::msm_variable_base, BlsScalar, G1Affine, G1Projective, }; use merlin::Transcript; #[cfg(feature = "std")] @@ -193,6 +199,7 @@ pub(crate) mod alloc { impl Proof { /// Performs the verification of a [`Proof`] returning a boolean result. + #[allow(non_snake_case)] pub(crate) fn verify( &self, verifier_key: &VerifierKey, @@ -212,10 +219,10 @@ pub(crate) mod alloc { // same challenges // // Add commitment to witness polynomials to transcript - transcript.append_commitment(b"a_w", &self.a_comm); - transcript.append_commitment(b"b_w", &self.b_comm); - transcript.append_commitment(b"o_w", &self.o_comm); - transcript.append_commitment(b"d_w", &self.d_comm); + transcript.append_commitment(b"a_comm", &self.a_comm); + transcript.append_commitment(b"b_comm", &self.b_comm); + transcript.append_commitment(b"c_comm", &self.c_comm); + transcript.append_commitment(b"d_comm", &self.d_comm); // Compute beta and gamma challenges let beta = transcript.challenge_scalar(b"beta"); @@ -223,7 +230,7 @@ pub(crate) mod alloc { let gamma = transcript.challenge_scalar(b"gamma"); // Add commitment to permutation polynomial to transcript - transcript.append_commitment(b"z", &self.z_comm); + transcript.append_commitment(b"z_comm", &self.z_comm); // Compute quotient challenge let alpha = transcript.challenge_scalar(b"alpha"); @@ -237,54 +244,20 @@ pub(crate) mod alloc { .challenge_scalar(b"variable base separation challenge"); // Add commitment to quotient polynomial to transcript - transcript.append_commitment(b"t_low", &self.t_low_comm); - transcript.append_commitment(b"t_mid", &self.t_mid_comm); - transcript.append_commitment(b"t_high", &self.t_high_comm); - transcript.append_commitment(b"t_4", &self.t_4_comm); + transcript.append_commitment(b"t_low_comm", &self.t_low_comm); + transcript.append_commitment(b"t_mid_comm", &self.t_mid_comm); + transcript.append_commitment(b"t_high_comm", &self.t_high_comm); + transcript.append_commitment(b"t_fourth_comm", &self.t_fourth_comm); // Compute evaluation challenge z let z_challenge = transcript.challenge_scalar(b"z_challenge"); - // Compute zero polynomial evaluated at challenge `z` - let z_h_eval = domain.evaluate_vanishing_polynomial(&z_challenge); - - // Compute first lagrange polynomial evaluated at challenge `z` - let l1_eval = compute_first_lagrange_evaluation( - &domain, - &z_h_eval, - &z_challenge, - ); - - // Compute quotient polynomial evaluated at challenge `z` - let t_eval = self.compute_quotient_evaluation( - &domain, - pub_inputs, - &alpha, - &beta, - &gamma, - &z_challenge, - &z_h_eval, - &l1_eval, - &self.evaluations.perm_eval, - ); - - // Compute commitment to quotient polynomial - // This method is necessary as we pass the `un-splitted` variation - // to our commitment scheme - let t_comm = - self.compute_quotient_commitment(&z_challenge, domain.size()); - - // Add evaluations to transcript + // Add opening evaluations to transcript transcript.append_scalar(b"a_eval", &self.evaluations.a_eval); transcript.append_scalar(b"b_eval", &self.evaluations.b_eval); - transcript.append_scalar(b"o_eval", &self.evaluations.o_eval); + transcript.append_scalar(b"c_eval", &self.evaluations.c_eval); transcript.append_scalar(b"d_eval", &self.evaluations.d_eval); - transcript - .append_scalar(b"a_next_eval", &self.evaluations.a_next_eval); - transcript - .append_scalar(b"b_next_eval", &self.evaluations.b_next_eval); - transcript - .append_scalar(b"d_next_eval", &self.evaluations.d_next_eval); + transcript.append_scalar( b"s_sigma_1_eval", &self.evaluations.s_sigma_1_eval, @@ -297,158 +270,196 @@ pub(crate) mod alloc { b"s_sigma_3_eval", &self.evaluations.s_sigma_3_eval, ); + + transcript.append_scalar(b"z_eval", &self.evaluations.z_eval); + + // Add extra shifted evaluations to transcript + transcript.append_scalar(b"a_w_eval", &self.evaluations.a_w_eval); + transcript.append_scalar(b"b_w_eval", &self.evaluations.b_w_eval); + transcript.append_scalar(b"d_w_eval", &self.evaluations.d_w_eval); transcript .append_scalar(b"q_arith_eval", &self.evaluations.q_arith_eval); transcript.append_scalar(b"q_c_eval", &self.evaluations.q_c_eval); transcript.append_scalar(b"q_l_eval", &self.evaluations.q_l_eval); transcript.append_scalar(b"q_r_eval", &self.evaluations.q_r_eval); - transcript.append_scalar(b"perm_eval", &self.evaluations.perm_eval); - transcript.append_scalar(b"t_eval", &t_eval); - transcript.append_scalar(b"r_eval", &self.evaluations.r_poly_eval); - - // Compute linearization commitment - let r_comm = self.compute_linearization_commitment( - &alpha, - &beta, - &gamma, - ( - &range_sep_challenge, - &logic_sep_challenge, - &fixed_base_sep_challenge, - &var_base_sep_challenge, - ), - &z_challenge, - l1_eval, - verifier_key, - ); - // Commitment Scheme - // Now we delegate computation to the commitment scheme by batch - // checking two proofs The `AggregateProof`, which is a - // proof that all the necessary polynomials evaluated at - // challenge `z` are correct and a `SingleProof` which - // is proof that the permutation polynomial evaluated at the shifted - // root of unity is correct + let v_challenge = transcript.challenge_scalar(b"v_challenge"); + let v_w_challenge = transcript.challenge_scalar(b"v_w_challenge"); - // Compose the Aggregated Proof - // - let mut aggregate_proof = - AggregateProof::with_witness(self.w_z_chall_comm); - aggregate_proof.add_part((t_eval, t_comm)); - aggregate_proof.add_part((self.evaluations.r_poly_eval, r_comm)); - aggregate_proof.add_part((self.evaluations.a_eval, self.a_comm)); - aggregate_proof.add_part((self.evaluations.b_eval, self.b_comm)); - aggregate_proof.add_part((self.evaluations.o_eval, self.o_comm)); - aggregate_proof.add_part((self.evaluations.d_eval, self.d_comm)); - aggregate_proof.add_part(( - self.evaluations.s_sigma_1_eval, - verifier_key.permutation.s_sigma_1, - )); - aggregate_proof.add_part(( - self.evaluations.s_sigma_2_eval, - verifier_key.permutation.s_sigma_2, - )); - aggregate_proof.add_part(( - self.evaluations.s_sigma_3_eval, - verifier_key.permutation.s_sigma_3, - )); - // Flatten proof with opening challenge - let flattened_proof_a = aggregate_proof.flatten(transcript); - - // Compose the shifted aggregate proof - let mut shifted_aggregate_proof = - AggregateProof::with_witness(self.w_z_chall_w_comm); - shifted_aggregate_proof - .add_part((self.evaluations.perm_eval, self.z_comm)); - shifted_aggregate_proof - .add_part((self.evaluations.a_next_eval, self.a_comm)); - shifted_aggregate_proof - .add_part((self.evaluations.b_next_eval, self.b_comm)); - shifted_aggregate_proof - .add_part((self.evaluations.d_next_eval, self.d_comm)); - - let flattened_proof_b = shifted_aggregate_proof.flatten(transcript); // Add commitment to openings to transcript - transcript.append_commitment(b"w_z", &self.w_z_chall_comm); - transcript.append_commitment(b"w_z_w", &self.w_z_chall_w_comm); - // Batch check - if opening_key - .batch_check( - &[z_challenge, (z_challenge * domain.group_gen)], - &[flattened_proof_a, flattened_proof_b], - transcript, - ) - .is_err() - { - return Err(Error::ProofVerificationError); - } - - Ok(()) - } - - #[allow(clippy::too_many_arguments)] - fn compute_quotient_evaluation( - &self, - domain: &EvaluationDomain, - pub_inputs: &[BlsScalar], - alpha: &BlsScalar, - beta: &BlsScalar, - gamma: &BlsScalar, - z_challenge: &BlsScalar, - z_h_eval: &BlsScalar, - l1_eval: &BlsScalar, - z_hat_eval: &BlsScalar, - ) -> BlsScalar { - // Compute the public input polynomial evaluated at challenge `z` - let pi_eval = - compute_barycentric_eval(pub_inputs, z_challenge, domain); + transcript + .append_commitment(b"w_z_chall_comm", &self.w_z_chall_comm); + transcript + .append_commitment(b"w_z_chall_w_comm", &self.w_z_chall_w_comm); - // Compute powers of alpha_0 - let alpha_sq = alpha.square(); + // Compute the challenge 'u' + let u_challenge = transcript.challenge_scalar(b"u_challenge"); - // r + PI(z) - let a = self.evaluations.r_poly_eval + pi_eval; + // Compute zero polynomial evaluated at challenge `z` + let z_h_eval = domain.evaluate_vanishing_polynomial(&z_challenge); - // a + beta * sigma_1 + gamma - let beta_sig1 = beta * self.evaluations.s_sigma_1_eval; - let b_0 = self.evaluations.a_eval + beta_sig1 + gamma; + // Compute first lagrange polynomial evaluated at challenge `z` + let l1_eval = compute_first_lagrange_evaluation( + &domain, + &z_h_eval, + &z_challenge, + ); - // b + beta * sigma_2 + gamma - let beta_sig2 = beta * self.evaluations.s_sigma_2_eval; - let b_1 = self.evaluations.b_eval + beta_sig2 + gamma; + // Compute '[D]_1' + let D = self + .compute_linearization_commitment( + &alpha, + &beta, + &gamma, + ( + &range_sep_challenge, + &logic_sep_challenge, + &fixed_base_sep_challenge, + &var_base_sep_challenge, + ), + &z_challenge, + &u_challenge, + l1_eval, + verifier_key, + &domain, + ) + .0; - // o + beta * sigma_3 + gamma - let beta_sig3 = beta * self.evaluations.s_sigma_3_eval; - let b_2 = self.evaluations.o_eval + beta_sig3 + gamma; + // Evaluate public inputs + let pi_eval = + compute_barycentric_eval(pub_inputs, &z_challenge, &domain); + + // Compute r_0 + let r_0_eval = pi_eval + - l1_eval * alpha.square() + - alpha + * (self.evaluations.a_eval + + beta * self.evaluations.s_sigma_1_eval + + gamma) + * (self.evaluations.b_eval + + beta * self.evaluations.s_sigma_2_eval + + gamma) + * (self.evaluations.c_eval + + beta * self.evaluations.s_sigma_3_eval + + gamma) + * (self.evaluations.d_eval + gamma) + * self.evaluations.z_eval; + + // Coefficients to compute [E]_1 + let mut v_coeffs_E = vec![v_challenge]; + + // Compute the powers of the v_challenge + for i in 1..V_MAX_DEGREE { + v_coeffs_E.push(v_coeffs_E[i - 1] * v_challenge); + } - // ((d + gamma) * z_hat) * alpha_0 - let b_3 = (self.evaluations.d_eval + gamma) * z_hat_eval * alpha; + // Compute the powers of the v_challenge multiplied by u_challenge + v_coeffs_E.push(v_w_challenge * u_challenge); + 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(); + + // 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]; + + // Commitments to compute [F]_1 + let F_comms = 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, + ]; + + // Compute '[F]_1' in single-core + #[cfg(not(feature = "std"))] + let mut F: G1Projective = F_comms + .iter() + .zip(v_coeffs_F.iter()) + .map(|(poly, coeff)| poly * coeff) + .sum(); + + // Compute '[F]_1' in multi-core + #[cfg(feature = "std")] + let mut F: G1Projective = F_comms + .par_iter() + .zip(v_coeffs_F.par_iter()) + .map(|(poly, coeff)| poly * coeff) + .sum(); + + // [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 + 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; + + // 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), + ); - let b = b_0 * b_1 * b_2 * b_3; + // 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 + - E, + ); - // l_1(z) * alpha_0^2 - let c = l1_eval * alpha_sq; + // Compute the two pairings and subtract them + let pairing = dusk_bls12_381::multi_miller_loop(&[ + (&left, &opening_key.prepared_x_h), + (&right, &opening_key.prepared_h), + ]) + .final_exponentiation(); - // Return t_eval - ( - a - b - c - //+ d - ) * z_h_eval.invert().unwrap() - } + // Return 'ProofVerificationError' if the two + // pairings are not equal, continue otherwise + if pairing != dusk_bls12_381::Gt::identity() { + return Err(Error::ProofVerificationError); + }; - fn compute_quotient_commitment( - &self, - z_challenge: &BlsScalar, - n: usize, - ) -> Commitment { - let z_n = z_challenge.pow(&[n as u64, 0, 0, 0]); - let z_two_n = z_challenge.pow(&[2 * n as u64, 0, 0, 0]); - let z_three_n = z_challenge.pow(&[3 * n as u64, 0, 0, 0]); - let t_comm = self.t_low_comm.0 - + self.t_mid_comm.0 * z_n - + self.t_high_comm.0 * z_two_n - + self.t_4_comm.0 * z_three_n; - Commitment::from(t_comm) + Ok(()) } // Commitment to [r]_1 @@ -465,8 +476,10 @@ pub(crate) mod alloc { var_base_sep_challenge, ): (&BlsScalar, &BlsScalar, &BlsScalar, &BlsScalar), z_challenge: &BlsScalar, + u_challenge: &BlsScalar, l1_eval: BlsScalar, verifier_key: &VerifierKey, + domain: &EvaluationDomain, ) -> Commitment { let mut scalars: Vec<_> = Vec::with_capacity(6); let mut points: Vec = Vec::with_capacity(6); @@ -510,11 +523,34 @@ pub(crate) mod alloc { &mut points, &self.evaluations, z_challenge, + u_challenge, (alpha, beta, gamma), &l1_eval, self.z_comm.0, ); + let domain_size = domain.size(); + let z_h_eval = -domain.evaluate_vanishing_polynomial(z_challenge); + + let z_n = + z_challenge.pow(&[domain_size as u64, 0, 0, 0]) * z_h_eval; + let z_two_n = + z_challenge.pow(&[2 * domain_size as u64, 0, 0, 0]) * z_h_eval; + let z_three_n = + z_challenge.pow(&[3 * domain_size as u64, 0, 0, 0]) * z_h_eval; + + scalars.push(z_h_eval); + points.push(self.t_low_comm.0); + + scalars.push(z_n); + points.push(self.t_mid_comm.0); + + scalars.push(z_two_n); + points.push(self.t_high_comm.0); + + scalars.push(z_three_n); + points.push(self.t_fourth_comm.0); + Commitment::from(msm_variable_base(&points, &scalars)) } } @@ -529,7 +565,7 @@ pub(crate) mod alloc { z_h_eval * denom.invert().unwrap() } - fn compute_barycentric_eval( + pub(crate) fn compute_barycentric_eval( evaluations: &[BlsScalar], point: &BlsScalar, domain: &EvaluationDomain, @@ -596,23 +632,23 @@ mod proof_tests { let proof = Proof { a_comm: Commitment::default(), b_comm: Commitment::default(), - o_comm: Commitment::default(), + c_comm: Commitment::default(), d_comm: Commitment::default(), z_comm: Commitment::default(), t_low_comm: Commitment::default(), t_mid_comm: Commitment::default(), t_high_comm: Commitment::default(), - t_4_comm: Commitment::default(), + t_fourth_comm: Commitment::default(), w_z_chall_comm: Commitment::default(), w_z_chall_w_comm: Commitment::default(), evaluations: ProofEvaluations { a_eval: BlsScalar::random(&mut OsRng), b_eval: BlsScalar::random(&mut OsRng), - o_eval: BlsScalar::random(&mut OsRng), + c_eval: BlsScalar::random(&mut OsRng), d_eval: BlsScalar::random(&mut OsRng), - a_next_eval: BlsScalar::random(&mut OsRng), - b_next_eval: BlsScalar::random(&mut OsRng), - d_next_eval: BlsScalar::random(&mut OsRng), + a_w_eval: BlsScalar::random(&mut OsRng), + b_w_eval: BlsScalar::random(&mut OsRng), + d_w_eval: BlsScalar::random(&mut OsRng), q_arith_eval: BlsScalar::random(&mut OsRng), q_c_eval: BlsScalar::random(&mut OsRng), q_l_eval: BlsScalar::random(&mut OsRng), @@ -620,8 +656,7 @@ mod proof_tests { s_sigma_1_eval: BlsScalar::random(&mut OsRng), s_sigma_2_eval: BlsScalar::random(&mut OsRng), s_sigma_3_eval: BlsScalar::random(&mut OsRng), - r_poly_eval: BlsScalar::random(&mut OsRng), - perm_eval: BlsScalar::random(&mut OsRng), + z_eval: BlsScalar::random(&mut OsRng), }, }; diff --git a/src/proof_system/quotient_poly.rs b/src/proof_system/quotient_poly.rs index c22c6a45..b635c041 100644 --- a/src/proof_system/quotient_poly.rs +++ b/src/proof_system/quotient_poly.rs @@ -20,7 +20,7 @@ pub(crate) fn compute( domain: &EvaluationDomain, prover_key: &ProverKey, z_poly: &Polynomial, - (a_w_poly, b_w_poly, o_w_poly, d_w_poly): ( + (a_poly, b_poly, c_poly, d_poly): ( &Polynomial, &Polynomial, &Polynomial, @@ -50,17 +50,17 @@ pub(crate) fn compute( let mut z_eval_8n = domain_8n.coset_fft(z_poly); - let mut a_w_eval_8n = domain_8n.coset_fft(a_w_poly); - let mut b_w_eval_8n = domain_8n.coset_fft(b_w_poly); - let o_w_eval_8n = domain_8n.coset_fft(o_w_poly); - let mut d_w_eval_8n = domain_8n.coset_fft(d_w_poly); + let mut a_eval_8n = domain_8n.coset_fft(a_poly); + let mut b_eval_8n = domain_8n.coset_fft(b_poly); + let c_eval_8n = domain_8n.coset_fft(c_poly); + let mut d_eval_8n = domain_8n.coset_fft(d_poly); for i in 0..8 { z_eval_8n.push(z_eval_8n[i]); - a_w_eval_8n.push(a_w_eval_8n[i]); - b_w_eval_8n.push(b_w_eval_8n[i]); - // o_w_eval_8n push not required - d_w_eval_8n.push(d_w_eval_8n[i]); + a_eval_8n.push(a_eval_8n[i]); + b_eval_8n.push(b_eval_8n[i]); + // c_eval_8n push not required + d_eval_8n.push(d_eval_8n[i]); } let t_1 = compute_circuit_satisfiability_equation( @@ -72,14 +72,14 @@ pub(crate) fn compute( var_base_challenge, ), prover_key, - (&a_w_eval_8n, &b_w_eval_8n, &o_w_eval_8n, &d_w_eval_8n), + (&a_eval_8n, &b_eval_8n, &c_eval_8n, &d_eval_8n), public_inputs_poly, ); let t_2 = compute_permutation_checks( domain, prover_key, - (&a_w_eval_8n, &b_w_eval_8n, &o_w_eval_8n, &d_w_eval_8n), + (&a_eval_8n, &b_eval_8n, &c_eval_8n, &d_eval_8n), &z_eval_8n, (alpha, beta, gamma), ); @@ -103,7 +103,6 @@ pub(crate) fn compute( Ok(Polynomial::from_coefficients_vec(coset)) } -// Ensures that the circuit is satisfied // Ensures that the circuit is satisfied fn compute_circuit_satisfiability_equation( domain: &EvaluationDomain, @@ -114,7 +113,7 @@ fn compute_circuit_satisfiability_equation( var_base_challenge, ): (&BlsScalar, &BlsScalar, &BlsScalar, &BlsScalar), prover_key: &ProverKey, - (a_w_eval_8n, b_w_eval_8n, o_w_eval_8n, d_w_eval_8n): ( + (a_eval_8n, b_eval_8n, c_eval_8n, d_eval_8n): ( &[BlsScalar], &[BlsScalar], &[BlsScalar], @@ -133,66 +132,67 @@ fn compute_circuit_satisfiability_equation( let t: Vec<_> = range .map(|i| { - let a_w = &a_w_eval_8n[i]; - let b_w = &b_w_eval_8n[i]; - let o_w = &o_w_eval_8n[i]; - let d_w = &d_w_eval_8n[i]; - let a_w_next = &a_w_eval_8n[i + 8]; - let b_w_next = &b_w_eval_8n[i + 8]; - let d_w_next = &d_w_eval_8n[i + 8]; + let a = &a_eval_8n[i]; + let b = &b_eval_8n[i]; + let c = &c_eval_8n[i]; + let d = &d_eval_8n[i]; + let a_w = &a_eval_8n[i + 8]; + let b_w = &b_eval_8n[i + 8]; + let d_w = &d_eval_8n[i + 8]; let pi = &public_eval_8n[i]; - let a = prover_key - .arithmetic - .compute_quotient_i(i, a_w, b_w, o_w, d_w); + let t_arith = + prover_key.arithmetic.compute_quotient_i(i, a, b, c, d); - let b = prover_key.range.compute_quotient_i( + let t_range = prover_key.range.compute_quotient_i( i, range_challenge, - a_w, - b_w, - o_w, + a, + b, + c, + d, d_w, - d_w_next, ); - let c = prover_key.logic.compute_quotient_i( + let t_logic = prover_key.logic.compute_quotient_i( i, logic_challenge, + a, a_w, - a_w_next, + b, b_w, - b_w_next, - o_w, + c, + d, d_w, - d_w_next, ); - let d = prover_key.fixed_base.compute_quotient_i( + let t_fixed = prover_key.fixed_base.compute_quotient_i( i, fixed_base_challenge, + a, a_w, - a_w_next, + b, b_w, - b_w_next, - o_w, + c, + d, d_w, - d_w_next, ); - let e = prover_key.variable_base.compute_quotient_i( + let t_var = prover_key.variable_base.compute_quotient_i( i, var_base_challenge, + a, a_w, - a_w_next, + b, b_w, - b_w_next, - o_w, + c, + d, d_w, - d_w_next, ); - (a + pi) + b + c + d + e + // Multiplication by selectors and challenges + // has already been done + t_arith + t_range + t_logic + t_fixed + t_var + pi }) .collect(); t @@ -201,7 +201,7 @@ fn compute_circuit_satisfiability_equation( fn compute_permutation_checks( domain: &EvaluationDomain, prover_key: &ProverKey, - (a_w_eval_8n, b_w_eval_8n, o_w_eval_8n, d_w_eval_8n): ( + (a_eval_8n, b_eval_8n, c_eval_8n, d_eval_8n): ( &[BlsScalar], &[BlsScalar], &[BlsScalar], @@ -225,10 +225,10 @@ fn compute_permutation_checks( .map(|i| { prover_key.permutation.compute_quotient_i( i, - &a_w_eval_8n[i], - &b_w_eval_8n[i], - &o_w_eval_8n[i], - &d_w_eval_8n[i], + &a_eval_8n[i], + &b_eval_8n[i], + &c_eval_8n[i], + &d_eval_8n[i], &z_eval_8n[i], &z_eval_8n[i + 8], alpha, diff --git a/src/proof_system/widget.rs b/src/proof_system/widget.rs index f1c48846..dda20b16 100644 --- a/src/proof_system/widget.rs +++ b/src/proof_system/widget.rs @@ -91,7 +91,7 @@ impl Serializable<{ 20 * Commitment::SIZE + u64::SIZE }> for VerifierKey { writer.write(&self.arithmetic.q_l.to_bytes()); writer.write(&self.arithmetic.q_r.to_bytes()); writer.write(&self.arithmetic.q_o.to_bytes()); - writer.write(&self.arithmetic.q_4.to_bytes()); + writer.write(&self.arithmetic.q_f.to_bytes()); writer.write(&self.arithmetic.q_c.to_bytes()); writer.write(&self.arithmetic.q_arith.to_bytes()); writer.write(&self.logic.q_logic.to_bytes()); @@ -140,7 +140,7 @@ impl VerifierKey { q_l: Commitment, q_r: Commitment, q_o: Commitment, - q_4: Commitment, + q_f: Commitment, q_c: Commitment, q_arith: Commitment, q_logic: Commitment, @@ -157,7 +157,7 @@ impl VerifierKey { q_l, q_r, q_o, - q_4, + q_f, q_c, q_arith, }; @@ -213,7 +213,7 @@ pub(crate) mod alloc { transcript.append_commitment(b"q_r", &self.arithmetic.q_r); transcript.append_commitment(b"q_o", &self.arithmetic.q_o); transcript.append_commitment(b"q_c", &self.arithmetic.q_c); - transcript.append_commitment(b"q_4", &self.arithmetic.q_4); + transcript.append_commitment(b"q_f", &self.arithmetic.q_f); transcript.append_commitment(b"q_arith", &self.arithmetic.q_arith); transcript.append_commitment(b"q_range", &self.range.q_range); transcript.append_commitment(b"q_logic", &self.logic.q_logic); @@ -286,7 +286,7 @@ pub(crate) mod alloc { /// Returns the size of the ProverKey for serialization. /// /// Note: - /// Duplicate polynomials of the ProverKey (e.g. `q_l`, `q_r` and `q_c`) + /// Duplicate polynomials of the ProverKey (e.g. `q_L`, `q_R` and `q_C`) /// are only counted once. fn serialization_size(&self) -> usize { // Fetch size in bytes of each Polynomial @@ -344,9 +344,9 @@ pub(crate) mod alloc { writer.write(&self.arithmetic.q_o.0.to_var_bytes()); writer.write(&self.arithmetic.q_o.1.to_var_bytes()); - writer.write(&(self.arithmetic.q_4.0.len() as u64).to_bytes()); - writer.write(&self.arithmetic.q_4.0.to_var_bytes()); - writer.write(&self.arithmetic.q_4.1.to_var_bytes()); + writer.write(&(self.arithmetic.q_f.0.len() as u64).to_bytes()); + writer.write(&self.arithmetic.q_f.0.to_var_bytes()); + writer.write(&self.arithmetic.q_f.1.to_var_bytes()); writer.write(&(self.arithmetic.q_c.0.len() as u64).to_bytes()); writer.write(&self.arithmetic.q_c.0.to_var_bytes()); @@ -464,9 +464,9 @@ pub(crate) mod alloc { let q_o_evals = evals_from_reader(&mut buffer)?; let q_o = (q_o_poly, q_o_evals); - let q_4_poly = poly_from_reader(&mut buffer)?; - let q_4_evals = evals_from_reader(&mut buffer)?; - let q_4 = (q_4_poly, q_4_evals); + let q_f_poly = poly_from_reader(&mut buffer)?; + let q_f_evals = evals_from_reader(&mut buffer)?; + let q_f = (q_f_poly, q_f_evals); let q_c_poly = poly_from_reader(&mut buffer)?; let q_c_evals = evals_from_reader(&mut buffer)?; @@ -520,7 +520,7 @@ pub(crate) mod alloc { q_r: q_r.clone(), q_o, q_c: q_c.clone(), - q_4, + q_f, q_arith, }; @@ -604,7 +604,7 @@ mod test { let q_r = rand_poly_eval(n); let q_o = rand_poly_eval(n); let q_c = rand_poly_eval(n); - let q_4 = rand_poly_eval(n); + let q_f = rand_poly_eval(n); let q_arith = rand_poly_eval(n); let q_logic = rand_poly_eval(n); @@ -629,7 +629,7 @@ mod test { q_r: q_r.clone(), q_o, q_c: q_c.clone(), - q_4, + q_f, q_arith, }; @@ -689,7 +689,7 @@ mod test { let q_r = Commitment(G1Affine::generator()); let q_o = Commitment(G1Affine::generator()); let q_c = Commitment(G1Affine::generator()); - let q_4 = Commitment(G1Affine::generator()); + let q_f = Commitment(G1Affine::generator()); let q_arith = Commitment(G1Affine::generator()); let q_range = Commitment(G1Affine::generator()); @@ -710,7 +710,7 @@ mod test { q_r, q_o, q_c, - q_4, + q_f, q_arith, }; diff --git a/src/proof_system/widget/arithmetic/proverkey.rs b/src/proof_system/widget/arithmetic/proverkey.rs index 3bb5d943..75288834 100644 --- a/src/proof_system/widget/arithmetic/proverkey.rs +++ b/src/proof_system/widget/arithmetic/proverkey.rs @@ -5,6 +5,7 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use crate::fft::{Evaluations, Polynomial}; +use crate::proof_system::linearization_poly::ProofEvaluations; use dusk_bls12_381::BlsScalar; #[cfg(feature = "rkyv-impl")] @@ -32,7 +33,7 @@ pub(crate) struct ProverKey { #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub q_o: (Polynomial, Evaluations), #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub q_4: (Polynomial, Evaluations), + pub q_f: (Polynomial, Evaluations), #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub q_c: (Polynomial, Evaluations), #[cfg_attr(feature = "rkyv-impl", omit_bounds)] @@ -43,71 +44,67 @@ impl ProverKey { pub(crate) fn compute_quotient_i( &self, index: usize, - a_w_i: &BlsScalar, - b_w_i: &BlsScalar, - o_w_i: &BlsScalar, - d_w_i: &BlsScalar, + a_i: &BlsScalar, + b_i: &BlsScalar, + c_i: &BlsScalar, + d_i: &BlsScalar, ) -> BlsScalar { let q_m_i = &self.q_m.1[index]; let q_l_i = &self.q_l.1[index]; let q_r_i = &self.q_r.1[index]; let q_o_i = &self.q_o.1[index]; - let q_4_i = &self.q_4.1[index]; + let q_f_i = &self.q_f.1[index]; let q_c_i = &self.q_c.1[index]; let q_arith_i = &self.q_arith.1[index]; - // (a(x)b(x)q_M(x) + a(x)q_L(x) + b(X)q_R(x) + o(X)q_O(X) + d(x)q_4(X) + - // Q_C(X)) * Q_Arith(X) + // (a(x)b(x)q_M(x) + a(x)q_L(x) + b(X)q_R(x) + c(X)q_O(X) + d(x)q_F(X) + + // q_C(X)) * q_arith(X) // - let a_1 = a_w_i * b_w_i * q_m_i; - let a_2 = a_w_i * q_l_i; - let a_3 = b_w_i * q_r_i; - let a_4 = o_w_i * q_o_i; - let a_5 = d_w_i * q_4_i; + let a_1 = a_i * b_i * q_m_i; + let a_2 = a_i * q_l_i; + let a_3 = b_i * q_r_i; + let a_4 = c_i * q_o_i; + let a_5 = d_i * q_f_i; let a_6 = q_c_i; (a_1 + a_2 + a_3 + a_4 + a_5 + a_6) * q_arith_i } pub(crate) fn compute_linearization( &self, - a_eval: &BlsScalar, - b_eval: &BlsScalar, - o_eval: &BlsScalar, - d_eval: &BlsScalar, - q_arith_eval: &BlsScalar, + evaluations: &ProofEvaluations, ) -> Polynomial { let q_m_poly = &self.q_m.0; let q_l_poly = &self.q_l.0; let q_r_poly = &self.q_r.0; let q_o_poly = &self.q_o.0; - let q_4_poly = &self.q_4.0; + let q_f_poly = &self.q_f.0; let q_c_poly = &self.q_c.0; - // (a_eval * b_eval * q_m_poly + a_eval * q_l + b_eval * q_r + o_eval - // * q_o + d_eval * q_4 + q_c) * q_arith_eval + // (a_eval * b_eval * q_m_poly + a_eval * q_l + b_eval * q_r + c_eval + // * q_o + d_eval * q_f + q_c) * q_arith_eval // // a_eval * b_eval * q_m_poly - let ab = a_eval * b_eval; + let ab = evaluations.a_eval * evaluations.b_eval; let a_0 = q_m_poly * &ab; // a_eval * q_l - let a_1 = q_l_poly * a_eval; + let a_1 = q_l_poly * &evaluations.a_eval; // b_eval * q_r - let a_2 = q_r_poly * b_eval; + let a_2 = q_r_poly * &evaluations.b_eval; - //o_eval * q_o - let a_3 = q_o_poly * o_eval; + //c_eval * q_o + let a_3 = q_o_poly * &evaluations.c_eval; - // d_eval * q_4 - let a_4 = q_4_poly * d_eval; + // d_eval * q_f + let a_4 = q_f_poly * &evaluations.d_eval; let mut a = &a_0 + &a_1; a = &a + &a_2; a = &a + &a_3; a = &a + &a_4; a = &a + q_c_poly; - a = &a * q_arith_eval; + a = &a * &evaluations.q_arith_eval; a } diff --git a/src/proof_system/widget/arithmetic/verifierkey.rs b/src/proof_system/widget/arithmetic/verifierkey.rs index d8d28c6a..8bd3506c 100644 --- a/src/proof_system/widget/arithmetic/verifierkey.rs +++ b/src/proof_system/widget/arithmetic/verifierkey.rs @@ -32,7 +32,7 @@ pub(crate) struct VerifierKey { #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub q_o: Commitment, #[cfg_attr(feature = "rkyv-impl", omit_bounds)] - pub q_4: Commitment, + pub q_f: Commitment, #[cfg_attr(feature = "rkyv-impl", omit_bounds)] pub q_c: Commitment, #[cfg_attr(feature = "rkyv-impl", omit_bounds)] @@ -51,7 +51,7 @@ impl Serializable<{ 7 * Commitment::SIZE }> for VerifierKey { writer.write(&self.q_l.to_bytes()); writer.write(&self.q_r.to_bytes()); writer.write(&self.q_o.to_bytes()); - writer.write(&self.q_4.to_bytes()); + writer.write(&self.q_f.to_bytes()); writer.write(&self.q_c.to_bytes()); writer.write(&self.q_arith.to_bytes()); @@ -64,7 +64,7 @@ impl Serializable<{ 7 * Commitment::SIZE }> for VerifierKey { let q_l = Commitment::from_reader(&mut buffer)?; let q_r = Commitment::from_reader(&mut buffer)?; let q_o = Commitment::from_reader(&mut buffer)?; - let q_4 = Commitment::from_reader(&mut buffer)?; + let q_f = Commitment::from_reader(&mut buffer)?; let q_c = Commitment::from_reader(&mut buffer)?; let q_arith = Commitment::from_reader(&mut buffer)?; @@ -73,7 +73,7 @@ impl Serializable<{ 7 * Commitment::SIZE }> for VerifierKey { q_l, q_r, q_o, - q_4, + q_f, q_c, q_arith, }) @@ -107,11 +107,11 @@ mod alloc { scalars.push(evaluations.b_eval * q_arith_eval); points.push(self.q_r.0); - scalars.push(evaluations.o_eval * q_arith_eval); + scalars.push(evaluations.c_eval * q_arith_eval); points.push(self.q_o.0); scalars.push(evaluations.d_eval * q_arith_eval); - points.push(self.q_4.0); + points.push(self.q_f.0); scalars.push(q_arith_eval); points.push(self.q_c.0); diff --git a/src/proof_system/widget/ecc/curve_addition/proverkey.rs b/src/proof_system/widget/ecc/curve_addition/proverkey.rs index a8c40d58..1c80afc4 100644 --- a/src/proof_system/widget/ecc/curve_addition/proverkey.rs +++ b/src/proof_system/widget/ecc/curve_addition/proverkey.rs @@ -5,6 +5,7 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use crate::fft::{Evaluations, Polynomial}; +use crate::proof_system::linearization_poly::ProofEvaluations; use dusk_bls12_381::BlsScalar; use dusk_jubjub::EDWARDS_D; @@ -33,25 +34,25 @@ impl ProverKey { &self, index: usize, curve_add_separation_challenge: &BlsScalar, - a_w_i: &BlsScalar, // x_1 - a_w_i_next: &BlsScalar, // x_3 - b_w_i: &BlsScalar, // y_1 - b_w_i_next: &BlsScalar, // y_3 - o_w_i: &BlsScalar, // x_2 - d_w_i: &BlsScalar, // y_2 - d_w_i_next: &BlsScalar, // x_1 * y_2 + a_i: &BlsScalar, // x_1 + a_i_w: &BlsScalar, // x_3 + b_i: &BlsScalar, // y_1 + b_i_w: &BlsScalar, // y_3 + c_i: &BlsScalar, // x_2 + d_i: &BlsScalar, // y_2 + d_i_w: &BlsScalar, // x_1 * y_2 ) -> BlsScalar { let q_variable_group_add_i = &self.q_variable_group_add.1[index]; let kappa = curve_add_separation_challenge.square(); - let x_1 = a_w_i; - let x_3 = a_w_i_next; - let y_1 = b_w_i; - let y_3 = b_w_i_next; - let x_2 = o_w_i; - let y_2 = d_w_i; - let x1_y2 = d_w_i_next; + let x_1 = a_i; + let x_3 = a_i_w; + let y_1 = b_i; + let y_3 = b_i_w; + let x_2 = c_i; + let y_2 = d_i; + let x1_y2 = d_i_w; // Checks // @@ -80,25 +81,19 @@ impl ProverKey { pub(crate) fn compute_linearization( &self, curve_add_separation_challenge: &BlsScalar, - a_eval: &BlsScalar, - a_next_eval: &BlsScalar, - b_eval: &BlsScalar, - b_next_eval: &BlsScalar, - o_eval: &BlsScalar, - d_eval: &BlsScalar, - d_next_eval: &BlsScalar, + evaluations: &ProofEvaluations, ) -> Polynomial { let q_variable_group_add_poly = &self.q_variable_group_add.0; let kappa = curve_add_separation_challenge.square(); - let x_1 = a_eval; - let x_3 = a_next_eval; - let y_1 = b_eval; - let y_3 = b_next_eval; - let x_2 = o_eval; - let y_2 = d_eval; - let x1_y2 = d_next_eval; + let x_1 = evaluations.a_eval; + let x_3 = evaluations.a_w_eval; + let y_1 = evaluations.b_eval; + let y_3 = evaluations.b_w_eval; + let x_2 = evaluations.c_eval; + let y_2 = evaluations.d_eval; + let x1_y2 = evaluations.d_w_eval; // Checks // diff --git a/src/proof_system/widget/ecc/curve_addition/verifierkey.rs b/src/proof_system/widget/ecc/curve_addition/verifierkey.rs index 52187883..2453d743 100644 --- a/src/proof_system/widget/ecc/curve_addition/verifierkey.rs +++ b/src/proof_system/widget/ecc/curve_addition/verifierkey.rs @@ -46,12 +46,12 @@ mod alloc { let kappa = curve_add_separation_challenge.square(); let x_1 = evaluations.a_eval; - let x_3 = evaluations.a_next_eval; + let x_3 = evaluations.a_w_eval; let y_1 = evaluations.b_eval; - let y_3 = evaluations.b_next_eval; - let x_2 = evaluations.o_eval; + let y_3 = evaluations.b_w_eval; + let x_2 = evaluations.c_eval; let y_2 = evaluations.d_eval; - let x1_y2 = evaluations.d_next_eval; + let x1_y2 = evaluations.d_w_eval; // Checks // diff --git a/src/proof_system/widget/ecc/scalar_mul/fixed_base/proverkey.rs b/src/proof_system/widget/ecc/scalar_mul/fixed_base/proverkey.rs index fbf4c8ad..f83b845e 100644 --- a/src/proof_system/widget/ecc/scalar_mul/fixed_base/proverkey.rs +++ b/src/proof_system/widget/ecc/scalar_mul/fixed_base/proverkey.rs @@ -5,6 +5,7 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use crate::fft::{Evaluations, Polynomial}; +use crate::proof_system::linearization_poly::ProofEvaluations; use dusk_bls12_381::BlsScalar; use dusk_jubjub::EDWARDS_D; @@ -39,13 +40,13 @@ impl ProverKey { &self, index: usize, ecc_separation_challenge: &BlsScalar, - a_w_i: &BlsScalar, // acc_x or curr_x - a_w_i_next: &BlsScalar, // // next_x - b_w_i: &BlsScalar, // acc_y or curr_y - b_w_i_next: &BlsScalar, // next_y - o_w_i: &BlsScalar, // xy_alpha - d_w_i: &BlsScalar, // accumulated_bit - d_w_i_next: &BlsScalar, // accumulated_bit_next + a_i: &BlsScalar, // acc_x or curr_x + a_i_w: &BlsScalar, // shifted x + b_i: &BlsScalar, // acc_y or curr_y + b_i_w: &BlsScalar, // shifted y + c_i: &BlsScalar, // xy_alpha + d_i: &BlsScalar, // accumulated_bit + d_i_w: &BlsScalar, // accumulated_bit_w ) -> BlsScalar { let q_fixed_group_add_i = &self.q_fixed_group_add.1[index]; let q_c_i = &self.q_c.1[index]; @@ -57,16 +58,16 @@ impl ProverKey { let x_beta = &self.q_l.1[index]; let y_beta = &self.q_r.1[index]; - let acc_x = a_w_i; - let acc_x_next = a_w_i_next; - let acc_y = b_w_i; - let acc_y_next = b_w_i_next; + let acc_x = a_i; + let acc_x_w = a_i_w; + let acc_y = b_i; + let acc_y_w = b_i_w; - let xy_alpha = o_w_i; + let xy_alpha = c_i; - let accumulated_bit = d_w_i; - let accumulated_bit_next = d_w_i_next; - let bit = extract_bit(accumulated_bit, accumulated_bit_next); + let accumulated_bit = d_i; + let accumulated_bit_w = d_i_w; + let bit = extract_bit(accumulated_bit, accumulated_bit_w); // Checks // @@ -82,13 +83,13 @@ impl ProverKey { let xy_consistency = ((bit * q_c_i) - xy_alpha) * kappa; // x accumulator consistency check - let x_3 = acc_x_next; + let x_3 = acc_x_w; let lhs = x_3 + (x_3 * xy_alpha * acc_x * acc_y * EDWARDS_D); let rhs = (acc_x * y_alpha) + (acc_y * x_alpha); let x_acc_consistency = (lhs - rhs) * kappa_sq; // y accumulator consistency check - let y_3 = acc_y_next; + let y_3 = acc_y_w; let lhs = y_3 - (y_3 * xy_alpha * acc_x * acc_y * EDWARDS_D); let rhs = (acc_y * y_alpha) + (acc_x * x_alpha); let y_acc_consistency = (lhs - rhs) * kappa_cu; @@ -104,16 +105,7 @@ impl ProverKey { pub(crate) fn compute_linearization( &self, ecc_separation_challenge: &BlsScalar, - a_eval: &BlsScalar, - a_next_eval: &BlsScalar, - b_eval: &BlsScalar, - b_next_eval: &BlsScalar, - o_eval: &BlsScalar, - d_eval: &BlsScalar, - d_next_eval: &BlsScalar, - q_l_eval: &BlsScalar, - q_r_eval: &BlsScalar, - q_c_eval: &BlsScalar, + evaluations: &ProofEvaluations, ) -> Polynomial { let q_fixed_group_add_poly = &self.q_fixed_group_add.0; @@ -121,19 +113,19 @@ impl ProverKey { let kappa_sq = kappa.square(); let kappa_cu = kappa_sq * kappa; - let x_beta_eval = q_l_eval; - let y_beta_eval = q_r_eval; + let x_beta_eval = evaluations.q_l_eval; + let y_beta_eval = evaluations.q_r_eval; - let acc_x = a_eval; - let acc_x_next = a_next_eval; - let acc_y = b_eval; - let acc_y_next = b_next_eval; + let acc_x = evaluations.a_eval; + let acc_x_w = evaluations.a_w_eval; + let acc_y = evaluations.b_eval; + let acc_y_w = evaluations.b_w_eval; - let xy_alpha = o_eval; + let xy_alpha = evaluations.c_eval; - let accumulated_bit = d_eval; - let accumulated_bit_next = d_next_eval; - let bit = extract_bit(accumulated_bit, accumulated_bit_next); + let accumulated_bit = evaluations.d_eval; + let accumulated_bit_w = evaluations.d_w_eval; + let bit = extract_bit(&accumulated_bit, &accumulated_bit_w); // Check bit consistency let bit_consistency = check_bit_consistency(bit); @@ -144,16 +136,16 @@ impl ProverKey { let x_alpha = x_beta_eval * bit; // xy_alpha consistency check - let xy_consistency = ((bit * q_c_eval) - xy_alpha) * kappa; + let xy_consistency = ((bit * evaluations.q_c_eval) - xy_alpha) * kappa; // x accumulator consistency check - let x_3 = acc_x_next; + let x_3 = acc_x_w; let lhs = x_3 + (x_3 * xy_alpha * acc_x * acc_y * EDWARDS_D); let rhs = (x_alpha * acc_y) + (y_alpha * acc_x); let x_acc_consistency = (lhs - rhs) * kappa_sq; // y accumulator consistency check - let y_3 = acc_y_next; + let y_3 = acc_y_w; let lhs = y_3 - (y_3 * xy_alpha * acc_x * acc_y * EDWARDS_D); let rhs = (x_alpha * acc_x) + (y_alpha * acc_y); let y_acc_consistency = (lhs - rhs) * kappa_cu; @@ -167,12 +159,9 @@ impl ProverKey { } } -pub(crate) fn extract_bit( - curr_acc: &BlsScalar, - next_acc: &BlsScalar, -) -> BlsScalar { - // Next - 2 * current - next_acc - curr_acc - curr_acc +pub(crate) fn extract_bit(acc: &BlsScalar, acc_w: &BlsScalar) -> BlsScalar { + // acc_w - 2 * acc + acc_w - acc - acc } // Ensures that the bit is either +1, -1 or 0 diff --git a/src/proof_system/widget/ecc/scalar_mul/fixed_base/verifierkey.rs b/src/proof_system/widget/ecc/scalar_mul/fixed_base/verifierkey.rs index 05c7fdfe..8b1e8bc2 100644 --- a/src/proof_system/widget/ecc/scalar_mul/fixed_base/verifierkey.rs +++ b/src/proof_system/widget/ecc/scalar_mul/fixed_base/verifierkey.rs @@ -58,15 +58,15 @@ mod alloc { let y_beta_eval = evaluations.q_r_eval; let acc_x = evaluations.a_eval; - let acc_x_next = evaluations.a_next_eval; + let acc_x_w = evaluations.a_w_eval; let acc_y = evaluations.b_eval; - let acc_y_next = evaluations.b_next_eval; + let acc_y_w = evaluations.b_w_eval; - let xy_alpha = evaluations.o_eval; + let xy_alpha = evaluations.c_eval; let accumulated_bit = evaluations.d_eval; - let accumulated_bit_next = evaluations.d_next_eval; - let bit = extract_bit(&accumulated_bit, &accumulated_bit_next); + let accumulated_bit_w = evaluations.d_w_eval; + let bit = extract_bit(&accumulated_bit, &accumulated_bit_w); // Check bit consistency let bit_consistency = check_bit_consistency(bit); @@ -81,13 +81,13 @@ mod alloc { ((bit * evaluations.q_c_eval) - xy_alpha) * kappa; // x accumulator consistency check - let x_3 = acc_x_next; + let x_3 = acc_x_w; let lhs = x_3 + (x_3 * xy_alpha * acc_x * acc_y * EDWARDS_D); let rhs = (x_alpha * acc_y) + (y_alpha * acc_x); let x_acc_consistency = (lhs - rhs) * kappa_sq; // y accumulator consistency check - let y_3 = acc_y_next; + let y_3 = acc_y_w; let lhs = y_3 - (y_3 * xy_alpha * acc_x * acc_y * EDWARDS_D); let rhs = (x_alpha * acc_x) + (y_alpha * acc_y); let y_acc_consistency = (lhs - rhs) * kappa_cu; diff --git a/src/proof_system/widget/logic/proverkey.rs b/src/proof_system/widget/logic/proverkey.rs index be2b070a..72865c54 100644 --- a/src/proof_system/widget/logic/proverkey.rs +++ b/src/proof_system/widget/logic/proverkey.rs @@ -5,6 +5,7 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use crate::fft::{Evaluations, Polynomial}; +use crate::proof_system::linearization_poly::ProofEvaluations; use dusk_bls12_381::BlsScalar; @@ -35,13 +36,13 @@ impl ProverKey { &self, index: usize, logic_separation_challenge: &BlsScalar, - a_w_i: &BlsScalar, - a_w_i_next: &BlsScalar, - b_w_i: &BlsScalar, - b_w_i_next: &BlsScalar, - o_w_i: &BlsScalar, - d_w_i: &BlsScalar, - d_w_i_next: &BlsScalar, + a_i: &BlsScalar, + a_i_w: &BlsScalar, + b_i: &BlsScalar, + b_i_w: &BlsScalar, + c_i: &BlsScalar, + d_i: &BlsScalar, + d_i_w: &BlsScalar, ) -> BlsScalar { let four = BlsScalar::from(4); @@ -53,34 +54,27 @@ impl ProverKey { let kappa_cu = kappa_sq * kappa; let kappa_qu = kappa_cu * kappa; - let a = a_w_i_next - four * a_w_i; - let o_0 = delta(a); + let a = a_i_w - four * a_i; + let c_0 = delta(a); - let b = b_w_i_next - four * b_w_i; - let o_1 = delta(b) * kappa; + let b = b_i_w - four * b_i; + let c_1 = delta(b) * kappa; - let d = d_w_i_next - four * d_w_i; - let o_2 = delta(d) * kappa_sq; + let d = d_i_w - four * d_i; + let c_2 = delta(d) * kappa_sq; - let w = o_w_i; - let o_3 = (w - a * b) * kappa_cu; + let w = c_i; + let c_3 = (w - a * b) * kappa_cu; - let o_4 = delta_xor_and(&a, &b, w, &d, q_c_i) * kappa_qu; + let c_4 = delta_xor_and(&a, &b, w, &d, q_c_i) * kappa_qu; - q_logic_i * (o_3 + o_0 + o_1 + o_2 + o_4) * logic_separation_challenge + q_logic_i * (c_3 + c_0 + c_1 + c_2 + c_4) * logic_separation_challenge } pub(crate) fn compute_linearization( &self, logic_separation_challenge: &BlsScalar, - a_eval: &BlsScalar, - a_next_eval: &BlsScalar, - b_eval: &BlsScalar, - b_next_eval: &BlsScalar, - o_eval: &BlsScalar, - d_eval: &BlsScalar, - d_next_eval: &BlsScalar, - q_c_eval: &BlsScalar, + evaluations: &ProofEvaluations, ) -> Polynomial { let four = BlsScalar::from(4); let q_logic_poly = &self.q_logic.0; @@ -90,21 +84,22 @@ impl ProverKey { let kappa_cu = kappa_sq * kappa; let kappa_qu = kappa_cu * kappa; - let a = a_next_eval - four * a_eval; - let o_0 = delta(a); + let a = evaluations.a_w_eval - four * evaluations.a_eval; + let c_0 = delta(a); - let b = b_next_eval - four * b_eval; - let o_1 = delta(b) * kappa; + let b = evaluations.b_w_eval - four * evaluations.b_eval; + let c_1 = delta(b) * kappa; - let d = d_next_eval - four * d_eval; - let o_2 = delta(d) * kappa_sq; + let d = evaluations.d_w_eval - four * evaluations.d_eval; + let c_2 = delta(d) * kappa_sq; - let w = o_eval; - let o_3 = (w - a * b) * kappa_cu; + let w = evaluations.c_eval; + let c_3 = (w - a * b) * kappa_cu; - let o_4 = delta_xor_and(&a, &b, w, &d, q_c_eval) * kappa_qu; + let c_4 = + delta_xor_and(&a, &b, &w, &d, &evaluations.q_c_eval) * kappa_qu; - let t = (o_0 + o_1 + o_2 + o_3 + o_4) * logic_separation_challenge; + let t = (c_0 + c_1 + c_2 + c_3 + c_4) * logic_separation_challenge; q_logic_poly * &t } diff --git a/src/proof_system/widget/logic/verifierkey.rs b/src/proof_system/widget/logic/verifierkey.rs index 77604d52..ec8aa626 100644 --- a/src/proof_system/widget/logic/verifierkey.rs +++ b/src/proof_system/widget/logic/verifierkey.rs @@ -52,22 +52,22 @@ mod alloc { let kappa_cu = kappa_sq * kappa; let kappa_qu = kappa_cu * kappa; - let a = evaluations.a_next_eval - four * evaluations.a_eval; - let o_0 = delta(a); + let a = evaluations.a_w_eval - four * evaluations.a_eval; + let c_0 = delta(a); - let b = evaluations.b_next_eval - four * evaluations.b_eval; - let o_1 = delta(b) * kappa; + let b = evaluations.b_w_eval - four * evaluations.b_eval; + let c_1 = delta(b) * kappa; - let d = evaluations.d_next_eval - four * evaluations.d_eval; - let o_2 = delta(d) * kappa_sq; + let d = evaluations.d_w_eval - four * evaluations.d_eval; + let c_2 = delta(d) * kappa_sq; - let o = evaluations.o_eval; - let o_3 = (o - a * b) * kappa_cu; + let w = evaluations.c_eval; + let c_3 = (w - a * b) * kappa_cu; - let o_4 = - delta_xor_and(&a, &b, &o, &d, &evaluations.q_c_eval) * kappa_qu; + let c_4 = + delta_xor_and(&a, &b, &w, &d, &evaluations.q_c_eval) * kappa_qu; scalars.push( - (o_0 + o_1 + o_2 + o_3 + o_4) * logic_separation_challenge, + (c_0 + c_1 + c_2 + c_3 + c_4) * logic_separation_challenge, ); points.push(self.q_logic.0); } diff --git a/src/proof_system/widget/permutation/proverkey.rs b/src/proof_system/widget/permutation/proverkey.rs index 8f1d0d3c..8da74f10 100644 --- a/src/proof_system/widget/permutation/proverkey.rs +++ b/src/proof_system/widget/permutation/proverkey.rs @@ -46,22 +46,22 @@ impl ProverKey { pub(crate) fn compute_quotient_i( &self, index: usize, - a_w_i: &BlsScalar, - b_w_i: &BlsScalar, - o_w_i: &BlsScalar, - d_w_i: &BlsScalar, + a_i: &BlsScalar, + b_i: &BlsScalar, + c_i: &BlsScalar, + d_i: &BlsScalar, z_i: &BlsScalar, - z_i_next: &BlsScalar, + z_i_w: &BlsScalar, alpha: &BlsScalar, l1_alpha_sq: &BlsScalar, beta: &BlsScalar, gamma: &BlsScalar, ) -> BlsScalar { let a = self.compute_quotient_identity_range_check_i( - index, a_w_i, b_w_i, o_w_i, d_w_i, z_i, alpha, beta, gamma, + index, a_i, b_i, c_i, d_i, z_i, alpha, beta, gamma, ); let b = self.compute_quotient_copy_range_check_i( - index, a_w_i, b_w_i, o_w_i, d_w_i, z_i_next, alpha, beta, gamma, + index, a_i, b_i, c_i, d_i, z_i_w, alpha, beta, gamma, ); let c = self.compute_quotient_term_check_one_i(z_i, l1_alpha_sq); a + b + c @@ -71,10 +71,10 @@ impl ProverKey { fn compute_quotient_identity_range_check_i( &self, index: usize, - a_w_i: &BlsScalar, - b_w_i: &BlsScalar, - o_w_i: &BlsScalar, - d_w_i: &BlsScalar, + a_i: &BlsScalar, + b_i: &BlsScalar, + c_i: &BlsScalar, + d_i: &BlsScalar, z_i: &BlsScalar, alpha: &BlsScalar, beta: &BlsScalar, @@ -82,10 +82,10 @@ impl ProverKey { ) -> BlsScalar { let x = self.linear_evaluations[index]; - (a_w_i + (beta * x) + gamma) - * (b_w_i + (beta * K1 * x) + gamma) - * (o_w_i + (beta * K2 * x) + gamma) - * (d_w_i + (beta * K3 * x) + gamma) + (a_i + (beta * x) + gamma) + * (b_i + (beta * K1 * x) + gamma) + * (c_i + (beta * K2 * x) + gamma) + * (d_i + (beta * K3 * x) + gamma) * z_i * alpha } @@ -95,11 +95,11 @@ impl ProverKey { fn compute_quotient_copy_range_check_i( &self, index: usize, - a_w_i: &BlsScalar, - b_w_i: &BlsScalar, - o_w_i: &BlsScalar, - d_w_i: &BlsScalar, - z_i_next: &BlsScalar, + a_i: &BlsScalar, + b_i: &BlsScalar, + c_i: &BlsScalar, + d_i: &BlsScalar, + z_i_w: &BlsScalar, alpha: &BlsScalar, beta: &BlsScalar, gamma: &BlsScalar, @@ -109,11 +109,11 @@ impl ProverKey { let s_sigma_3_eval = self.s_sigma_3.1[index]; let s_sigma_4_eval = self.s_sigma_4.1[index]; - let product = (a_w_i + (beta * s_sigma_1_eval) + gamma) - * (b_w_i + (beta * s_sigma_2_eval) + gamma) - * (o_w_i + (beta * s_sigma_3_eval) + gamma) - * (d_w_i + (beta * s_sigma_4_eval) + gamma) - * z_i_next + let product = (a_i + (beta * s_sigma_1_eval) + gamma) + * (b_i + (beta * s_sigma_2_eval) + gamma) + * (c_i + (beta * s_sigma_3_eval) + gamma) + * (d_i + (beta * s_sigma_4_eval) + gamma) + * z_i_w * alpha; -product @@ -131,7 +131,7 @@ impl ProverKey { &self, z_challenge: &BlsScalar, (alpha, beta, gamma): (&BlsScalar, &BlsScalar, &BlsScalar), - (a_eval, b_eval, o_eval, d_eval): ( + (a_eval, b_eval, c_eval, d_eval): ( &BlsScalar, &BlsScalar, &BlsScalar, @@ -146,13 +146,13 @@ impl ProverKey { z_poly: &Polynomial, ) -> Polynomial { let a = self.compute_linearizer_identity_range_check( - (a_eval, b_eval, o_eval, d_eval), + (a_eval, b_eval, c_eval, d_eval), z_challenge, (alpha, beta, gamma), z_poly, ); let b = self.compute_linearizer_copy_range_check( - (a_eval, b_eval, o_eval), + (a_eval, b_eval, c_eval), z_eval, sigma_1_eval, sigma_2_eval, @@ -172,10 +172,10 @@ impl ProverKey { &(&a + &b) + &c } // (a_eval + beta * z_challenge + gamma)(b_eval + beta * K1 * z_challenge + - // gamma)(o_eval + beta * K2 * z_challenge + gamma) * alpha z(X) + // gamma)(c_eval + beta * K2 * z_challenge + gamma) * alpha z(X) fn compute_linearizer_identity_range_check( &self, - (a_eval, b_eval, o_eval, d_eval): ( + (a_eval, b_eval, c_eval, d_eval): ( &BlsScalar, &BlsScalar, &BlsScalar, @@ -196,9 +196,9 @@ impl ProverKey { let mut a_1 = b_eval + beta_z_k1; a_1 += gamma; - // o_eval + beta * K2 * z_challenge + gamma + // c_eval + beta * K2 * z_challenge + gamma let beta_z_k2 = K2 * beta_z; - let mut a_2 = o_eval + beta_z_k2; + let mut a_2 = c_eval + beta_z_k2; a_2 += gamma; // d_eval + beta * K3 * z_challenge + gamma @@ -210,17 +210,17 @@ impl ProverKey { a *= a_2; a *= a_3; a *= alpha; // (a_eval + beta * z_challenge + gamma)(b_eval + beta * K1 * - // z_challenge + gamma)(o_eval + beta * K2 * z_challenge + gamma)(d_eval + // z_challenge + gamma)(c_eval + beta * K2 * z_challenge + gamma)(d_eval // + beta * K3 * z_challenge + gamma) * alpha z_poly * &a // (a_eval + beta * z_challenge + gamma)(b_eval + beta * K1 - // * z_challenge + gamma)(o_eval + beta * K2 * z_challenge + + // * z_challenge + gamma)(c_eval + beta * K2 * z_challenge + // gamma) * alpha z(X) } // -(a_eval + beta * sigma_1 + gamma)(b_eval + beta * sigma_2 + gamma) - // (o_eval + beta * sigma_3 + gamma) * beta *z_eval * alpha^2 * Sigma_4(X) + // (c_eval + beta * sigma_3 + gamma) * beta *z_eval * alpha^2 * Sigma_4(X) fn compute_linearizer_copy_range_check( &self, - (a_eval, b_eval, o_eval): (&BlsScalar, &BlsScalar, &BlsScalar), + (a_eval, b_eval, c_eval): (&BlsScalar, &BlsScalar, &BlsScalar), z_eval: &BlsScalar, sigma_1_eval: &BlsScalar, sigma_2_eval: &BlsScalar, @@ -238,9 +238,9 @@ impl ProverKey { let mut a_1 = b_eval + beta_sigma_2; a_1 += gamma; - // o_eval + beta * sigma_3 + gamma + // c_eval + beta * sigma_3 + gamma let beta_sigma_3 = beta * sigma_3_eval; - let mut a_2 = o_eval + beta_sigma_3; + let mut a_2 = c_eval + beta_sigma_3; a_2 += gamma; let beta_z_eval = beta * z_eval; @@ -248,10 +248,10 @@ impl ProverKey { let mut a = a_0 * a_1 * a_2; a *= beta_z_eval; a *= alpha; // (a_eval + beta * sigma_1 + gamma)(b_eval + beta * sigma_2 + - // gamma)(o_eval + beta * sigma_3 + gamma) * beta * z_eval * alpha + // gamma)(c_eval + beta * sigma_3 + gamma) * beta * z_eval * alpha s_sigma_4_poly * &-a // -(a_eval + beta * sigma_1 + gamma)(b_eval + - // beta * sigma_2 + gamma) (o_eval + beta * + // beta * sigma_2 + gamma) (c_eval + beta * // sigma_3 + gamma) * beta * z_eval * alpha^2 * // Sigma_4(X) } diff --git a/src/proof_system/widget/permutation/verifierkey.rs b/src/proof_system/widget/permutation/verifierkey.rs index 3052aee0..f5c21e5f 100644 --- a/src/proof_system/widget/permutation/verifierkey.rs +++ b/src/proof_system/widget/permutation/verifierkey.rs @@ -48,6 +48,7 @@ mod alloc { points: &mut Vec, evaluations: &ProofEvaluations, z_challenge: &BlsScalar, + u_challenge: &BlsScalar, (alpha, beta, gamma): (&BlsScalar, &BlsScalar, &BlsScalar), l1_eval: &BlsScalar, z_comm: G1Affine, @@ -56,7 +57,7 @@ mod alloc { // (a_eval + beta * z + gamma) // * (b_eval + beta * z * k1 + gamma) - // * (o_eval + beta * k2 * z + gamma) + // * (c_eval + beta * k2 * z + gamma) // * (d_eval + beta * k3 * z + gamma) * alpha let x = { let beta_z = beta * z_challenge; @@ -66,7 +67,7 @@ mod alloc { let q_1 = evaluations.b_eval + beta_k1_z + gamma; let beta_k2_z = beta * K2 * z_challenge; - let q_2 = evaluations.o_eval + beta_k2_z + gamma; + let q_2 = evaluations.c_eval + beta_k2_z + gamma; let beta_k3_z = beta * K3 * z_challenge; let q_3 = (evaluations.d_eval + beta_k3_z + gamma) * alpha; @@ -77,12 +78,12 @@ mod alloc { // l1(z) * alpha^2 let r = l1_eval * alpha_sq; - scalars.push(x + r); + scalars.push(x + r + u_challenge); points.push(z_comm); // -1 * (a_eval + beta * sigma_1_eval + gamma) // * (b_eval + beta * sigma_2_eval + gamma) - // * (o_eval + beta * sigma_3_eval + gamma) + // * (c_eval + beta * sigma_3_eval + gamma) // * alpha^2 let y = { let beta_sigma_1 = beta * evaluations.s_sigma_1_eval; @@ -92,9 +93,9 @@ mod alloc { let q_1 = evaluations.b_eval + beta_sigma_2 + gamma; let beta_sigma_3 = beta * evaluations.s_sigma_3_eval; - let q_2 = evaluations.o_eval + beta_sigma_3 + gamma; + let q_2 = evaluations.c_eval + beta_sigma_3 + gamma; - let q_3 = beta * evaluations.perm_eval * alpha; + let q_3 = beta * evaluations.z_eval * alpha; -(q_0 * q_1 * q_2 * q_3) }; diff --git a/src/proof_system/widget/range/proverkey.rs b/src/proof_system/widget/range/proverkey.rs index 1c54ae40..2a99efc5 100644 --- a/src/proof_system/widget/range/proverkey.rs +++ b/src/proof_system/widget/range/proverkey.rs @@ -5,6 +5,7 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use crate::fft::{Evaluations, Polynomial}; +use crate::proof_system::linearization_poly::ProofEvaluations; use dusk_bls12_381::BlsScalar; #[cfg(feature = "rkyv-impl")] @@ -32,11 +33,11 @@ impl ProverKey { &self, index: usize, range_separation_challenge: &BlsScalar, - a_w_i: &BlsScalar, - b_w_i: &BlsScalar, - o_w_i: &BlsScalar, - d_w_i: &BlsScalar, - d_w_i_next: &BlsScalar, + a_i: &BlsScalar, + b_i: &BlsScalar, + c_i: &BlsScalar, + d_i: &BlsScalar, + d_i_w: &BlsScalar, ) -> BlsScalar { let four = BlsScalar::from(4); let q_range_i = &self.q_range.1[index]; @@ -48,21 +49,17 @@ impl ProverKey { // Delta([o(X) - 4 * d(X)]) + Delta([b(X) - 4 * o(X)]) + Delta([a(X) - 4 // * b(X)]) + Delta([d(Xg) - 4 * a(X)]) * Q_Range(X) // - let b_1 = delta(o_w_i - four * d_w_i); - let b_2 = delta(b_w_i - four * o_w_i) * kappa; - let b_3 = delta(a_w_i - four * b_w_i) * kappa_sq; - let b_4 = delta(d_w_i_next - four * a_w_i) * kappa_cu; + let b_1 = delta(c_i - four * d_i); + let b_2 = delta(b_i - four * c_i) * kappa; + let b_3 = delta(a_i - four * b_i) * kappa_sq; + let b_4 = delta(d_i_w - four * a_i) * kappa_cu; (b_1 + b_2 + b_3 + b_4) * q_range_i * range_separation_challenge } pub(crate) fn compute_linearization( &self, range_separation_challenge: &BlsScalar, - a_eval: &BlsScalar, - b_eval: &BlsScalar, - o_eval: &BlsScalar, - d_eval: &BlsScalar, - d_next_eval: &BlsScalar, + evaluations: &ProofEvaluations, ) -> Polynomial { let four = BlsScalar::from(4); let q_range_poly = &self.q_range.0; @@ -71,13 +68,15 @@ impl ProverKey { let kappa_sq = kappa.square(); let kappa_cu = kappa_sq * kappa; - // Delta([o_eval - 4 * d_eval]) + Delta([b_eval - 4 * o_eval]) + - // Delta([a_eval - 4 * b_eval]) + Delta([d_next_eval - 4 * a_eval]) * + // Delta([c_eval - 4 * d_eval]) + Delta([b_eval - 4 * c_eval]) + + // Delta([a_eval - 4 * b_eval]) + Delta([d_w_eval - 4 * a_eval]) * // Q_Range(X) - let b_1 = delta(o_eval - four * d_eval); - let b_2 = delta(b_eval - four * o_eval) * kappa; - let b_3 = delta(a_eval - four * b_eval) * kappa_sq; - let b_4 = delta(d_next_eval - four * a_eval) * kappa_cu; + let b_1 = delta(evaluations.c_eval - four * evaluations.d_eval); + let b_2 = delta(evaluations.b_eval - four * evaluations.c_eval) * kappa; + let b_3 = + delta(evaluations.a_eval - four * evaluations.b_eval) * kappa_sq; + let b_4 = + delta(evaluations.d_w_eval - four * evaluations.a_eval) * kappa_cu; let t = (b_1 + b_2 + b_3 + b_4) * range_separation_challenge; diff --git a/src/proof_system/widget/range/verifierkey.rs b/src/proof_system/widget/range/verifierkey.rs index 6398688a..e32ebb68 100644 --- a/src/proof_system/widget/range/verifierkey.rs +++ b/src/proof_system/widget/range/verifierkey.rs @@ -49,14 +49,13 @@ mod alloc { let kappa_sq = kappa.square(); let kappa_cu = kappa_sq * kappa; - let b_1 = delta(evaluations.o_eval - (four * evaluations.d_eval)); + let b_1 = delta(evaluations.c_eval - (four * evaluations.d_eval)); let b_2 = - delta(evaluations.b_eval - four * evaluations.o_eval) * kappa; + delta(evaluations.b_eval - four * evaluations.c_eval) * kappa; let b_3 = delta(evaluations.a_eval - four * evaluations.b_eval) * kappa_sq; - let b_4 = - delta(evaluations.d_next_eval - (four * evaluations.a_eval)) - * kappa_cu; + let b_4 = delta(evaluations.d_w_eval - (four * evaluations.a_eval)) + * kappa_cu; scalars.push((b_1 + b_2 + b_3 + b_4) * range_separation_challenge); points.push(self.q_range.0); diff --git a/tests/append_gate.rs b/tests/append_gate.rs index 77e75ff6..9a06f210 100644 --- a/tests/append_gate.rs +++ b/tests/append_gate.rs @@ -18,7 +18,7 @@ fn append_gate() { pub struct TestCircuit { a: BlsScalar, b: BlsScalar, - o: BlsScalar, + c: BlsScalar, d: BlsScalar, public: BlsScalar, } @@ -27,20 +27,20 @@ fn append_gate() { pub fn new( a: BlsScalar, b: BlsScalar, - o: BlsScalar, + c: BlsScalar, d: BlsScalar, public: BlsScalar, ) -> Self { - Self { a, b, o, d, public } + Self { a, b, c, d, public } } } impl Circuit for TestCircuit { fn circuit(&self, composer: &mut Composer) -> Result<(), Error> { - let w_a = composer.append_witness(self.a); - let w_b = composer.append_witness(self.b); - let w_o = composer.append_witness(self.o); - let w_d = composer.append_witness(self.d); + let a = composer.append_witness(self.a); + let b = composer.append_witness(self.b); + let c = composer.append_witness(self.c); + let d = composer.append_witness(self.d); let constraint = Constraint::new() .left(1) @@ -48,10 +48,10 @@ fn append_gate() { .mult(1) .fourth(1) .output(1) - .a(w_a) - .b(w_b) - .o(w_o) - .d(w_d) + .a(a) + .b(b) + .c(c) + .d(d) .public(self.public) .constant(BlsScalar::zero()); @@ -71,10 +71,10 @@ fn append_gate() { let public = BlsScalar::zero(); let a = BlsScalar::zero(); let b = BlsScalar::zero(); - let o = BlsScalar::zero(); + let c = BlsScalar::zero(); let d = BlsScalar::zero(); let pi = vec![public]; - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); let pp = PublicParameters::setup(capacity, &mut rng) .expect("Creation of public parameter shouldn't fail"); let (prover, verifier) = Compiler::compile::(&pp, label) @@ -85,95 +85,95 @@ fn append_gate() { check_satisfied_circuit(&prover, &verifier, &pi, &circuit, &mut rng, &msg); // Test satisfied circuit: - // q_l·a + q_r·b + q_m·a·b + q_o·o + q_4·d + public + constant = 0 + // q_l·a + q_r·b + q_m·a·b + q_o·c + q_4·d + public + constant = 0 let msg = "Verification of satisfied circuit should pass"; let a = BlsScalar::one(); let b = BlsScalar::one(); - let o = -BlsScalar::from(4); + let c = -BlsScalar::from(4); let d = BlsScalar::one(); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_satisfied_circuit(&prover, &verifier, &pi, &circuit, &mut rng, &msg); // Test satisfied circuit: - // q_l·a + q_r·b + q_m·a·b + q_o·o + q_4·d + public + constant = 0 + // q_l·a + q_r·b + q_m·a·b + q_o·c + q_4·d + public + constant = 0 let msg = "Verification of satisfied circuit should pass"; let a = BlsScalar::one(); let b = BlsScalar::zero(); - let o = -BlsScalar::one(); + let c = -BlsScalar::one(); let d = BlsScalar::zero(); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_satisfied_circuit(&prover, &verifier, &pi, &circuit, &mut rng, &msg); // Test satisfied circuit: - // q_l·a + q_r·b + q_m·a·b + q_o·o + q_4·d + public + constant = 0 + // q_l·a + q_r·b + q_m·a·b + q_o·c + q_4·d + public + constant = 0 let msg = "Verification of satisfied circuit should pass"; let a = BlsScalar::zero(); let b = BlsScalar::one(); - let o = -BlsScalar::one(); + let c = -BlsScalar::one(); let d = BlsScalar::zero(); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_satisfied_circuit(&prover, &verifier, &pi, &circuit, &mut rng, &msg); // Test satisfied circuit: - // q_l·a + q_r·b + q_m·a·b + q_o·o + q_4·d + public + constant = 0 + // q_l·a + q_r·b + q_m·a·b + q_o·c + q_4·d + public + constant = 0 let msg = "Verification of satisfied circuit should pass"; let a = BlsScalar::one(); let b = BlsScalar::one(); - let o = -BlsScalar::from(3u64); + let c = -BlsScalar::from(3u64); let d = BlsScalar::zero(); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_satisfied_circuit(&prover, &verifier, &pi, &circuit, &mut rng, &msg); // Test satisfied circuit: - // q_l·a + q_r·b + q_m·a·b + q_o·o + q_4·d + public + constant = 0 + // q_l·a + q_r·b + q_m·a·b + q_o·c + q_4·d + public + constant = 0 let msg = "Verification of satisfied circuit should pass"; let a = -BlsScalar::one(); let b = BlsScalar::zero(); - let o = BlsScalar::zero(); + let c = BlsScalar::zero(); let d = BlsScalar::one(); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_satisfied_circuit(&prover, &verifier, &pi, &circuit, &mut rng, &msg); // Test satisfied circuit: - // q_l·a + q_r·b + q_m·a·b + q_o·o + q_4·d + public + constant = 0 + // q_l·a + q_r·b + q_m·a·b + q_o·c + q_4·d + public + constant = 0 let msg = "Verification of satisfied circuit should pass"; let a = BlsScalar::random(&mut rng); let b = BlsScalar::random(&mut rng); let d = BlsScalar::random(&mut rng); let public = BlsScalar::from(42); - let o = -(a + b + a * b + d + public); + let c = -(a + b + a * b + d + public); let pi = vec![public]; - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_satisfied_circuit(&prover, &verifier, &pi, &circuit, &mut rng, &msg); // Test unsatisfied circuit: let msg = "Proof creation of unsatisfied circuit should fail"; let a = BlsScalar::random(&mut rng); let b = BlsScalar::random(&mut rng); - let o = BlsScalar::random(&mut rng); + let c = BlsScalar::random(&mut rng); let d = BlsScalar::random(&mut rng); let public = BlsScalar::random(&mut rng); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_unsatisfied_circuit(&prover, &circuit, &mut rng, &msg); // Test unsatisfied circuit: - // q_l·a + q_r·b + q_m·a·b + q_o·o + q_4·d + public + constant = 0 + // q_l·a + q_r·b + q_m·a·b + q_o·c + q_4·d + public + constant = 0 let msg = "Proof creation of unsatisfied circuit should fail"; let a = BlsScalar::one(); let b = BlsScalar::one(); - let o = BlsScalar::one(); + let c = BlsScalar::one(); let d = BlsScalar::one(); let public = BlsScalar::one(); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_unsatisfied_circuit(&prover, &circuit, &mut rng, &msg); // Test unsatisfied circuit let msg = "Verification of unsatisfied circuit should pass"; let a = BlsScalar::one(); let b = BlsScalar::one(); - let o = BlsScalar::one(); + let c = BlsScalar::one(); let d = BlsScalar::one(); let public = BlsScalar::one(); - let circuit = TestCircuit::new(a, b, o, d, public); + let circuit = TestCircuit::new(a, b, c, d, public); check_unsatisfied_circuit(&prover, &circuit, &mut rng, &msg); }