From d2e5bb58fabfd3e84908596a976d551cef702f19 Mon Sep 17 00:00:00 2001 From: c r Date: Sun, 20 Aug 2023 00:56:44 -0400 Subject: [PATCH 1/3] catch up on unimplemented parallelism, Closes #62 (#66) * done * Commitment scheme (#67) * initial * go go go go * 21 * 14 * 0 --- .../src/plonk/composer/standard_composer.rs | 9 +- .../plonk/proof_system/commitment_scheme.rs | 322 ++++++++++++++++-- .../src/plonk/proof_system/prover/mod.rs | 28 +- .../src/plonk/proof_system/prover/test.rs | 21 +- .../proof_system/types/prover_settings.rs | 6 +- .../src/plonk/proof_system/verifier/mod.rs | 26 +- .../src/plonk/proof_system/verifier/test.rs | 36 +- .../src/polynomials/polynomial_arithmetic.rs | 268 ++++++++------- barustenberg/src/transcript.rs | 12 +- 9 files changed, 526 insertions(+), 202 deletions(-) diff --git a/barustenberg/src/plonk/composer/standard_composer.rs b/barustenberg/src/plonk/composer/standard_composer.rs index 6d8d589..651fc96 100644 --- a/barustenberg/src/plonk/composer/standard_composer.rs +++ b/barustenberg/src/plonk/composer/standard_composer.rs @@ -1103,7 +1103,7 @@ impl StandardComposer { /// It first computes the verification key, then constructs a `Verifier` /// using the computed key and the manifest of public inputs. /// Finally, it adds a `KateCommitmentScheme` to the verifier and returns it. - fn create_verifier(&mut self) -> Result>> { + fn create_verifier(&mut self) -> Result> { let cbd = self.cbd.clone(); let cbd = cbd.read().unwrap(); @@ -1113,7 +1113,8 @@ impl StandardComposer { self.create_manifest(cbd.public_inputs.len()), ); - output_state.commitment_scheme = Box::new(KateCommitmentScheme::new()); + output_state.commitment_scheme = + Box::new(KateCommitmentScheme::new(output_state.settings.clone())); Ok(output_state) } @@ -1129,7 +1130,7 @@ impl StandardComposer { /// # Returns /// /// * Returns an initialized `Prover`. - fn create_prover(&mut self) -> Prover> { + fn create_prover(&mut self) -> Prover { self.compute_proving_key(); self.compute_witness(); @@ -1154,7 +1155,7 @@ impl StandardComposer { .transition_widgets .push(Box::new(arithmetic_widget)); - output_state.commitment_scheme = KateCommitmentScheme::new(); + output_state.commitment_scheme = KateCommitmentScheme::new(output_state.settings.clone()); output_state } diff --git a/barustenberg/src/plonk/proof_system/commitment_scheme.rs b/barustenberg/src/plonk/proof_system/commitment_scheme.rs index a7f37d2..042b975 100644 --- a/barustenberg/src/plonk/proof_system/commitment_scheme.rs +++ b/barustenberg/src/plonk/proof_system/commitment_scheme.rs @@ -5,13 +5,16 @@ use std::sync::{Arc, RwLock}; use ark_bn254::{Fq, Fr, G1Affine}; use ark_ec::AffineRepr; use ark_ff::{FftField, Field, One, Zero}; +use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use crate::polynomials::{polynomial_arithmetic, Polynomial}; use crate::proof_system::work_queue::{Work, WorkItem, WorkQueue}; use crate::transcript::{BarretenHasher, Transcript}; use super::proving_key::ProvingKey; +use super::types::polynomial_manifest::PolynomialSource; use super::types::proof::CommitmentOpenProof; +use super::types::prover_settings::Settings; use super::verification_key::VerificationKey; /// A polynomial commitment scheme defined over two FieldExts, a group, a hash function. @@ -77,27 +80,37 @@ pub(crate) trait CommitmentScheme { #[derive(Default, Debug)] pub(crate) struct KateCommitmentScheme< + S: Settings, H: BarretenHasher, Fq: Field + FftField, Fr: Field + FftField, G: AffineRepr, > { _kate_open_proof: CommitmentOpenProof, + settings: S, phantom: PhantomData<(H, Fr, G, Fq)>, } -impl - KateCommitmentScheme +impl< + S: Settings, + H: BarretenHasher, + Fq: Field + FftField, + Fr: Field + FftField, + G: AffineRepr, + > KateCommitmentScheme { - pub(crate) fn new() -> Self { + pub(crate) fn new(settings: S) -> Self { Self { _kate_open_proof: CommitmentOpenProof::default(), + settings, phantom: PhantomData, } } } -impl CommitmentScheme for KateCommitmentScheme { +impl, H: BarretenHasher> CommitmentScheme + for KateCommitmentScheme +{ type Fq = Fq; type Fr = Fr; type Group = G1Affine; @@ -121,15 +134,82 @@ impl CommitmentScheme for KateCommitmentScheme, - _input_key: Option>>>, - _in_lagrange_form: bool, + transcript: &mut Transcript, + input_key: Option>>>, + in_lagrange_form: bool, ) { - todo!() + // In this function, we compute the evaluations of all polynomials in the polynomial manifest at the + // evaluation challenge "zeta", as well as the needed evaluations at shifts. + // + // We also allow this evaluation computation for lagrange (evaluation) forms of polynomials instead of + // the usual coefficient forms. + + // + let input_key = input_key.unwrap(); + let input_key = input_key.read().unwrap(); + + let zeta: Self::Fr = transcript.get_challenge_field_element("z", None); + let shifted_z = zeta * input_key.small_domain.root; + let n = input_key.small_domain.size; + + for i in 0..input_key.polynomial_manifest.len() { + let info = input_key.polynomial_manifest[i.into()].clone(); + let poly = input_key + .polynomial_store + .get(&info.polynomial_label) + .unwrap(); + let poly = &poly.read().unwrap().coefficients; + let poly_evaluation = if in_lagrange_form { + input_key + .small_domain + .compute_barycentric_evaluation(poly, n, &zeta) + } else { + polynomial_arithmetic::evaluate(poly, &zeta, n) + }; + + transcript.add_field_element("poly_eval", &poly_evaluation); + + if info.requires_shifted_evaluation { + let poly_evaluation = if in_lagrange_form { + // TODO is this a bug? Shouldn't we be using shifted_z instead of zeta? + input_key + .small_domain + .compute_barycentric_evaluation(poly, n, &zeta) + } else { + polynomial_arithmetic::evaluate(poly, &shifted_z, n) + }; + transcript.add_field_element( + format!("{}_omega", info.polynomial_label).as_str(), + &poly_evaluation, + ); + } + } } - fn compute_opening_polynomial(&self, _src: &[Fr], _dest: &mut [Fr], _z: &Fr, _n: usize) { - todo!() + fn compute_opening_polynomial(&self, src: &[Fr], dest: &mut [Fr], z_point: &Fr, n: usize) { + // open({cm_i}, {cm'_i}, {z, z'}, {s_i, s'_i}) + + // if `coeffs` represents F(X), we want to compute W(X) + // where W(X) = F(X) - F(z) / (X - z) + // i.e. divide by the degree-1 polynomial [-z, 1] + + // We assume that the commitment is well-formed and that there is no remainder term. + // Under these conditions we can perform this polynomial division in linear time with good constants. + // Note that the opening polynomial always has (n+1) coefficients for Standard/Turbo/Ultra due to + // the blinding of the quotient polynomial parts. + let f = polynomial_arithmetic::evaluate(src, z_point, n + 1); + + // compute (1 / -z) + let divisor = -z_point.inverse().unwrap(); + + // we're about to shove these coefficients into a pippenger multi-exponentiation routine, where we need + // to convert out of montgomery form. So, we can use lazy reduction techniques here without triggering overflows + dest[0] = src[0] - f; + dest[0] *= divisor; + for i in 1..n { + dest[i] = src[i] - dest[i - 1]; + dest[i] *= divisor; + } } fn generic_batch_open( @@ -224,21 +304,225 @@ impl CommitmentScheme for KateCommitmentScheme, - _queue: &mut WorkQueue, - _input_key: Option>>>, + transcript: &Transcript, + queue: &mut WorkQueue, + input_key: Option>>>, ) { - todo!() + let input_key = input_key.unwrap(); + let mut input_key = input_key.write().unwrap(); + /* + Compute batch opening polynomials according to the Kate commitment scheme. + + Step 1: Compute the polynomial F(X) s.t. W_{\zeta}(X) = (F(X) - F(\zeta))/(X - \zeta) defined in round 5 of the + PLONK paper. Step 2: Compute the polynomial z(X) s.t. W_{\zeta \omega}(X) = (z(X) - z(\zeta \omega))/(X - + \zeta.\omega). Step 3: Compute coefficient form of W_{\zeta}(X) and W_{\zeta \omega}(X). Step 4: Commit to + W_{\zeta}(X) and W_{\zeta \omega}(X). + */ + let mut opened_polynomials_at_zeta: Vec<(Arc>>, Fr)> = Vec::new(); + let mut opened_polynomials_at_zeta_omega: Vec<(Arc>>, Fr)> = + Vec::new(); + + // Add the following tuples to the above data structures: + // + // [a(X), nu_1], [b(X), nu_2], [c(X), nu_3], + // [S_{\sigma_1}(X), nu_4], [S_{\sigma_2}(X), nu_5], + // [z(X), nu_6] + // + // Note that the challenges nu_1, ..., nu_6 depend on the label of the respective polynomial. + + // Add challenge-poly tuples for all polynomials in the manifest + for i in 0..input_key.polynomial_manifest.len() { + let info = &input_key.polynomial_manifest[i.into()]; + let poly_label = &info.polynomial_label; + + let poly = input_key.polynomial_store.get(poly_label).unwrap(); + + let nu_challenge = transcript.get_challenge_field_element_from_map("nu", poly_label); + opened_polynomials_at_zeta.push((poly.clone(), nu_challenge)); + + if info.requires_shifted_evaluation { + let nu_challenge = transcript + .get_challenge_field_element_from_map("nu", &format!("{}_omega", poly_label)); + opened_polynomials_at_zeta_omega.push((poly, nu_challenge)); + } + } + + let zeta: Fr = transcript.get_challenge_field_element("z", None); + + // Note: the opening poly W_\frak{z} is always size (n + 1) due to blinding + // of the quotient polynomial + let opening_poly: Arc>> = + Arc::new(RwLock::new(Polynomial::new(input_key.circuit_size + 1))); + let shifted_opening_poly: Arc>> = + Arc::new(RwLock::new(Polynomial::new(input_key.circuit_size))); + + // Add the tuples [t_{mid}(X), \zeta^{n}], [t_{high}(X), \zeta^{2n}] + // Note: We don't need to include the t_{low}(X) since it is multiplied by 1 for combining with other witness + // polynomials. + // + for i in 1..self.settings.program_width() { + let offset = i * input_key.small_domain.size; + let scalar = zeta.pow([offset as u64]); + opened_polynomials_at_zeta + .push((input_key.quotient_polynomial_parts[i].clone(), scalar)); + } + + // Add up things to get coefficients of opening polynomials. + // TODO THESE LOCKS ARE FUCKED. UP. THEY WILL BE UNDER HEAVY CONTENTION. FIX THEM + (0..input_key.small_domain.size) + .into_par_iter() + .for_each(|i| { + let mut opening_poly = opening_poly.write().unwrap(); + opening_poly[i] = input_key.quotient_polynomial_parts[0].read().unwrap()[i]; + for &(ref poly, challenge) in &opened_polynomials_at_zeta { + opening_poly[i] += (*poly).read().unwrap()[i] * challenge; + } + let mut shifted_opening_poly = shifted_opening_poly.write().unwrap(); + shifted_opening_poly[i] = Fr::zero(); + for &(ref poly, challenge) in &opened_polynomials_at_zeta_omega { + shifted_opening_poly[i] += (*poly).read().unwrap()[i] * challenge; + } + }); + + let opening_poly = Arc::try_unwrap(opening_poly).unwrap(); + let opening_poly = opening_poly.into_inner(); + let mut opening_poly = opening_poly.unwrap(); + let shifted_opening_poly = Arc::try_unwrap(shifted_opening_poly).unwrap(); + let shifted_opening_poly = shifted_opening_poly.into_inner(); + let shifted_opening_poly = shifted_opening_poly.unwrap(); + + // Adjust the (n + 1)th coefficient of t_{0,1,2}(X) or r(X) (Note: t_4 (Turbo/Ultra) has only n coefficients) + opening_poly[input_key.circuit_size] = Fr::zero(); + let zeta_pow_n = zeta.pow([input_key.circuit_size as u64]); + + let num_deg_n_poly = if self.settings.program_width() == 3 { + self.settings.program_width() + } else { + self.settings.program_width() - 1 + }; + let mut scalar_mult = Fr::one(); + for i in 0..num_deg_n_poly { + opening_poly[input_key.circuit_size] += + input_key.quotient_polynomial_parts[i].read().unwrap()[input_key.circuit_size] + * scalar_mult; + scalar_mult *= zeta_pow_n; + } + + // Compute the shifted evaluation point \frak{z}*omega + let zeta_omega = zeta * input_key.small_domain.root; + + // Compute the W_{\zeta}(X) and W_{\zeta \omega}(X) polynomials + self.compute_opening_polynomial( + &[opening_poly[0]], + &mut [opening_poly[0]], + &zeta, + input_key.circuit_size, + ); + self.compute_opening_polynomial( + &[shifted_opening_poly[0]], + &mut [shifted_opening_poly[0]], + &zeta_omega, + input_key.circuit_size, + ); + + input_key + .polynomial_store + .put("opening_poly".to_string(), opening_poly); + input_key + .polynomial_store + .put("shifted_opening_poly".to_string(), shifted_opening_poly); + + // Commit to the opening and shifted opening polynomials + self.commit( + input_key + .polynomial_store + .get(&"opening_poly".to_string()) + .unwrap(), + "PI_Z".to_owned(), + Fr::from(input_key.circuit_size as u64), + queue, + ); + self.commit( + input_key + .polynomial_store + .get(&"shifted_opening_poly".to_string()) + .unwrap(), + "PI_Z_OMEGA".to_owned(), + Fr::from(input_key.circuit_size as u64), + queue, + ); } fn batch_verify( &self, - _transcript: &Transcript, - _kate_g1_elements: &mut HashMap, - _kate_fr_elements: &mut HashMap, - _input_key: Option<&VerificationKey>, + transcript: &Transcript, + kate_g1_elements: &mut HashMap, + kate_fr_elements: &mut HashMap, + input_key: Option<&VerificationKey>, ) { - todo!() + let mut batch_eval = Fr::zero(); + let polynomial_manifest = &input_key.as_ref().unwrap().polynomial_manifest; + for i in 0..polynomial_manifest.len() { + let item = &polynomial_manifest[i.into()]; + let label = item.commitment_label.clone(); + let poly_label = item.polynomial_label.clone(); + match item.source { + PolynomialSource::Witness => { + let element: G1Affine = transcript.get_group_element(&label); + // removed || element.is_point_at_infinity() + if !element.is_on_curve() { + panic!("polynomial commitment to witness is not a valid point."); + } + kate_g1_elements.insert(label.clone(), element); + } + PolynomialSource::Selector | PolynomialSource::Permutation => { + let element = input_key.as_ref().unwrap().commitments.get(&label).unwrap(); + if !element.is_on_curve() { + panic!("polynomial commitment to selector is not a valid point."); + } + kate_g1_elements.insert(label.clone(), *element); + } + PolynomialSource::Other => {} + } + + let has_shifted_evaluation = item.requires_shifted_evaluation; + let mut kate_fr_scalar = Fr::zero(); + if has_shifted_evaluation { + let challenge: Fr = transcript + .get_challenge_field_element_from_map("nu", &format!("{}_omega", poly_label)); + let separator_challenge: Fr = + transcript.get_challenge_field_element("separator", Some(0)); + kate_fr_scalar += separator_challenge * challenge; + let poly_at_zeta_omega: Fr = + transcript.get_field_element(&format!("{}_omega", poly_label)); + batch_eval += separator_challenge * challenge * poly_at_zeta_omega; + } + + let challenge: Fr = transcript.get_challenge_field_element_from_map("nu", &poly_label); + kate_fr_scalar += challenge; + let poly_at_zeta: Fr = transcript.get_field_element(&poly_label); + batch_eval += challenge * poly_at_zeta; + kate_fr_elements.insert(label, kate_fr_scalar); + } + + let zeta: Fr = transcript.get_challenge_field_element("z", None); + let quotient_challenge: Fr = transcript.get_challenge_field_element_from_map("nu", "t"); + + let z_pow_n = zeta.pow([input_key.as_ref().unwrap().circuit_size as u64]); + let mut z_power = Fr::one(); + for i in 0..self.settings.program_width() { + let quotient_label = format!("T_{}", i + 1); + let element = transcript.get_group_element("ient_label); + kate_g1_elements.insert(quotient_label.clone(), element); + kate_fr_elements.insert(quotient_label, quotient_challenge * z_power); + z_power *= z_pow_n; + } + + let quotient_eval: Fr = transcript.get_field_element("t"); + batch_eval += quotient_eval * quotient_challenge; + + kate_g1_elements.insert("BATCH_EVALUATION".to_string(), G1Affine::identity()); + kate_fr_elements.insert("BATCH_EVALUATION".to_string(), -batch_eval); } } diff --git a/barustenberg/src/plonk/proof_system/prover/mod.rs b/barustenberg/src/plonk/proof_system/prover/mod.rs index 9f4895f..c9d8143 100644 --- a/barustenberg/src/plonk/proof_system/prover/mod.rs +++ b/barustenberg/src/plonk/proof_system/prover/mod.rs @@ -7,7 +7,10 @@ use rand::RngCore; use super::{ commitment_scheme::{CommitmentScheme, KateCommitmentScheme}, proving_key::ProvingKey, - types::{prover_settings::Settings, Proof}, + types::{ + prover_settings::{Settings, StandardSettings}, + Proof, + }, widgets::{ random_widgets::random_widget::ProverRandomWidget, transition_widgets::transition_widget::TransitionWidgetBase, @@ -32,22 +35,18 @@ mod test; // todo https://doc.rust-lang.org/reference/const_eval.html /// Plonk prover. #[derive(Debug)] -pub struct Prover> { +pub struct Prover { pub(crate) circuit_size: usize, pub(crate) transcript: Arc>>, pub(crate) key: Arc>>, pub(crate) queue: WorkQueue, pub(crate) random_widgets: Vec>>, pub(crate) transition_widgets: Vec>>, - pub(crate) commitment_scheme: KateCommitmentScheme, - pub(crate) settings: S, + pub(crate) commitment_scheme: KateCommitmentScheme, H, Fq, Fr, G1Affine>, + pub(crate) settings: StandardSettings, } -impl< - H: BarretenHasher + Default, - S: Settings + Default, - > Prover -{ +impl Prover { /// Create a new prover. /// Parameters: /// - `input_key` Proving key. @@ -58,7 +57,7 @@ impl< pub fn new( input_key: Option>>>, input_manifest: Option, - input_settings: Option, + input_settings: Option>, ) -> Self { let circuit_size = input_key .as_ref() @@ -81,15 +80,16 @@ impl< queue, random_widgets: Vec::new(), transition_widgets: Vec::new(), - commitment_scheme: KateCommitmentScheme::::default(), + commitment_scheme: + KateCommitmentScheme::, H, Fq, Fr, G1Affine>::new( + settings.clone(), + ), settings, } } } -impl> - Prover -{ +impl Prover { fn _copy_placeholder(&self) { todo!("LOOK AT THE COMMENTS IN PROVERBASE"); } diff --git a/barustenberg/src/plonk/proof_system/prover/test.rs b/barustenberg/src/plonk/proof_system/prover/test.rs index f78fdcc..43cef53 100644 --- a/barustenberg/src/plonk/proof_system/prover/test.rs +++ b/barustenberg/src/plonk/proof_system/prover/test.rs @@ -4,9 +4,7 @@ use crate::{ plonk::{ composer::composer_base::ComposerType, proof_system::{ - commitment_scheme::KateCommitmentScheme, proving_key::ProvingKey, - types::prover_settings::StandardSettings, utils::permutation::compute_permutation_lagrange_base_single, widgets::{ random_widgets::permutation_widget::ProverPermutationWidget, @@ -18,7 +16,7 @@ use crate::{ srs::reference_string::file_reference_string::FileReferenceString, transcript::{BarretenHasher, Keccak256, Manifest, ManifestEntry, RoundManifest}, }; -use ark_bn254::{Fq, Fr, G1Affine}; +use ark_bn254::Fr; use ark_ff::{One, UniformRand, Zero}; use super::Prover; @@ -252,14 +250,11 @@ fn create_manifest(num_public_inputs: usize) -> Manifest { ]) } -fn generate_test_data( - n: usize, -) -> Prover> { +fn generate_test_data(n: usize) -> Prover { // create some constraints that satisfy our arithmetic circuit relation - let reference_string = Arc::new(RwLock::new(FileReferenceString::new( - n + 1, - "./src/srs_db/ignition", - ).unwrap())); + let reference_string = Arc::new(RwLock::new( + FileReferenceString::new(n + 1, "./src/srs_db/ignition").unwrap(), + )); let key = Arc::new(RwLock::new(ProvingKey::new( n, 0, @@ -514,13 +509,9 @@ fn generate_test_data( let widget: Box> = Box::new(ProverArithmeticWidget::::new(key.clone())); - let kate_commitment_scheme = KateCommitmentScheme::::new(); - - let mut state: Prover> = - Prover::new(Some(key), Some(create_manifest(0)), None); + let mut state: Prover = Prover::new(Some(key), Some(create_manifest(0)), None); state.random_widgets.push(permutation_widget); state.transition_widgets.push(widget); - state.commitment_scheme = kate_commitment_scheme; state } diff --git a/barustenberg/src/plonk/proof_system/types/prover_settings.rs b/barustenberg/src/plonk/proof_system/types/prover_settings.rs index 41d4248..41e4478 100644 --- a/barustenberg/src/plonk/proof_system/types/prover_settings.rs +++ b/barustenberg/src/plonk/proof_system/types/prover_settings.rs @@ -12,7 +12,7 @@ use crate::{ // TODO bevy_reflect? or what // or inline everything! -pub trait Settings: Sized { +pub(crate) trait Settings: Sized { type Hasher: BarretenHasher; type Field: Field + FftField; type Group: AffineRepr; @@ -48,8 +48,8 @@ pub trait Settings: Sized { fn hasher(&self) -> &Self::Hasher; } -#[derive(Default, Debug)] -pub(crate) struct StandardSettings { +#[derive(Default, Debug, Clone, Copy)] +pub struct StandardSettings { hasher: H, } diff --git a/barustenberg/src/plonk/proof_system/verifier/mod.rs b/barustenberg/src/plonk/proof_system/verifier/mod.rs index 467b696..8978f3b 100644 --- a/barustenberg/src/plonk/proof_system/verifier/mod.rs +++ b/barustenberg/src/plonk/proof_system/verifier/mod.rs @@ -14,7 +14,10 @@ use ark_ff::{BigInteger, Field, One, Zero}; use super::{ commitment_scheme::{CommitmentScheme, KateCommitmentScheme}, - types::{prover_settings::Settings, Proof}, + types::{ + prover_settings::{Settings, StandardSettings}, + Proof, + }, }; use std::collections::HashMap; @@ -29,17 +32,18 @@ mod test; /// Verifier struct #[derive(Debug)] -pub struct Verifier> { - settings: S, +pub struct Verifier { + pub(crate) settings: StandardSettings, key: Arc>>, manifest: Manifest, kate_g1_elements: HashMap, kate_fr_elements: HashMap, - pub(crate) commitment_scheme: Box>, + pub(crate) commitment_scheme: + Box, H, Fq, Fr, G1Affine>>, } /// verifier interface -impl> Verifier { +impl Verifier { /// Constructor pub fn new( _verifier_key: Option>>>, @@ -139,7 +143,7 @@ impl> V // compute the quotient polynomial numerator contribution let t_numerator_eval = Fr::zero(); - S::compute_quotient_evaluation_contribution( + StandardSettings::::compute_quotient_evaluation_contribution( &(*self.key).read().unwrap(), &alpha, &transcript, @@ -188,7 +192,7 @@ impl> V // Again, we dont actually compute the MSMs and just accumulate scalars and group elements and postpone MSM to last // step. // - S::append_scalar_multiplication_inputs( + StandardSettings::::append_scalar_multiplication_inputs( &(*self.key).read().unwrap(), &alpha, &transcript, @@ -314,7 +318,13 @@ impl> V // TODO: Optimize by precomputing miller lines for G2 let q: [G2Affine; 2] = [ G2Affine::generator(), - (*self.key).read().unwrap().reference_string.read().unwrap().get_g2x(), + (*self.key) + .read() + .unwrap() + .reference_string + .read() + .unwrap() + .get_g2x(), ]; let result: Fq12 = Bn254::multi_pairing(p, q).0; diff --git a/barustenberg/src/plonk/proof_system/verifier/test.rs b/barustenberg/src/plonk/proof_system/verifier/test.rs index 04e6bae..4bd4962 100644 --- a/barustenberg/src/plonk/proof_system/verifier/test.rs +++ b/barustenberg/src/plonk/proof_system/verifier/test.rs @@ -24,11 +24,9 @@ use ark_ff::UniformRand; use anyhow::Result; -use anyhow::Result; - use super::*; -impl> Verifier { +impl Verifier { pub fn generate_verifier( circuit_proving_key: Arc>>, ) -> Result { @@ -144,20 +142,23 @@ impl> V ComposerType::Standard.create_manifest(0), ); - let kate_commitment_scheme = Box::new(KateCommitmentScheme::::new()); + let kate_commitment_scheme = Box::new(KateCommitmentScheme::< + StandardSettings, + H, + Fq, + Fr, + G1Affine, + >::new(verifier.settings.clone())); verifier.commitment_scheme = kate_commitment_scheme; Ok(verifier) } } -fn generate_test_data<'a, H: BarretenHasher + Default + 'static>( - n: usize, -) -> Prover> { +fn generate_test_data<'a, H: BarretenHasher + Default + 'static>(n: usize) -> Prover { // create some constraints that satisfy our arithmetic circuit relation - let crs = Arc::new(RwLock::new(FileReferenceString::new( - n + 1, - "./src/srs_db/ignition", - ).unwrap())); + let crs = Arc::new(RwLock::new( + FileReferenceString::new(n + 1, "./src/srs_db/ignition").unwrap(), + )); let key = Arc::new(RwLock::new(ProvingKey::new( n, 0, @@ -397,16 +398,13 @@ fn generate_test_data<'a, H: BarretenHasher + Default + 'static>( let widget: Box> = Box::new(ProverArithmeticWidget::::new(key.clone())); - let kate_commitment_scheme = KateCommitmentScheme::::new(); - - let mut state: Prover> = Prover::new( + let mut state: Prover = Prover::new( Some(key), Some(ComposerType::Standard.create_manifest(0)), None, ); state.random_widgets.push(permutation_widget); state.transition_widgets.push(widget); - state.commitment_scheme = kate_commitment_scheme; state } @@ -419,7 +417,7 @@ fn verify_arithmetic_proof_small() { // Construct proof let proof = state.construct_proof().unwrap(); - let mut verifier: Verifier> = + let mut verifier: Verifier = Verifier::generate_verifier::(state.key).unwrap(); // Verify proof @@ -433,13 +431,13 @@ fn verify_arithmetic_proof() { let n = 1 << 14; let mut state = generate_test_data::(n); - let _verifier: Verifier> = + let _verifier: Verifier = Verifier::generate_verifier::(state.key.clone()).unwrap(); // Construct proof let proof = state.construct_proof().unwrap(); - let mut verifier: Verifier> = + let mut verifier: Verifier = Verifier::generate_verifier::(state.key.clone()).unwrap(); // Verify proof @@ -454,7 +452,7 @@ fn verify_damaged_proof() { let n = 8; let state = generate_test_data::(n); - let mut verifier: Verifier> = + let mut verifier: Verifier = Verifier::generate_verifier::(state.key).unwrap(); // Create empty proof diff --git a/barustenberg/src/polynomials/polynomial_arithmetic.rs b/barustenberg/src/polynomials/polynomial_arithmetic.rs index d57f584..720185e 100644 --- a/barustenberg/src/polynomials/polynomial_arithmetic.rs +++ b/barustenberg/src/polynomials/polynomial_arithmetic.rs @@ -33,6 +33,8 @@ use ark_ff::batch_inversion; use ark_ff::{FftField, Field}; use anyhow::Result; +use rayon::iter::ParallelIterator; +use rayon::prelude::IntoParallelIterator; use crate::{common::max_threads::compute_num_threads, numeric::bitop::Msb}; @@ -152,19 +154,16 @@ pub(crate) fn copy_polynomial( .copy_from_slice(&src.coefficients[..num_src_coefficients]); if num_target_coefficients > num_src_coefficients { - // fill out the polynomial coefficients with zeroes - for item in dest - .coefficients - .iter_mut() - .take(num_target_coefficients) - .skip(num_src_coefficients) - { - *item = Fr::default(); + for j in num_src_coefficients..num_target_coefficients { + unsafe { + *(dest.coefficients.as_ptr() as *mut Fr).add(j) = Fr::zero(); + } } } } use std::ops::{Add, Mul, Sub}; +use std::sync::RwLock; use super::{evaluation_domain::EvaluationDomain, Polynomial}; @@ -272,18 +271,20 @@ impl EvaluationDomain { generator_shift: Fr, generator_size: usize, ) { - // TODO: parallelize - for j in 0..self.num_threads { + (0..self.num_threads).into_par_iter().for_each(|j| { let thread_shift = generator_shift.pow([(j * (generator_size / self.num_threads)) as u64]); let mut work_generator = generator_start * thread_shift; let offset = j * (generator_size / self.num_threads); let end = offset + (generator_size / self.num_threads); - for coeff_i in coeffs.iter_mut().take(end).skip(offset) { - *coeff_i *= work_generator; + + for i in offset..end { + unsafe { + *(coeffs.as_ptr() as *mut Fr).add(i) *= work_generator; + } work_generator *= generator_shift; } - } + }); } /// modifies target[..generator_size] @@ -295,18 +296,20 @@ impl EvaluationDomain { generator_shift: Fr, generator_size: usize, ) { - // TODO: parallelize - for j in 0..self.num_threads { + (0..self.num_threads).into_par_iter().for_each(|j| { let thread_shift = generator_shift.pow([(j * (generator_size / self.num_threads)) as u64]); let mut work_generator = generator_start * thread_shift; let offset = j * (generator_size / self.num_threads); let end = offset + (generator_size / self.num_threads); + #[allow(clippy::needless_range_loop)] for i in offset..end { - target[i] = coeffs[i] * work_generator; + unsafe { + *(target.as_ptr() as *mut Fr).add(i) = coeffs[i] * work_generator; + } work_generator *= generator_shift; } - } + }) } /// Compute multiplicative subgroup (g.X)^n. @@ -341,16 +344,13 @@ impl EvaluationDomain { Ok(()) } - // TODO readd pragma omp parallel pub(crate) fn fft_inner_parallel_vec_inplace( &self, coeffs: &mut [&mut [Fr]], _fr: &Fr, root_table: &[&[Fr]], ) { - //let scratch_space = Self::get_scratch_space(self.size); // Implement the get_scratch_space function - - let mut scratch_space = vec![Fr::zero(); self.size]; + let scratch_space = vec![Fr::zero(); self.size]; let num_polys = coeffs.len(); assert!(num_polys.is_power_of_two()); @@ -361,7 +361,7 @@ impl EvaluationDomain { // First FFT round is a special case - no need to multiply by root table, because all entries are 1. // We also combine the bit reversal step into the first round, to avoid a redundant round of copying data - for j in 0..self.num_threads { + (0..self.num_threads).into_par_iter().for_each(|j| { let mut temp_1; let mut temp_2; for i in (j * self.thread_size..(j + 1) * self.thread_size).step_by(2) { @@ -378,10 +378,12 @@ impl EvaluationDomain { temp_1 = coeffs[poly_idx_1][elem_idx_1]; temp_2 = coeffs[poly_idx_2][elem_idx_2]; - scratch_space[i + 1] = temp_1 - temp_2; - scratch_space[i] = temp_1 + temp_2; + unsafe { + *(scratch_space.as_ptr() as *mut Fr).add(i + 1) = temp_1 - temp_2; + *(scratch_space.as_ptr() as *mut Fr).add(i) = temp_1 + temp_2; + } } - } + }); // hard code exception for when the domain size is tiny - we won't execute the next loop, so need to manually // reduce + copy @@ -392,7 +394,7 @@ impl EvaluationDomain { // Outer FFT loop - iterates over the FFT rounds let mut m = 2; while m < self.size { - for j in 0..self.num_threads { + (0..self.num_threads).into_par_iter().for_each(|j| { let mut temp: Fr; // Ok! So, what's going on here? This is the inner loop of the FFT algorithm, and we want to break it @@ -452,8 +454,12 @@ impl EvaluationDomain { let k1 = (i & index_mask) << 1; let j1 = i & block_mask; temp = round_roots[j1] * scratch_space[k1 + j1 + m]; - scratch_space[k1 + j1 + m] = scratch_space[k1 + j1] - temp; - scratch_space[k1 + j1] += temp; + unsafe { + *(scratch_space.as_ptr() as *mut Fr).add(k1 + j1 + m) = + scratch_space[k1 + j1] - temp; + *(scratch_space.as_ptr() as *mut Fr).add(k1 + j1) = + scratch_space[k1 + j1] + temp; + } } } else { for i in start..end { @@ -466,16 +472,19 @@ impl EvaluationDomain { let elem_idx_2 = (k1 + j1 + m) & poly_mask; temp = round_roots[j1] * scratch_space[k1 + j1 + m]; - coeffs[poly_idx_2][elem_idx_2] = scratch_space[k1 + j1] - temp; - coeffs[poly_idx_1][elem_idx_1] = scratch_space[k1 + j1] + temp; + unsafe { + *(coeffs[poly_idx_2].as_ptr() as *mut Fr).add(elem_idx_2) = + scratch_space[k1 + j1] - temp; + *(coeffs[poly_idx_1].as_ptr() as *mut Fr).add(elem_idx_1) = + scratch_space[k1 + j1] + temp; + } } } - } + }); m <<= 1; } } - // TODO readd pragma omp parallel pub(crate) fn fft_inner_parallel( &self, coeffs: &mut [Fr], @@ -483,10 +492,9 @@ impl EvaluationDomain { _fr: &Fr, root_table: &[&[Fr]], ) { - // TODO parallelize // First FFT round is a special case - no need to multiply by root table, because all entries are 1. // We also combine the bit reversal step into the first round, to avoid a redundant round of copying data - (0..self.num_threads).for_each(|j| { + (0..self.num_threads).into_par_iter().for_each(|j| { let mut temp_1; let mut temp_2; let thread_start = j * self.thread_size; @@ -502,8 +510,10 @@ impl EvaluationDomain { temp_1 = coeffs[swap_index_1]; temp_2 = coeffs[swap_index_2]; - target[i + 1] = temp_1 - temp_2; - target[i] = temp_1 + temp_2; + unsafe { + *(target.as_ptr() as *mut Fr).add(i + 1) = temp_1 - temp_2; + *(target.as_ptr() as *mut Fr).add(i) = temp_1 + temp_2; + } } }); @@ -517,7 +527,7 @@ impl EvaluationDomain { // outer FFT loop // TODO this is super incorrect for m in (2..self.size).step_by(2) { - (0..self.num_threads).for_each(|j| { + (0..self.num_threads).into_par_iter().for_each(|j| { let mut temp; let start = j * (self.thread_size >> 1); @@ -532,8 +542,10 @@ impl EvaluationDomain { let k1 = (i & index_mask) << 1; let j1 = i & block_mask; temp = round_roots[j1] * target[k1 + j1 + m]; - target[k1 + j1 + m] = target[k1 + j1] - temp; - target[k1 + j1] += temp; + unsafe { + *(target.as_ptr() as *mut Fr).add(k1 + j1 + m) = target[k1 + j1] - temp; + *(target.as_ptr() as *mut Fr).add(k1 + j1) = target[k1 + j1] + temp; + } } }); } @@ -601,7 +613,7 @@ impl EvaluationDomain { let small_domain = EvaluationDomain::::new(n, None); // iterate for s = 0, 1, 2, 3 to compute R_{i,s} - for j in 0..small_domain.num_threads { + (0..small_domain.num_threads).into_par_iter().for_each(|j| { let internal_bound_start = j * small_domain.thread_size; let internal_bound_end = (j + 1) * small_domain.thread_size; for i in internal_bound_start..internal_bound_end { @@ -611,10 +623,13 @@ impl EvaluationDomain { coeffs[i + 2 * n], coeffs[i + 3 * n], ]; - coeffs[i] = Fr::zero(); - coeffs[i + n] = Fr::zero(); - coeffs[i + 2 * n] = Fr::zero(); - coeffs[i + 3 * n] = Fr::zero(); + + unsafe { + *(coeffs.as_ptr() as *mut Fr).add(i) = Fr::zero(); + *(coeffs.as_ptr() as *mut Fr).add(i + n) = Fr::zero(); + *(coeffs.as_ptr() as *mut Fr).add(i + 2 * n) = Fr::zero(); + *(coeffs.as_ptr() as *mut Fr).add(i + 3 * n) = Fr::zero(); + } let mut index; let mut root_index; @@ -633,15 +648,20 @@ impl EvaluationDomain { if root_index >= m { root_multiplier = -round_roots[root_index & half_mask]; } - coeffs[(3 - s) * n + i] += root_multiplier * t_j; + unsafe { + *(coeffs.as_ptr() as *mut Fr).add((3 - s) * n + i) += + root_multiplier * t_j; + } } if is_coset { temp_constant *= self.generator; - coeffs[(3 - s) * n + i] *= temp_constant; + unsafe { + *(coeffs.as_ptr() as *mut Fr).add((3 - s) * n + i) *= temp_constant; + } } } } - } + }); } pub(crate) fn partial_fft_serial(&self, coeffs: &mut [Fr], target: &mut [Fr]) { @@ -677,16 +697,13 @@ impl EvaluationDomain { &self.root_inverse, &self.get_inverse_round_roots()[..], ); - // todo parallelize - for j in 0..self.num_threads { - for coeffs_i in coeffs - .iter_mut() - .take((j + 1) * self.thread_size) - .skip(j * self.thread_size) - { - *coeffs_i *= self.domain_inverse; + (0..self.num_threads).into_par_iter().for_each(|j| { + for i in (j * self.thread_size)..((j + 1) * self.thread_size) { + unsafe { + *(coeffs.as_ptr() as *mut Fr).add(i) *= self.domain_inverse; + } } - } + }) } pub(crate) fn ifft(&self, coeffs: &mut [Fr], target: &mut [Fr]) { @@ -696,11 +713,10 @@ impl EvaluationDomain { &self.root_inverse, &self.get_round_roots()[..], ); - // TODO parallelize me - todo!("parallelize here") - // for i in 0..self.size { - // target[i] *= self.domain_inverse; - // } + + (0..self.size).into_par_iter().for_each(|i| unsafe { + *(target.as_ptr() as *mut Fr).add(i) *= self.domain_inverse; + }); } pub(crate) fn ifft_vec_inplace(&self, coeffs: &mut [&mut [Fr]]) { @@ -717,12 +733,14 @@ impl EvaluationDomain { let poly_mask = poly_size - 1; let log2_poly_size = poly_size.get_msb(); - // todo!("parallelize") - for j in 0..self.num_threads { + (0..self.num_threads).into_par_iter().for_each(|j| { for i in j * self.thread_size..(j + 1) * self.thread_size { - coeffs[i >> log2_poly_size][i & poly_mask] *= self.domain_inverse; + unsafe { + *(coeffs[i >> log2_poly_size].as_ptr() as *mut Fr).add(i & poly_mask) *= + self.domain_inverse; + } } - } + }); } fn ifft_with_constant(&self, _coeffs: &mut [Fr], _value: Fr) { todo!(); @@ -817,17 +835,21 @@ impl EvaluationDomain { } if domain_extension == 4 { - // TODO parallelism - for j in 0..small_domain.num_threads { + (0..small_domain.num_threads).into_par_iter().for_each(|j| { let start = j * small_domain.thread_size; let end = (j + 1) * small_domain.thread_size; for i in start..end { - scratch_space[i] = coeffs[i << 2]; - scratch_space[i + (1 << small_domain.log2_size)] = coeffs[(i << 2) + 1]; - scratch_space[i + (2 << small_domain.log2_size)] = coeffs[(i << 2) + 2]; - scratch_space[i + (3 << small_domain.log2_size)] = coeffs[(i << 2) + 3]; + unsafe { + *(scratch_space.as_ptr() as *mut Fr).add(i) = coeffs[i << 2]; + *(scratch_space.as_ptr() as *mut Fr) + .add(i + (1 << small_domain.log2_size)) = coeffs[(i << 2) + 1]; + *(scratch_space.as_ptr() as *mut Fr) + .add(i + (2 << small_domain.log2_size)) = coeffs[(i << 2) + 2]; + *(scratch_space.as_ptr() as *mut Fr) + .add(i + (3 << small_domain.log2_size)) = coeffs[(i << 2) + 3]; + } } - } + }); for i in 0..small_domain.size { for j in 0..domain_extension { scratch_space[i + (j << small_domain.log2_size)] = @@ -1001,29 +1023,37 @@ impl EvaluationDomain { } } } else { - // TODO: Parallelize - for k in 0..target_domain.num_threads { - let offset = k * target_domain.thread_size; - let root_shift = target_domain.root.pow([offset as u64]); - let mut work_root = self.generator * root_shift; - for i in (offset..offset + target_domain.thread_size).step_by(subgroup_size) { - for (j, subgroup_root) in subgroup_roots.iter().enumerate().take(subgroup_size) - { - let poly_idx = (i + j) >> log2_poly_size; - let elem_idx = (i + j) & poly_mask; - coeffs[poly_idx][elem_idx] *= subgroup_root; - - for num_const in numerator_constants - .iter() - .take(num_roots_cut_out_of_vanishing_polynomial) + (0..target_domain.num_threads) + .into_par_iter() + .for_each(|k| { + let offset = k * target_domain.thread_size; + let root_shift = target_domain.root.pow([offset as u64]); + let mut work_root = self.generator * root_shift; + for i in (offset..offset + target_domain.thread_size).step_by(subgroup_size) { + for (j, subgroup_root) in + subgroup_roots.iter().enumerate().take(subgroup_size) { - coeffs[poly_idx][elem_idx] *= work_root + num_const; + let poly_idx = (i + j) >> log2_poly_size; + let elem_idx = (i + j) & poly_mask; + unsafe { + *(coeffs[poly_idx].as_ptr() as *mut Fr).add(elem_idx) *= + subgroup_root; + } + + for num_const in numerator_constants + .iter() + .take(num_roots_cut_out_of_vanishing_polynomial) + { + unsafe { + *(coeffs[poly_idx].as_ptr() as *mut Fr).add(elem_idx) *= + work_root + num_const; + } + } + + work_root *= target_domain.root; } - - work_root *= target_domain.root; } - } - } + }); }; Ok(()) } @@ -1154,15 +1184,20 @@ impl EvaluationDomain { let multiplicand = target_domain.root; // kn'th root of unity w' // First compute X_i - 1, i = 0,...,kn-1 - for j in 0..target_domain.num_threads { - let root_shift = multiplicand.pow([(j * target_domain.thread_size) as u64]); - let mut work_root = self.generator * root_shift; // g.(w')^{j*thread_size} - let offset = j * target_domain.thread_size; - for i in offset..offset + target_domain.thread_size { - l_1_coefficients[i] = work_root - Fr::one(); // (w')^{j*thread_size + i}.g - 1 - work_root *= multiplicand; // (w')^{j*thread_size + i + 1} - } - } + (0..target_domain.num_threads) + .into_par_iter() + .for_each(|j| { + let root_shift = multiplicand.pow([(j * target_domain.thread_size) as u64]); + let mut work_root = self.generator * root_shift; // g.(w')^{j*thread_size} + let offset = j * target_domain.thread_size; + for i in offset..offset + target_domain.thread_size { + unsafe { + *(l_1_coefficients.coefficients.as_ptr() as *mut Fr).add(i) = + work_root - Fr::one(); // (w')^{j*thread_size + i}.g - 1 + } + work_root *= multiplicand; // (w')^{j*thread_size + i + 1} + } + }); // Compute 1/(X_i - 1) using Montgomery batch inversion batch_inversion(l_1_coefficients.coefficients.as_mut_slice()); @@ -1177,19 +1212,24 @@ impl EvaluationDomain { self.compute_multiplicative_subgroup(log2_subgroup_size, &mut subgroup_roots)?; // Subtract 1 and divide by n to get the k elements (1/n)*(X_i^n - 1) - for root in &mut subgroup_roots { + for root in subgroup_roots.iter_mut() { *root -= Fr::one(); *root *= self.domain_inverse; } // Step 3: Construct L_1(X_i) by multiplying the 1/denominator evaluations in // l_1_coefficients by the numerator evaluations in subgroup_roots let subgroup_mask = subgroup_size - 1; - for i in 0..target_domain.num_threads { - for j in 0..target_domain.thread_size { - let eval_idx = i * target_domain.thread_size + j; - l_1_coefficients[eval_idx] *= subgroup_roots[eval_idx & subgroup_mask]; - } - } + (0..target_domain.num_threads) + .into_par_iter() + .for_each(|i| { + for j in 0..target_domain.thread_size { + let eval_idx = i * target_domain.thread_size + j; + unsafe { + *(l_1_coefficients.coefficients.as_ptr() as *mut Fr).add(eval_idx) *= + subgroup_roots[eval_idx & subgroup_mask]; + } + } + }); Ok(()) } @@ -1622,11 +1662,11 @@ pub(crate) fn evaluate(coeffs: &[F], z: &F, n: usize) -> F { let num_threads = compute_num_threads(); let range_per_thread = n / num_threads; let leftovers = n - (range_per_thread * num_threads); - let mut evaluations = vec![F::default(); num_threads]; - for (j, eval_j) in evaluations.iter_mut().enumerate().take(num_threads) { + let evaluations = RwLock::new(vec![F::default(); num_threads]); + (0..num_threads).into_par_iter().for_each(|j| { let mut z_acc = z.pow([(j * range_per_thread) as u64]); let offset = j * range_per_thread; - *eval_j = F::default(); + evaluations.write().unwrap()[j] = F::default(); let end = if j == num_threads - 1 { offset + range_per_thread + leftovers } else { @@ -1634,12 +1674,12 @@ pub(crate) fn evaluate(coeffs: &[F], z: &F, n: usize) -> F { }; for coeffs_i in coeffs.iter().take(end).skip(offset) { let work_var = z_acc * coeffs_i; - *eval_j += work_var; + evaluations.write().unwrap()[j] += work_var; z_acc *= z; } - } + }); let mut r = F::default(); - for evaluation in evaluations { + for evaluation in evaluations.read().unwrap().iter() { r += evaluation; } r diff --git a/barustenberg/src/transcript.rs b/barustenberg/src/transcript.rs index 2dac668..a15754e 100644 --- a/barustenberg/src/transcript.rs +++ b/barustenberg/src/transcript.rs @@ -9,7 +9,7 @@ use tracing::info; use typenum::{Unsigned, U16, U32}; /// BarretenHasher is a trait that defines the hash function used for Fiat-Shamir. -pub trait BarretenHasher: std::fmt::Debug + Send + Sync { +pub trait BarretenHasher: std::fmt::Debug + Send + Sync + Clone { /// The size of the security parameter in bytes. type SecurityParameterSize: ArrayLength; /// The size of the PRNG output in bytes. @@ -20,7 +20,7 @@ pub trait BarretenHasher: std::fmt::Debug + Send + Sync { } /// Keccak256 hasher. -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub(crate) struct Keccak256 {} impl BarretenHasher for Keccak256 { @@ -33,7 +33,7 @@ impl BarretenHasher for Keccak256 { } /// Pedersen with blake3s. -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct PedersenBlake3s {} impl BarretenHasher for PedersenBlake3s { @@ -66,7 +66,7 @@ impl BarretenHasher for PedersenBlake3s { } /// PlookupPedersenBlake3s -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct PlookupPedersenBlake3s {} impl BarretenHasher for PlookupPedersenBlake3s { @@ -166,7 +166,7 @@ struct Challenge { } #[derive(Debug)] -pub struct Transcript { +pub(crate) struct Transcript { current_round: usize, pub(crate) num_challenge_bytes: usize, elements: HashMap>, @@ -705,7 +705,7 @@ impl Transcript { let buf = self.get_challenge(challenge_name, idx); Fr::deserialize_uncompressed(buf.unwrap().as_slice()).unwrap() } - fn get_challenge_field_element_from_map( + pub(crate) fn get_challenge_field_element_from_map( &self, challenge_name: &str, challenge_map_name: &str, From 59584d1db9f2c3e2876949d948a53cd6e334ae5e Mon Sep 17 00:00:00 2001 From: c r Date: Sun, 20 Aug 2023 01:08:01 -0400 Subject: [PATCH 2/3] ready (#68) --- barustenberg/src/ecc/mod.rs | 2 -- .../src/plonk/proof_system/verifier/mod.rs | 27 +++++++++---------- .../reference_string/mem_reference_string.rs | 4 +-- barustenberg/src/transcript.rs | 6 ++--- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/barustenberg/src/ecc/mod.rs b/barustenberg/src/ecc/mod.rs index 0a2842d..d99304d 100644 --- a/barustenberg/src/ecc/mod.rs +++ b/barustenberg/src/ecc/mod.rs @@ -3,8 +3,6 @@ use ark_ff::{FftField, Field}; // TODO todo - stubs to get the compiler to cooperate. pub(crate) mod curves; -pub(crate) struct MillerLines; - #[inline] pub(crate) fn conditionally_subtract_from_double_modulus( _this: &Fr, diff --git a/barustenberg/src/plonk/proof_system/verifier/mod.rs b/barustenberg/src/plonk/proof_system/verifier/mod.rs index 8978f3b..9f98022 100644 --- a/barustenberg/src/plonk/proof_system/verifier/mod.rs +++ b/barustenberg/src/plonk/proof_system/verifier/mod.rs @@ -46,22 +46,19 @@ pub struct Verifier { impl Verifier { /// Constructor pub fn new( - _verifier_key: Option>>>, - _manifest: Manifest, + verifier_key: Option>>>, + manifest: Manifest, ) -> Self { - // Implement constructor logic here. - todo!("Verifier::new") - } - - /// Validate commitements - fn validate_commitments(&self) -> bool { - // Implement validate_commitments logic here. - todo!("Verifier::validate_commitments") - } - - fn validate_scalars(&self) -> bool { - // Implement validate_scalars logic here. - todo!("Verifier::validate_scalars") + let h = H::default(); + let s = StandardSettings::new(h); + let c = KateCommitmentScheme::, H, Fq, Fr, G1Affine>::new(s.clone()); + Verifier { settings: s, + key: verifier_key.unwrap(), // todo is this a problem? + manifest, + kate_g1_elements: HashMap::new(), + kate_fr_elements: HashMap::new(), + commitment_scheme: Box::new(c), + } } /// Verify Proof diff --git a/barustenberg/src/srs/reference_string/mem_reference_string.rs b/barustenberg/src/srs/reference_string/mem_reference_string.rs index ef33ea4..c613256 100644 --- a/barustenberg/src/srs/reference_string/mem_reference_string.rs +++ b/barustenberg/src/srs/reference_string/mem_reference_string.rs @@ -9,8 +9,8 @@ pub(crate) struct VerifierMemReferenceString { } impl VerifierMemReferenceString { - pub(crate) fn new(_g2x: &[u8]) -> Self { - let g2_x = match G2Affine::deserialize_uncompressed(&*_g2x) { + pub(crate) fn new(g2x: &[u8]) -> Self { + let g2_x = match G2Affine::deserialize_uncompressed(g2x) { Ok(g2_x) => g2_x, Err(_) => panic!("Failed to deserialize g2_x"), }; diff --git a/barustenberg/src/transcript.rs b/barustenberg/src/transcript.rs index a15754e..48f22e8 100644 --- a/barustenberg/src/transcript.rs +++ b/barustenberg/src/transcript.rs @@ -9,7 +9,7 @@ use tracing::info; use typenum::{Unsigned, U16, U32}; /// BarretenHasher is a trait that defines the hash function used for Fiat-Shamir. -pub trait BarretenHasher: std::fmt::Debug + Send + Sync + Clone { +pub trait BarretenHasher: std::fmt::Debug + Send + Sync + Clone + Default { /// The size of the security parameter in bytes. type SecurityParameterSize: ArrayLength; /// The size of the PRNG output in bytes. @@ -33,7 +33,7 @@ impl BarretenHasher for Keccak256 { } /// Pedersen with blake3s. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub(crate) struct PedersenBlake3s {} impl BarretenHasher for PedersenBlake3s { @@ -66,7 +66,7 @@ impl BarretenHasher for PedersenBlake3s { } /// PlookupPedersenBlake3s -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub(crate) struct PlookupPedersenBlake3s {} impl BarretenHasher for PlookupPedersenBlake3s { From 5bcad03e2e6caac85e8f0e84c4207e37dd10e5d9 Mon Sep 17 00:00:00 2001 From: c r Date: Sun, 20 Aug 2023 02:44:36 -0400 Subject: [PATCH 3/3] close several little nit issues (#69) * close 39 * some stuff in the settings * more * removing duplicates * removing empty file again --- .../ecc/curves/bn254_scalar_multiplication.rs | 4 - .../src/plonk/composer/composer_base.rs | 6 +- .../src/plonk/proof_system/types/mod.rs | 1 - .../proof_system/types/polynomial_manifest.rs | 6 +- .../proof_system/types/program_settings.rs | 125 ---------------- .../src/plonk/proof_system/types/proof.rs | 2 +- .../proof_system/types/prover_settings.rs | 141 ++++++++++-------- .../plonk/proof_system/utils/permutation.rs | 3 - .../src/plonk/proof_system/verifier/mod.rs | 26 ++-- .../random_widgets/permutation_widget.rs | 5 +- .../transition_widgets/arithmetic_widget.rs | 20 ++- .../widgets/transition_widgets/getters.rs | 105 +++++-------- .../transition_widgets/transition_widget.rs | 112 +++++++++----- 13 files changed, 230 insertions(+), 326 deletions(-) delete mode 100644 barustenberg/src/plonk/proof_system/types/program_settings.rs diff --git a/barustenberg/src/ecc/curves/bn254_scalar_multiplication.rs b/barustenberg/src/ecc/curves/bn254_scalar_multiplication.rs index 05bb0a2..4f5d085 100644 --- a/barustenberg/src/ecc/curves/bn254_scalar_multiplication.rs +++ b/barustenberg/src/ecc/curves/bn254_scalar_multiplication.rs @@ -6,10 +6,6 @@ use ark_ff::{Field, Zero}; use crate::srs::io::read_transcript_g1; -pub(crate) type G1AffineGroup = ::G1Config, -> as ark_ec::AffineRepr>::Group; - use anyhow::Result; #[inline] diff --git a/barustenberg/src/plonk/composer/composer_base.rs b/barustenberg/src/plonk/composer/composer_base.rs index 112f56e..1f5db40 100644 --- a/barustenberg/src/plonk/composer/composer_base.rs +++ b/barustenberg/src/plonk/composer/composer_base.rs @@ -39,9 +39,9 @@ pub(crate) enum WireType { pub(crate) enum ComposerType { #[default] Standard, - Turbo, - Plookup, - StandardHonk, + _Turbo, + _Plookup, + _StandardHonk, } impl ComposerType { diff --git a/barustenberg/src/plonk/proof_system/types/mod.rs b/barustenberg/src/plonk/proof_system/types/mod.rs index 817dc1e..f813631 100644 --- a/barustenberg/src/plonk/proof_system/types/mod.rs +++ b/barustenberg/src/plonk/proof_system/types/mod.rs @@ -1,5 +1,4 @@ pub(crate) mod polynomial_manifest; -pub(crate) mod program_settings; pub(crate) mod proof; pub(crate) mod prover_settings; diff --git a/barustenberg/src/plonk/proof_system/types/polynomial_manifest.rs b/barustenberg/src/plonk/proof_system/types/polynomial_manifest.rs index 452689f..87c2f05 100644 --- a/barustenberg/src/plonk/proof_system/types/polynomial_manifest.rs +++ b/barustenberg/src/plonk/proof_system/types/polynomial_manifest.rs @@ -203,14 +203,14 @@ impl PolynomialManifest { pub(crate) fn new_from_type(type_: ComposerType) -> Self { match type_ { ComposerType::Standard => STANDARD_POLYNOMIAL_MANIFEST.clone(), - ComposerType::Turbo => TURBO_POLYNOMIAL_MANIFEST.clone(), - ComposerType::Plookup => ULTRA_POLYNOMIAL_MANIFEST.clone(), + ComposerType::_Turbo => TURBO_POLYNOMIAL_MANIFEST.clone(), + ComposerType::_Plookup => ULTRA_POLYNOMIAL_MANIFEST.clone(), _ => unimplemented!("no standardhonk..."), } } pub(crate) fn len(&self) -> usize { - todo!() + self.manifest.len() } pub(crate) fn get(&self, index: PolynomialIndex) -> &PolynomialDescriptor { &self.manifest[index as usize] diff --git a/barustenberg/src/plonk/proof_system/types/program_settings.rs b/barustenberg/src/plonk/proof_system/types/program_settings.rs deleted file mode 100644 index 5aa6615..0000000 --- a/barustenberg/src/plonk/proof_system/types/program_settings.rs +++ /dev/null @@ -1,125 +0,0 @@ -// use ark_ff::FieldExt; - -// use crate::{ecc::Group, transcript::{HasherType, Transcript, self}, plonk::proof_system::verification_key::VerificationKey}; -// use std::collections::HashMap; - -// use super::prover_settings::SettingsBase; - -// pub trait VerifierSettings: SettingsBase { -// type ArithmeticWidget; // Define ArithmeticWidget trait -// type PermutationWidget; // Define PermutationWidget trait -// type Transcript; - -// const NUM_CHALLENGE_BYTES: usize; -// const HASH_TYPE: HasherType; -// const ID_POLYS: bool; - -// fn append_scalar_multiplication_inputs( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// scalars: &mut HashMap, -// ) -> Self::Fr; - -// fn compute_quotient_evaluation_contribution( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// quotient_numerator_eval: &mut Self::Fr, -// ) -> Self::Fr; -// } - -// pub struct StandardVerifierSettings; - -// impl VerifierSettings for StandardVerifierSettings { -// type Transcript = transcript::Transcript; -// type ArithmeticWidget; // Define ArithmeticWidget trait -// type PermutationWidget; // Define PermutationWidget trait - -// const HASH_TYPE: transcript::HashType = transcript::HasherType::PedersenBlake3s; -// const NUM_CHALLENGE_BYTES: usize = 16; -// const ID_POLYS: bool = false; - -// fn append_scalar_multiplication_inputs( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// scalars: &mut HashMap, -// ) -> Self::Fr; - -// fn compute_quotient_evaluation_contribution( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// quotient_numerator_eval: &mut Self::Fr, -// ) -> Self::Fr; -// } -// pub trait StandardVerifierSettings: StandardSettings { -// type Fr = ark_bn254::fr::Fr; -// type G1 = ark_bn254::g1::G1; -// type Transcript = transcript::StandardTranscript; -// type ArithmeticWidget; // Define ArithmeticWidget trait -// type PermutationWidget; // Define PermutationWidget trait - -// const HASH_TYPE: transcript::HashType = transcript::HashType::PedersenBlake3s; -// const NUM_CHALLENGE_BYTES: usize = 16; -// const ID_POLYS: bool = false; - -// fn append_scalar_multiplication_inputs( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// scalars: &mut HashMap, -// ) -> Self::Fr; - -// fn compute_quotient_evaluation_contribution( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// quotient_numerator_eval: &mut Self::Fr, -// ) -> Self::Fr; -// } - -// pub trait TurboVerifierSettings: TurboSettings { -// type Fr = fr; -// type G1 = g1; -// type Transcript = transcript::StandardTranscript; -// // Define other widget types here - -// const NUM_CHALLENGE_BYTES: usize = 16; -// const HASH_TYPE: transcript::HashType = transcript::HashType::PedersenBlake3s; -// const ID_POLYS: bool = false; - -// fn append_scalar_multiplication_inputs( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// scalars: &mut HashMap, -// ) -> Self::Fr; - -// fn compute_quotient_evaluation_contribution( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// quotient_numerator_eval: &mut Self::Fr, -// ) -> Self::Fr; -// } - -// pub trait UltraVerifierSettings: UltraSettings { -// type Fr = fr; -// type G1 = g1; -// type Transcript = transcript::StandardTranscript; -// // Define other widget types here - -// const NUM_CHALLENGE_BYTES: usize = 16; -// const HASH_TYPE: transcript::HashType = transcript::HashType::PlookupPedersenBlake3s; -// const ID_POLYS: bool = true; - -// fn append_scalar_multiplication_inputs( -// key: &mut VerificationKey, -// alpha_base: Self::Fr, -// transcript: &Self::Transcript, -// scalars: &mut HashMap, -// ) -> Self::Fr; - -// fn compute_quotient_evaluation_con diff --git a/barustenberg/src/plonk/proof_system/types/proof.rs b/barustenberg/src/plonk/proof_system/types/proof.rs index cf595a2..c410eb9 100644 --- a/barustenberg/src/plonk/proof_system/types/proof.rs +++ b/barustenberg/src/plonk/proof_system/types/proof.rs @@ -8,7 +8,7 @@ pub struct Proof { #[derive(Default, Debug)] pub(crate) struct CommitmentOpenProof { - pub(crate) proof_data: Vec, + pub(crate) _proof_data: Vec, } impl fmt::Display for Proof { diff --git a/barustenberg/src/plonk/proof_system/types/prover_settings.rs b/barustenberg/src/plonk/proof_system/types/prover_settings.rs index 41e4478..88260b4 100644 --- a/barustenberg/src/plonk/proof_system/types/prover_settings.rs +++ b/barustenberg/src/plonk/proof_system/types/prover_settings.rs @@ -1,4 +1,7 @@ -use std::collections::HashMap; +use std::{ + collections::HashMap, + sync::{Arc, RwLock}, +}; use ark_ec::AffineRepr; use ark_ff::{FftField, Field}; @@ -6,7 +9,16 @@ use ark_ff::{FftField, Field}; use ark_bn254::{Fr, G1Affine}; use crate::{ - plonk::proof_system::verification_key::VerificationKey, + plonk::proof_system::{ + verification_key::VerificationKey, + widgets::{ + random_widgets::permutation_widget::VerifierPermutationWidget, + transition_widgets::{ + arithmetic_widget::VerifierArithmeticWidget, + transition_widget::GenericVerifierWidgetBase, + }, + }, + }, transcript::{BarretenHasher, Keccak256, PedersenBlake3s, PlookupPedersenBlake3s, Transcript}, }; @@ -29,18 +41,18 @@ pub(crate) trait Settings: Sized { fn permutation_mask(&self) -> u32; fn num_roots_cut_out_of_vanishing_polynomial(&self) -> usize; fn compute_quotient_evaluation_contribution( - verification_key: &VerificationKey, + verification_key: Arc>>, alpha_base: &Self::Field, transcript: &Transcript, - quotient_numerator_eval: &Self::Field, + quotient_numerator_eval: &mut Self::Field, ) -> Self::Field where Self: Sized; fn append_scalar_multiplication_inputs( - verification_key: &VerificationKey, + verification_key: Arc>>, alpha_base: &Self::Field, transcript: &Transcript, - scalars: &HashMap, + scalars: &mut HashMap, ) -> Self::Field where Self: Sized; @@ -107,45 +119,46 @@ impl Settings for StandardSettings { #[inline] fn compute_quotient_evaluation_contribution( - _verification_key: &VerificationKey, - _alpha_base: &Fr, - _transcript: &Transcript, - _quotient_numerator_eval: &Fr, + verification_key: Arc>>, + alpha_base: &Fr, + transcript: &Transcript, + quotient_numerator_eval: &mut Fr, ) -> Fr { - unimplemented!("todo"); - /* - auto updated_alpha_base = VerifierPermutationWidget< - barretenberg::fr, - barretenberg::g1::affine_element, - transcript::StandardTranscript>::compute_quotient_evaluation_contribution(key, - alpha_base, - transcript, - quotient_numerator_eval); - - return ArithmeticWidget::compute_quotient_evaluation_contribution( - key, updated_alpha_base, transcript, quotient_numerator_eval); - */ + let updated_alpha_base = VerifierPermutationWidget::::compute_quotient_evaluation_contribution( + &verification_key.read().unwrap(), + *alpha_base, + transcript, + quotient_numerator_eval, + None + ); + return VerifierArithmeticWidget::::compute_quotient_evaluation_contribution( + verification_key, updated_alpha_base, transcript, quotient_numerator_eval); } #[inline] fn append_scalar_multiplication_inputs( - _verification_key: &VerificationKey, - _alpha_base: &Fr, - _transcript: &Transcript, - _scalars: &HashMap, + verification_key: Arc>>, + alpha_base: &Fr, + transcript: &Transcript, + scalars: &mut HashMap, ) -> Fr { - unimplemented!("todo"); + let updated_alpha = + VerifierPermutationWidget::::append_scalar_multiplication_inputs( + *alpha_base, + transcript, + ); + + return VerifierArithmeticWidget::::append_scalar_multiplication_inputs( + verification_key, + updated_alpha, + transcript, + scalars, + ); } } pub(crate) struct TurboSettings {} -impl TurboSettings { - pub(crate) fn new() -> Self { - Self {} - } -} - impl Settings for TurboSettings { type Hasher = PedersenBlake3s; type Field = Fr; @@ -189,10 +202,10 @@ impl Settings for TurboSettings { } #[inline] fn compute_quotient_evaluation_contribution( - _verification_key: &VerificationKey, + _verification_key: Arc>>, _alpha_base: &Fr, _transcript: &Transcript, - _quotient_numerator_eval: &Fr, + _quotient_numerator_eval: &mut Fr, ) -> Fr { unimplemented!(); /* @@ -212,11 +225,11 @@ impl Settings for TurboSettings { */ } fn append_scalar_multiplication_inputs( - _verification_key: &VerificationKey, - _alpha_base: &Fr, - _transcript: &Transcript, - _scalars: &HashMap, - ) -> Fr { + _verification_key: Arc>>, + _alpha_base: &Self::Field, + _transcript: &Transcript, + _scalars: &mut HashMap, + ) -> Self::Field { unimplemented!("todo"); } } @@ -267,10 +280,10 @@ impl Settings for UltraSettings { #[inline] fn compute_quotient_evaluation_contribution( - _verification_key: &VerificationKey, + _verification_key: Arc>>, _alpha_base: &Fr, - _transcript: &Transcript, - _quotient_numerator_eval: &Fr, + _transcript: &Transcript, + _quotient_numerator_eval: &mut Fr, ) -> Fr { /* auto updated_alpha_base = PermutationWidget::compute_quotient_evaluation_contribution( @@ -292,11 +305,11 @@ impl Settings for UltraSettings { } fn append_scalar_multiplication_inputs( - _verification_key: &VerificationKey, - _alpha_base: &Fr, - _transcript: &Transcript, - _scalars: &HashMap, - ) -> Fr { + _verification_key: Arc>>, + _alpha_base: &Self::Field, + _transcript: &Transcript, + _scalars: &mut HashMap, + ) -> Self::Field { unimplemented!("todo"); } } @@ -346,21 +359,21 @@ impl Settings for UltraToStandardSettings { } #[inline] fn compute_quotient_evaluation_contribution( - _verification_key: &VerificationKey, + _verification_key: Arc>>, _alpha_base: &Fr, _transcript: &Transcript, - _quotient_numerator_eval: &Fr, + _quotient_numerator_eval: &mut Fr, ) -> Fr { // UltraSettings::compute_quotient_evaluation_contribution(verification_key, alpha_base, transcript, quotient_numerator_eval) todo!() } fn append_scalar_multiplication_inputs( - _verification_key: &VerificationKey, - _alpha_base: &Fr, - _transcript: &Transcript, - _scalars: &HashMap, - ) -> Fr { + _verification_key: Arc>>, + _alpha_base: &Self::Field, + _transcript: &Transcript, + _scalars: &mut HashMap, + ) -> Self::Field { unimplemented!("todo"); } } @@ -410,20 +423,20 @@ impl Settings for UltraWithKeccakSettings { } #[inline] fn compute_quotient_evaluation_contribution( - _verification_key: &VerificationKey, + _verification_key: Arc>>, _alpha_base: &Fr, - _transcript: &Transcript, - _quotient_numerator_eval: &Fr, + _transcript: &Transcript, + _quotient_numerator_eval: &mut Fr, ) -> Fr { //UltraSettings::compute_quotient_evaluation_contribution(verification_key, alpha_base, transcript, quotient_numerator_eval) todo!() } fn append_scalar_multiplication_inputs( - _verification_key: &VerificationKey, - _alpha_base: &Fr, - _transcript: &Transcript, - _scalars: &HashMap, - ) -> Fr { + _verification_key: Arc>>, + _alpha_base: &Self::Field, + _transcript: &Transcript, + _scalars: &mut HashMap, + ) -> Self::Field { unimplemented!("todo"); } } diff --git a/barustenberg/src/plonk/proof_system/utils/permutation.rs b/barustenberg/src/plonk/proof_system/utils/permutation.rs index cb2740f..627af50 100644 --- a/barustenberg/src/plonk/proof_system/utils/permutation.rs +++ b/barustenberg/src/plonk/proof_system/utils/permutation.rs @@ -70,15 +70,12 @@ pub(crate) fn compute_permutation_lagrange_base_single_helper< conditionally_subtract_from_double_modulus(&roots[idx], negative_idx as u64); if perm_i.is_public_input { - // TODO: Replace with correct external_coset_generator function output.coefficients[i] *= external_coset_generator::(); } else if perm_i.is_tag { - // TODO: Replace with correct tag_coset_generator function output.coefficients[i] *= tag_coset_generator::(); } else { let column_index = perm_i.column_index; if column_index > 0 { - // TODO: Replace with correct coset_generator function output.coefficients[i] *= coset_generator::(column_index - 1); } } diff --git a/barustenberg/src/plonk/proof_system/verifier/mod.rs b/barustenberg/src/plonk/proof_system/verifier/mod.rs index 9f98022..1a64d1f 100644 --- a/barustenberg/src/plonk/proof_system/verifier/mod.rs +++ b/barustenberg/src/plonk/proof_system/verifier/mod.rs @@ -45,19 +45,17 @@ pub struct Verifier { /// verifier interface impl Verifier { /// Constructor - pub fn new( - verifier_key: Option>>>, - manifest: Manifest, - ) -> Self { + pub fn new(verifier_key: Option>>>, manifest: Manifest) -> Self { let h = H::default(); let s = StandardSettings::new(h); let c = KateCommitmentScheme::, H, Fq, Fr, G1Affine>::new(s.clone()); - Verifier { settings: s, + Verifier { + settings: s, key: verifier_key.unwrap(), // todo is this a problem? - manifest, - kate_g1_elements: HashMap::new(), - kate_fr_elements: HashMap::new(), - commitment_scheme: Box::new(c), + manifest, + kate_g1_elements: HashMap::new(), + kate_fr_elements: HashMap::new(), + commitment_scheme: Box::new(c), } } @@ -139,12 +137,12 @@ impl Verifier { (*self.key).write().unwrap().z_pow_n = z_pow_n; // compute the quotient polynomial numerator contribution - let t_numerator_eval = Fr::zero(); + let mut t_numerator_eval = Fr::zero(); StandardSettings::::compute_quotient_evaluation_contribution( - &(*self.key).read().unwrap(), + self.key.clone(), &alpha, &transcript, - &t_numerator_eval, + &mut t_numerator_eval, ); let t_eval = t_numerator_eval * lagrange_evals.vanishing_poly.inverse().unwrap(); transcript.add_field_element("t", &t_eval); @@ -190,10 +188,10 @@ impl Verifier { // step. // StandardSettings::::append_scalar_multiplication_inputs( - &(*self.key).read().unwrap(), + self.key.clone(), &alpha, &transcript, - &self.kate_fr_elements, + &mut self.kate_fr_elements, ); // Fetch the group elements [W_z]_1,[W_zω]_1 from the transcript diff --git a/barustenberg/src/plonk/proof_system/widgets/random_widgets/permutation_widget.rs b/barustenberg/src/plonk/proof_system/widgets/random_widgets/permutation_widget.rs index 2f3ac62..e120de8 100644 --- a/barustenberg/src/plonk/proof_system/widgets/random_widgets/permutation_widget.rs +++ b/barustenberg/src/plonk/proof_system/widgets/random_widgets/permutation_widget.rs @@ -44,12 +44,13 @@ where } pub(crate) fn compute_quotient_evaluation_contribution( - key: &Arc>, + key: &VerificationKey, alpha: F, transcript: &Transcript, quotient_numerator_eval: &mut F, - idpolys: bool, + idpolys: Option, ) -> F { + let idpolys = idpolys.unwrap_or(false); let alpha_squared: F = alpha.square(); let alpha_cubed = alpha_squared * alpha; // a.k.a. zeta or ʓ diff --git a/barustenberg/src/plonk/proof_system/widgets/transition_widgets/arithmetic_widget.rs b/barustenberg/src/plonk/proof_system/widgets/transition_widgets/arithmetic_widget.rs index 50d0464..9387e46 100644 --- a/barustenberg/src/plonk/proof_system/widgets/transition_widgets/arithmetic_widget.rs +++ b/barustenberg/src/plonk/proof_system/widgets/transition_widgets/arithmetic_widget.rs @@ -20,7 +20,10 @@ use std::{ use super::{ containers::{ChallengeArray, CoefficientArray, CHALLENGE_BIT_ALPHA}, getters::BaseGetter, - transition_widget::{KernelBase, TransitionWidget, TransitionWidgetBase}, + transition_widget::{ + GenericVerifierWidget, GenericVerifierWidgetBase, KernelBase, TransitionWidget, + TransitionWidgetBase, + }, }; #[derive(Debug)] @@ -232,3 +235,18 @@ impl ProverArithmeticWidget { Self(TransitionWidget::new(key)) } } + +#[derive(Debug)] +pub(crate) struct VerifierArithmeticWidget { + widget: GenericVerifierWidget>, +} + +impl<'a, H: BarretenHasher, F: Field + FftField, G: AffineRepr> GenericVerifierWidgetBase<'a> + for VerifierArithmeticWidget +{ + type Hasher = H; + type Field = F; + type Group = G; + type NumIndependentRelations = typenum::U1; + type KB = ArithmeticKernel; +} diff --git a/barustenberg/src/plonk/proof_system/widgets/transition_widgets/getters.rs b/barustenberg/src/plonk/proof_system/widgets/transition_widgets/getters.rs index 226299f..b5a9bde 100644 --- a/barustenberg/src/plonk/proof_system/widgets/transition_widgets/getters.rs +++ b/barustenberg/src/plonk/proof_system/widgets/transition_widgets/getters.rs @@ -11,7 +11,7 @@ use std::{collections::HashSet, marker::PhantomData}; use typenum::Unsigned; use ark_ec::AffineRepr; -use ark_ff::{FftField, Field, Zero}; +use ark_ff::{FftField, Field}; use crate::{ plonk::proof_system::{ @@ -128,7 +128,7 @@ pub(crate) trait BaseGetter { ) -> Self::Fr; } -pub(crate) struct EvaluationGetterImpl +pub(crate) struct EvaluationGetter where F: Field + FftField, G: AffineRepr, @@ -138,40 +138,13 @@ where phantom: PhantomData<(F, H, G, NWidgetRelations)>, } -impl BaseGetter - for EvaluationGetterImpl +impl EvaluationGetter where + F: Field + FftField, + G: AffineRepr, H: BarretenHasher, NWidgetRelations: generic_array::ArrayLength, { - type Hasher = H; - type Fr = F; - type G1 = G; - type PC = PolyArray; - type NWidgetRelations = NWidgetRelations; - - fn get_value( - polynomials: &PolyArray, - evaluation_type: EvaluationType, - id: PolynomialIndex, - index: Option, - ) -> F { - assert!(index.is_none()); - match evaluation_type { - EvaluationType::NonShifted => polynomials[id].1, - EvaluationType::Shifted => polynomials[id].0, - } - } -} - -/// Implements loading polynomial openings from transcript in addition to BaseGetter's -/// loading challenges from the transcript and computing powers of α -pub(crate) trait EvaluationGetter { - type Hasher: BarretenHasher; - type Fr: Field + FftField; - type G1: AffineRepr; - type NWidgetRelations: generic_array::ArrayLength; - /// Get a polynomial at offset `id` /// /// # Arguments @@ -186,12 +159,12 @@ pub(crate) trait EvaluationGetter { /// # Returns /// /// The chosen polynomial - fn get_evaluation_value( - polynomials: &PolyArray, + pub(crate) fn get_evaluation_value( + polynomials: &PolyArray, evaluation_type: EvaluationType, id: PolynomialIndex, index: Option, - ) -> &Self::Fr { + ) -> &F { assert!(index.is_none()); match evaluation_type { EvaluationType::Shifted => &polynomials[id].1, @@ -209,11 +182,11 @@ pub(crate) trait EvaluationGetter { /// # Returns /// /// `PolyArray` - fn get_polynomial_evaluations( + pub(crate) fn get_polynomial_evaluations( polynomial_manifest: &PolynomialManifest, - transcript: &Transcript, - ) -> PolyArray { - let mut result: PolyArray = Default::default(); + transcript: &Transcript, + ) -> PolyArray { + let mut result: PolyArray = Default::default(); for i in 0..polynomial_manifest.len() { let info = &polynomial_manifest[i.into()]; let label = info.polynomial_label.clone(); @@ -222,15 +195,15 @@ pub(crate) trait EvaluationGetter { if info.requires_shifted_evaluation { result[info.index].1 = transcript.get_field_element(&(label + "_omega")); } else { - result[info.index].1 = Self::Fr::zero(); + result[info.index].1 = F::zero(); } } result } } -impl EvaluationGetter - for EvaluationGetterImpl +impl BaseGetter + for EvaluationGetter where H: BarretenHasher, NWidgetRelations: generic_array::ArrayLength, @@ -238,10 +211,24 @@ where type Hasher = H; type Fr = F; type G1 = G; + type PC = PolyArray; type NWidgetRelations = NWidgetRelations; + + fn get_value( + polynomials: &PolyArray, + evaluation_type: EvaluationType, + id: PolynomialIndex, + index: Option, + ) -> F { + assert!(index.is_none()); + match evaluation_type { + EvaluationType::NonShifted => polynomials[id].1, + EvaluationType::Shifted => polynomials[id].0, + } + } } -pub(crate) struct FFTGetterImpl +pub(crate) struct FFTGetter where F: Field + FftField, H: BarretenHasher, @@ -251,7 +238,7 @@ where phantom: PhantomData<(F, H, G, NWidgetRelations)>, } -impl BaseGetter for FFTGetterImpl +impl BaseGetter for FFTGetter where F: Field + FftField, H: BarretenHasher, @@ -282,31 +269,19 @@ where } } -impl FFTGetter for FFTGetterImpl +/// Provides access to polynomials (monomial or coset FFT) for use in widgets +/// Coset FFT access is needed in quotient construction. +impl FFTGetter where - F: Field + FftField, + Fr: Field + FftField, H: BarretenHasher, - G: AffineRepr, - NWidgetRelations: generic_array::ArrayLength, + G1: AffineRepr, + NWidgetRelations: generic_array::ArrayLength, { - type Hasher = H; - type Fr = F; - type G1 = G; - type NWidgetRelations = NWidgetRelations; -} - -/// Provides access to polynomials (monomial or coset FFT) for use in widgets -/// Coset FFT access is needed in quotient construction. -pub(crate) trait FFTGetter { - type Hasher: BarretenHasher; - type Fr: Field + FftField; - type G1: AffineRepr; - type NWidgetRelations: generic_array::ArrayLength; - - fn get_polynomials( - key: &ProvingKey, + pub(crate) fn get_polynomials( + key: &ProvingKey, required_polynomial_ids: &HashSet, - ) -> PolyPtrMap + ) -> PolyPtrMap where Self: Sized, { diff --git a/barustenberg/src/plonk/proof_system/widgets/transition_widgets/transition_widget.rs b/barustenberg/src/plonk/proof_system/widgets/transition_widgets/transition_widget.rs index 9cc82f3..a6d95e7 100644 --- a/barustenberg/src/plonk/proof_system/widgets/transition_widgets/transition_widget.rs +++ b/barustenberg/src/plonk/proof_system/widgets/transition_widgets/transition_widget.rs @@ -17,8 +17,8 @@ use crate::{ }; use super::{ - containers::{ChallengeArray, CoefficientArray, PolyArray}, - getters::{BaseGetter, EvaluationGetter, FFTGetter, FFTGetterImpl}, + containers::{ChallengeArray, CoefficientArray}, + getters::{BaseGetter, EvaluationGetter, FFTGetter}, }; pub(crate) trait KernelBase { @@ -126,12 +126,12 @@ where rng: &mut dyn rand::RngCore, ) -> F { let required_polynomial_ids = KB::get_required_polynomial_ids(); - let polynomials = FFTGetterImpl::::get_polynomials( + let polynomials = FFTGetter::::get_polynomials( &self.key.read().unwrap(), &required_polynomial_ids, ); - let challenges = FFTGetterImpl::::get_challenges( + let challenges = FFTGetter::::get_challenges( transcript, alpha_base, KB::quotient_required_challenges(), @@ -145,14 +145,14 @@ where // TODO: hidden missing multithreading here for i in 0..borrowed_key.large_domain.size { let mut linear_terms = CoefficientArray::default(); - KB::compute_linear_terms::>( + KB::compute_linear_terms::>( &polynomials, &challenges, &mut linear_terms, Some(i), ); let sum_of_linear_terms = KB::sum_linear_terms::< - FFTGetterImpl, + FFTGetter, >(&polynomials, &challenges, &linear_terms, i); quotient_term = borrowed_key.quotient_polynomial_parts @@ -160,7 +160,7 @@ where .read() .unwrap()[i & (borrowed_key.circuit_size - 1)]; quotient_term += sum_of_linear_terms; - KB::compute_non_linear_terms::>( + KB::compute_non_linear_terms::>( &polynomials, &challenges, &mut quotient_term, @@ -168,27 +168,15 @@ where ); } - FFTGetterImpl::::update_alpha(&challenges) + FFTGetter::::update_alpha(&challenges) } } -pub(crate) trait GenericVerifierWidget<'a> { +pub(crate) trait GenericVerifierWidgetBase<'a> { type Hasher: BarretenHasher; type Field: Field + FftField; type Group: AffineRepr; type NumIndependentRelations: generic_array::ArrayLength; - type Get: EvaluationGetter< - Hasher = Self::Hasher, - Fr = Self::Field, - G1 = Self::Group, - NWidgetRelations = Self::NumIndependentRelations, - > + BaseGetter< - Hasher = Self::Hasher, - Fr = Self::Field, - G1 = Self::Group, - NWidgetRelations = Self::NumIndependentRelations, - PC = PolyArray, - >; type KB: KernelBase< Field = Self::Field, Hasher = Self::Hasher, @@ -197,58 +185,102 @@ pub(crate) trait GenericVerifierWidget<'a> { >; fn compute_quotient_evaluation_contribution( - key: &Arc>, + key: Arc>>, alpha_base: Self::Field, transcript: &Transcript, quotient_numerator_eval: &mut Self::Field, - rng: &mut Box, ) -> Self::Field { - let polynomial_evaluations = - Self::Get::get_polynomial_evaluations(&key.as_ref().polynomial_manifest, transcript); - let challenges = Self::Get::get_challenges( + let polynomial_evaluations = EvaluationGetter::< + Self::Hasher, + Self::Field, + Self::Group, + Self::NumIndependentRelations, + >::get_polynomial_evaluations( + &key.read().unwrap().polynomial_manifest, transcript + ); + let challenges = EvaluationGetter::< + Self::Hasher, + Self::Field, + Self::Group, + Self::NumIndependentRelations, + >::get_challenges( transcript, alpha_base, Self::KB::quotient_required_challenges(), - rng, + &mut Box::new(rand::thread_rng()), ); let mut linear_terms = CoefficientArray::default(); - Self::KB::compute_linear_terms::( + Self::KB::compute_linear_terms::< + EvaluationGetter, + >( &polynomial_evaluations, &challenges, &mut linear_terms, Some(0), ); - *quotient_numerator_eval += Self::KB::sum_linear_terms::( - &polynomial_evaluations, - &challenges, - &linear_terms, - 0, + *quotient_numerator_eval += Self::KB::sum_linear_terms::< + EvaluationGetter, + >( + &polynomial_evaluations, &challenges, &linear_terms, 0 ); - Self::KB::compute_non_linear_terms::( + Self::KB::compute_non_linear_terms::< + EvaluationGetter, + >( &polynomial_evaluations, &challenges, quotient_numerator_eval, 0, ); - Self::Get::update_alpha(&challenges) + EvaluationGetter::::update_alpha(&challenges) } fn append_scalar_multiplication_inputs( - _key: &Arc>, + _key: Arc>>, alpha_base: Self::Field, transcript: &Transcript, _scalar_mult_inputs: &mut HashMap, - rng: &mut Box, ) -> Self::Field { - let challenges = Self::Get::get_challenges( + let mut rng = Box::new(rand::thread_rng()); + let challenges = EvaluationGetter::< + Self::Hasher, + Self::Field, + Self::Group, + Self::NumIndependentRelations, + >::get_challenges( transcript, alpha_base, Self::KB::quotient_required_challenges() | Self::KB::update_required_challenges(), - rng, + &mut rng, ); - Self::Get::update_alpha(&challenges) + EvaluationGetter::::update_alpha(&challenges) } } + +#[derive(Debug)] +pub(crate) struct GenericVerifierWidget< + H: BarretenHasher, + F: Field + FftField, + G: AffineRepr, + KB: KernelBase, +> { + key: Arc>, + phantom: PhantomData<(H, G, KB)>, +} + +impl< + 'a, + H: BarretenHasher, + F: Field + FftField, + G: AffineRepr, + KB: KernelBase, + > GenericVerifierWidgetBase<'a> for GenericVerifierWidget +{ + type Hasher = H; + type Field = F; + type Group = G; + type NumIndependentRelations = KB::NumIndependentRelations; + type KB = KB; +}