diff --git a/co-noir/ultrahonk/Cargo.toml b/co-noir/ultrahonk/Cargo.toml index f1303fa6..966e6195 100644 --- a/co-noir/ultrahonk/Cargo.toml +++ b/co-noir/ultrahonk/Cargo.toml @@ -19,3 +19,4 @@ sha3.workspace = true tracing.workspace = true thiserror.workspace = true rand.workspace = true +byteorder.workspace = true diff --git a/co-noir/ultrahonk/crs/bn254_g1.dat b/co-noir/ultrahonk/crs/bn254_g1.dat new file mode 100644 index 00000000..78ec38ab Binary files /dev/null and b/co-noir/ultrahonk/crs/bn254_g1.dat differ diff --git a/co-noir/ultrahonk/crs/bn254_g2.dat b/co-noir/ultrahonk/crs/bn254_g2.dat new file mode 100644 index 00000000..8d2083bb --- /dev/null +++ b/co-noir/ultrahonk/crs/bn254_g2.dat @@ -0,0 +1 @@ +ÄÕ¸7¼Â¼‰µ³˜µ—NŸYD;2‹~#쓈ƒ°&²QöñÇçÿNX‘ÞèêQØz5Ž‹Nþ0úÀ“ƒÁ"þ½£ÀÀc*VG[Båa^æÝ?–æ΢…J‡ÔÚÌ^Uüci÷ãÒQVÁ»šr…œò FAù›¤îA<€Új_ä \ No newline at end of file diff --git a/co-noir/ultrahonk/src/crs.rs b/co-noir/ultrahonk/src/crs.rs new file mode 100644 index 00000000..2e2c11f6 --- /dev/null +++ b/co-noir/ultrahonk/src/crs.rs @@ -0,0 +1,222 @@ +// copied from barustenberg: + +use ark_ec::pairing::Pairing; +use ark_ec::AffineRepr; +use ark_ec::CurveGroup; +use ark_serialize::CanonicalDeserialize; +use byteorder::ByteOrder; +use byteorder::ReadBytesExt; +use byteorder::WriteBytesExt; +use byteorder::{BigEndian, LittleEndian}; +use eyre::{anyhow, Result}; +use std::cmp::min; +use std::fs::File; +use std::io::Read; +use std::io::Seek; +use std::io::SeekFrom; +use std::path::Path; + +const BLAKE2B_CHECKSUM_LENGTH: usize = 64; + +#[derive(Debug, Default)] +struct Manifest { + transcript_number: u32, + total_transcripts: u32, + total_g1_points: u32, + total_g2_points: u32, + num_g1_points: u32, + num_g2_points: u32, + start_from: u32, +} + +fn get_transcript_size(manifest: &Manifest) -> usize { + let manifest_size = std::mem::size_of::(); + let g1_buffer_size = std::mem::size_of::<::BaseField>() + * 2 + * manifest.num_g1_points as usize; + let g2_buffer_size = std::mem::size_of::<::BaseField>() + * 2 + * manifest.num_g2_points as usize; + manifest_size + g1_buffer_size + g2_buffer_size + BLAKE2B_CHECKSUM_LENGTH +} + +fn read_manifest(filename: &str) -> Result { + let mut file = File::open(filename)?; + + Ok(Manifest { + transcript_number: file.read_u32::()?, + total_transcripts: file.read_u32::()?, + total_g1_points: file.read_u32::()?, + total_g2_points: file.read_u32::()?, + num_g1_points: file.read_u32::()?, + num_g2_points: file.read_u32::()?, + start_from: file.read_u32::()?, + }) +} + +fn write_manifest(filename: &str, manifest: &Manifest) -> Result<()> { + let mut file = File::create(filename)?; + + // Here you need to call file.write_u32::(value)? for each field in Manifest + file.write_u32::(manifest.transcript_number)?; + file.write_u32::(manifest.total_transcripts)?; + file.write_u32::(manifest.total_g1_points)?; + file.write_u32::(manifest.total_g2_points)?; + file.write_u32::(manifest.num_g1_points)?; + file.write_u32::(manifest.num_g2_points)?; + file.write_u32::(manifest.start_from)?; + + Ok(()) +} + +fn convert_endianness_inplace(buffer: &mut [u8]) { + for i in (0..buffer.len()).step_by(8) { + let be = BigEndian::read_u64(&buffer[i..i + 8]); + LittleEndian::write_u64(&mut buffer[i..i + 8], be); + } +} + +fn read_elements_from_buffer(elements: &mut [G], buffer: &mut [u8]) { + for (element, chunk) in elements.iter_mut().zip(buffer.chunks_exact_mut(64)) { + convert_endianness_inplace(chunk); + #[allow(clippy::redundant_slicing)] + if let Ok(val) = G::deserialize_uncompressed_unchecked(&chunk[..]) { + *element = val; + } + } +} + +fn get_file_size(filename: &str) -> std::io::Result { + let metadata = std::fs::metadata(filename)?; + Ok(metadata.len()) +} + +fn read_file_into_buffer( + buffer: &mut [u8], + size: usize, + filename: &str, + offset: u64, + _amount: usize, +) -> std::io::Result<()> { + let mut file = File::open(filename)?; + file.seek(SeekFrom::Start(offset))?; + let actual_size = file.read(buffer)?; + if actual_size != size { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!( + "Only read {} bytes from file but expected {}.", + actual_size, size + ), + )); + } + Ok(()) +} + +fn get_transcript_path(dir: &str, num: usize) -> String { + format!("{}/monomial/transcript{:02}.dat", dir, num) +} + +fn is_file_exist(file_name: &str) -> bool { + Path::new(file_name).exists() +} + +pub(crate) fn read_transcript_g1( + monomials: &mut [P::G1Affine], + degree: usize, + dir: &str, +) -> Result<()> { + let num = 0; + let mut num_read = 0; + let mut path = get_transcript_path(dir, num); + + while Path::new(&path).exists() && num_read < degree { + let manifest = read_manifest(&path)?; + + let offset = std::mem::size_of::(); + let num_to_read = min(manifest.num_g1_points as usize, degree - num_read); + let g1_buffer_size = + std::mem::size_of::<::BaseField>() * 2 * num_to_read; + let mut buffer = vec![0_u8; g1_buffer_size]; + + let mut file = File::open(&path)?; + file.seek(SeekFrom::Start(offset as u64))?; + let mut file = file.take(g1_buffer_size as u64); + file.read_exact(&mut buffer[..])?; + + // We must pass the size actually read to the second call, not the desired + // g1_buffer_size as the file may have been smaller than this. + let monomial = &mut monomials[num_read..]; + read_elements_from_buffer(monomial, &mut buffer); + + num_read += num_to_read; + path = get_transcript_path(dir, num + 1); + } + + if num_read < degree { + return Err(anyhow!( + "Only read {} points from {}, but require {}. Is your SRS large enough? \ + Either run bootstrap.sh to download the transcript.dat files to `srs_db/ignition/`, \ + or you might need to download extra transcript.dat files by editing \ + `srs_db/download_ignition.sh` (but be careful, as this suggests you've \ + just changed a circuit to exceed a new 'power of two' boundary).", + num_read, path, degree + ) + ); + } + + Ok(()) +} + +pub(crate) fn read_transcript_g2(g2_x: &mut P::G2Affine, dir: &str) -> Result<()> { + let g2_size = std::mem::size_of::<::BaseField>() * 2; + assert!(std::mem::size_of::() >= g2_size); + let mut path = format!("{}/g2.dat", dir); + + if Path::new(&path).exists() { + let mut buffer = vec![0_u8; g2_size]; + + let file = File::open(&path)?; + let mut file = file.take(g2_size as u64); + file.read_exact(&mut buffer[..])?; + convert_endianness_inplace(&mut buffer); + + // Again, size passed to second function should be size actually read + *g2_x = P::G2Affine::deserialize_uncompressed(&mut &buffer[..]) + .map_err(|e| anyhow!("Failed to deserialize G2Affine from transcript file: {}", e))?; + + return Ok(()); + } + + // Get transcript starting at g0.dat + path = get_transcript_path(dir, 0); + + let manifest = read_manifest(&path)?; + + let g2_buffer_offset = std::mem::size_of::<::BaseField>() + * 2 + * manifest.num_g1_points as usize; + let offset = std::mem::size_of::() + g2_buffer_offset; + + let mut file = File::open(&path)?; + file.seek(SeekFrom::Start(offset as u64))?; + let mut buf = vec![0; g2_size]; + file.read_exact(&mut buf[..])?; + convert_endianness_inplace(&mut buf); + + *g2_x = P::G2Affine::deserialize_uncompressed(&mut &buf[..]) + .map_err(|e| anyhow!("Failed to deserialize G2Affine from transcript file: {}", e))?; + + Ok(()) +} + +pub(crate) fn read_transcript( + monomials: &mut [P::G1Affine], + g2_x: &mut P::G2Affine, + degree: usize, + path: &str, +) -> Result<()> { + read_transcript_g1(monomials, degree, path)?; + read_transcript_g2(g2_x, path)?; + Ok(()) +} diff --git a/co-noir/ultrahonk/src/decider/prover.rs b/co-noir/ultrahonk/src/decider/prover.rs index bf562294..ba4f5b70 100644 --- a/co-noir/ultrahonk/src/decider/prover.rs +++ b/co-noir/ultrahonk/src/decider/prover.rs @@ -88,8 +88,8 @@ impl Decider

{ q[l] = f_k[size_q + l] - f_k[l]; } - quotients[log_n as usize - k as usize - 1] = q.clone(); // Assuming `clone` is implemented for Polynomial - g = f_k.clone(); // Assuming `clone` is implemented for Vec + quotients[log_n as usize - k as usize - 1] = q.clone(); + g = f_k.clone(); } quotients diff --git a/co-noir/ultrahonk/src/decider/verifier.rs b/co-noir/ultrahonk/src/decider/verifier.rs index b53547a1..92dd85b5 100644 --- a/co-noir/ultrahonk/src/decider/verifier.rs +++ b/co-noir/ultrahonk/src/decider/verifier.rs @@ -35,7 +35,7 @@ impl DeciderVerifier

{ public_inputs: Vec, relation_parameters: RelationParameters

, //weg damit witness_comms: WitnessCommitments

, //weg damit - ) { + ) -> bool { // tracing::trace!("Decider verification"); let mut transcript = Keccak256Transcript::

::default(); let log_circuit_size = get_msb(vk.circuit_size.clone()); @@ -55,17 +55,17 @@ impl DeciderVerifier

{ transcript.add_scalar(gate_challenges[idx - 1]); gate_challenges[idx] = transcript.get_challenge(); } - let (multivariate_challenge, claimed_evaluations, sumcheck_verified) = sumcheck_verify( - relation_parameters, - &mut transcript, - oink_output.alphas, - gate_challenges, - vk, - ); + let (multivariate_challenge, claimed_evaluations, sumcheck_verified) = + crate::verifier::sumcheck_verify( + relation_parameters, + &mut transcript, + oink_output.alphas, + vk, + ); // to do: build sumcheck verifier, returns (multivariate_challenge, claimed_evaluations, sumcheck_verified) // get_unshifted(), get_to_be_shifted(), get_shifted() - let opening_claim = zeromorph_verify( + let opening_claim = crate::verifier::zeromorph_verify( vk.circuit_size, witness_comms, witness_comms, @@ -73,6 +73,7 @@ impl DeciderVerifier

{ claimed_evaluations, multivariate_challenge, &mut transcript, + // TODO Check these types/shifts // concatenated_evaluations // actually it is // commitments.get_unshifted(), @@ -81,8 +82,8 @@ impl DeciderVerifier

{ // claimed_evaluations.get_shifted() // but i dont understand the shift yet ); - let pairing_points = reduce_verify(&mut transcript, opening_claim); - let pcs_verified = pairing_check(pairing_points[0], pairing_points[1], precomputedlines); + let pairing_points = crate::verifier::reduce_verify(&mut transcript, opening_claim); + let pcs_verified = crate::verifier::pairing_check(pairing_points[0], pairing_points[1]); sumcheck_verified && pcs_verified } } diff --git a/co-noir/ultrahonk/src/lib.rs b/co-noir/ultrahonk/src/lib.rs index f781b2bf..1d0737b9 100644 --- a/co-noir/ultrahonk/src/lib.rs +++ b/co-noir/ultrahonk/src/lib.rs @@ -1,6 +1,8 @@ +mod crs; pub(crate) mod decider; pub(crate) mod oink; pub mod prover; +mod reference_string; mod transcript; mod types; pub mod verifier; diff --git a/co-noir/ultrahonk/src/reference_string/file_reference_string.rs b/co-noir/ultrahonk/src/reference_string/file_reference_string.rs new file mode 100644 index 00000000..bcc3bf32 --- /dev/null +++ b/co-noir/ultrahonk/src/reference_string/file_reference_string.rs @@ -0,0 +1,132 @@ +// copied from barustenberg: + +use std::sync::{Arc, RwLock}; + +use super::{Pippenger, ProverReferenceString, ReferenceStringFactory, VerifierReferenceString}; +use crate::crs::read_transcript_g2; +// use crate::ecc::curves::bn254_scalar_multiplication::Pippenger; + +use ark_ec::pairing::Pairing; +use eyre::{anyhow, Result}; + +#[derive(Debug, Default)] +pub(crate) struct VerifierFileReferenceString { + g2_x: P::G2Affine, +} + +impl VerifierFileReferenceString

+where + P: Pairing, +{ + pub(crate) fn new(path: &str) -> Result { + let mut g2_x = P::G2Affine::default(); + read_transcript_g2(&mut g2_x, path)?; + + Ok(Self { g2_x }) + } +} + +impl VerifierReferenceString

for VerifierFileReferenceString

{ + fn get_g2x(&self) -> P::G2Affine { + self.g2_x + } +} + +#[derive(Debug, Default)] +pub(crate) struct FileReferenceString { + num_points: usize, + pippenger: Pippenger

, +} + +impl FileReferenceString

{ + pub(crate) fn new(num_points: usize, path: &str) -> Result { + // Implementation depends on your project. + let pippenger = Pippenger::

::from_path(path, num_points)?; + Ok(Self { + num_points, + pippenger, + }) + } + + pub(crate) fn read_from_path(_path: &str) -> Result { + // Implementation depends on your project. + todo!("FileReferenceString::read_from_path") + } +} + +impl ProverReferenceString

for FileReferenceString

{ + fn get_monomial_points(&self) -> Arc> { + // Implementation depends on your project. + todo!() + } + + fn get_monomial_size(&self) -> usize { + self.num_points + } +} + +#[derive(Debug, Default)] +pub(crate) struct FileReferenceStringFactory { + path: String, +} + +impl FileReferenceStringFactory { + pub(crate) fn new(path: String) -> Self { + Self { path } + } +} +impl ReferenceStringFactory

for FileReferenceStringFactory { + type Pro = FileReferenceString

; + type Ver = VerifierFileReferenceString

; + fn get_prover_crs(&self, degree: usize) -> Result>>> { + Ok(Some(Arc::new(RwLock::new(FileReferenceString::new( + degree, &self.path, + )?)))) + } + + fn get_verifier_crs(&self) -> Result>>> { + Ok(Some(Arc::new(RwLock::new( + VerifierFileReferenceString::new(&self.path)?, + )))) + } +} + +#[derive(Debug, Default)] +pub(crate) struct DynamicFileReferenceStringFactory { + path: String, + degree: RwLock, + prover_crs: Arc>>, + verifier_crs: Arc>>, +} + +impl DynamicFileReferenceStringFactory

{ + pub(crate) fn new(path: String, initial_degree: usize) -> Result { + let verifier_crs = Arc::new(RwLock::new(VerifierFileReferenceString::new(&path)?)); + let prover_crs = Arc::new(RwLock::new(FileReferenceString::new( + initial_degree, + &path, + )?)); + Ok(Self { + path, + degree: RwLock::new(initial_degree), + prover_crs, + verifier_crs, + }) + } +} + +impl ReferenceStringFactory

for DynamicFileReferenceStringFactory

{ + type Pro = FileReferenceString

; + type Ver = VerifierFileReferenceString

; + fn get_prover_crs(&self, degree: usize) -> Result>>> { + if degree != *self.degree.read().unwrap() { + *self.prover_crs.write().unwrap() = FileReferenceString::new(degree, &self.path)?; + *self.degree.write().unwrap() = degree; + } + Ok(Some(self.prover_crs.clone())) + } + + fn get_verifier_crs(&self) -> Result>>> { + Ok(Some(self.verifier_crs.clone())) + } +} diff --git a/co-noir/ultrahonk/src/reference_string/mem_reference_string.rs b/co-noir/ultrahonk/src/reference_string/mem_reference_string.rs new file mode 100644 index 00000000..2292b8e7 --- /dev/null +++ b/co-noir/ultrahonk/src/reference_string/mem_reference_string.rs @@ -0,0 +1,36 @@ +// copied from barustenberg: + +use ark_ec::pairing::Pairing; +use ark_serialize::CanonicalDeserialize; + +use super::VerifierReferenceString; + +#[derive(Debug)] +pub(crate) struct VerifierMemReferenceString { + g2_x: P::G2Affine, +} + +impl VerifierMemReferenceString

{ + pub(crate) fn new(g2x: &[u8]) -> Self { + let g2_x = match P::G2Affine::deserialize_uncompressed(g2x) { + Ok(g2_x) => g2_x, + Err(_) => panic!("Failed to deserialize g2_x"), + }; + + VerifierMemReferenceString { g2_x } + } + + pub(crate) fn from_affline(_g2x: P::G2Affine) -> Self { + VerifierMemReferenceString { g2_x: _g2x } + } + + pub(crate) fn default() -> Self { + VerifierMemReferenceString::from_affline(P::G2Affine::default()) + } +} + +impl VerifierReferenceString

for VerifierMemReferenceString

{ + fn get_g2x(&self) -> P::G2Affine { + self.g2_x + } +} diff --git a/co-noir/ultrahonk/src/reference_string/mod.rs b/co-noir/ultrahonk/src/reference_string/mod.rs new file mode 100644 index 00000000..91347943 --- /dev/null +++ b/co-noir/ultrahonk/src/reference_string/mod.rs @@ -0,0 +1,33 @@ +// copied from barustenberg: + +pub(crate) mod file_reference_string; +pub(crate) mod mem_reference_string; +pub(crate) mod pippenger_reference_string; + +use std::fmt::Debug; +use std::sync::{Arc, RwLock}; + +use ark_ec::pairing::Pairing; +use eyre::{anyhow, Result}; +#[derive(Clone, Debug, Default)] +pub(crate) struct Pippenger { + monomials: Vec, + num_points: usize, +} +pub(crate) trait VerifierReferenceString: Debug + Send + Sync { + fn get_g2x(&self) -> P::G2Affine; +} + +pub(crate) trait ProverReferenceString: Debug + Send + Sync { + // cpp definition for this is non-const but all implementations are const, + // unclear to me that we need a mut ref to self + fn get_monomial_points(&self) -> Arc>; + fn get_monomial_size(&self) -> usize; +} +pub(crate) trait ReferenceStringFactory: Default { + type Pro: ProverReferenceString

+ 'static; + type Ver: VerifierReferenceString

+ 'static; + fn get_prover_crs(&self, _size: usize) -> Result>>>; + + fn get_verifier_crs(&self) -> Result>>>; +} diff --git a/co-noir/ultrahonk/src/reference_string/pippenger_reference_string.rs b/co-noir/ultrahonk/src/reference_string/pippenger_reference_string.rs new file mode 100644 index 00000000..895d4be0 --- /dev/null +++ b/co-noir/ultrahonk/src/reference_string/pippenger_reference_string.rs @@ -0,0 +1,61 @@ +// copied from barustenberg: + +use std::sync::{Arc, RwLock}; + +use crate::reference_string::{ProverReferenceString, ReferenceStringFactory}; +use ark_ec::pairing::Pairing; +use eyre::{anyhow, Result}; + +use super::{mem_reference_string::VerifierMemReferenceString, Pippenger}; + +#[derive(Debug)] +pub(crate) struct PippengerReferenceString { + pippenger: Arc>, +} + +impl PippengerReferenceString

{ + pub(crate) fn new(pippenger: Arc>) -> Self { + PippengerReferenceString { pippenger } + } +} + +impl ProverReferenceString

for PippengerReferenceString

{ + // TODO + fn get_monomial_size(&self) -> usize { + todo!() + } + + fn get_monomial_points(&self) -> Arc> { + // will we mutate self here? + todo!() + } +} + +#[derive(Debug, Default)] +pub(crate) struct PippengerReferenceStringFactory<'a, P: Pairing> { + pippenger: Arc>, + g2x: &'a [u8], +} + +impl<'a, P: Pairing> PippengerReferenceStringFactory<'a, P> { + pub(crate) fn new(pippenger: Arc>, g2x: &'a [u8]) -> Self { + PippengerReferenceStringFactory { pippenger, g2x } + } +} + +impl<'a, P: Pairing> ReferenceStringFactory

for PippengerReferenceStringFactory<'a, P> { + type Pro = PippengerReferenceString

; + type Ver = VerifierMemReferenceString

; + + fn get_prover_crs(&self, degree: usize) -> Result>>> { + assert!(degree <= self.pippenger.get_num_points()); + Ok(Some(Arc::new(RwLock::new(PippengerReferenceString::new( + self.pippenger.clone(), + ))))) + } + fn get_verifier_crs(&self) -> Result>>> { + Ok(Some(Arc::new(RwLock::new( + VerifierMemReferenceString::new(self.g2x), + )))) + } +} diff --git a/co-noir/ultrahonk/src/verifier.rs b/co-noir/ultrahonk/src/verifier.rs index d991429c..7be4f8b0 100644 --- a/co-noir/ultrahonk/src/verifier.rs +++ b/co-noir/ultrahonk/src/verifier.rs @@ -8,6 +8,7 @@ use crate::{ NUM_ALPHAS, }; use ark_ec::pairing::{self, Pairing}; +use ark_ec::Group; use ark_ec::VariableBaseMSM; use ark_ff::Field; use std::{io, marker::PhantomData}; @@ -53,12 +54,6 @@ impl UltraHonkVerifier

{ ) .verify(public_inputs); - // do we have to do this?: - // Copy the witness_commitments over to the VerifierCommitments - // for (auto [wit_comm_1, wit_comm_2] : zip_view(commitments.get_witness(), witness_commitments.get_all())) { - // wit_comm_1 = wit_comm_2; - // } - let mut transcript = Keccak256Transcript::

::default(); // let mut gate_challenges = Vec::with_capacity(log_circuit_size as usize); vk.gate_challenges[0] = transcript.get_challenge(); @@ -89,19 +84,16 @@ impl UltraHonkVerifier

{ // but i dont understand the shift yet ); let pairing_points = reduce_verify(&mut transcript, opening_claim); - let pcs_verified = pairing_check(pairing_points[0], pairing_points[1], precomputedlines); + let pcs_verified = pairing_check(pairing_points[0], pairing_points[1]); sumcheck_verified && pcs_verified } } //need (?) the verifier SRS for the following ("https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g1.dat" and "https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/flat/g2.dat") //Check: g1_identity first element in the SRS! -fn pairing_check( - p0: P::G1Affine, - p1: P::G1Affine, - precomputedlines: [P::G2Prepared; 2], //todo: where to get this from -) -> bool { +pub fn pairing_check(p0: P::G1Affine, p1: P::G1Affine) -> bool { let g1_prepared = [P::G1Prepared::from(p0), P::G1Prepared::from(p1)]; + let precomputedlines: [P::G2Prepared; 2]; //todo: where to get this from let m_loop = P::multi_miller_loop(g1_prepared, precomputedlines); let result = P::final_exponentiation(m_loop); match result { @@ -112,7 +104,7 @@ fn pairing_check( // (compare cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp or https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view) -fn zeromorph_verify( +pub fn zeromorph_verify( circuit_size: u32, unshifted_commitments: Vec, to_be_shifted_commitments: Vec, @@ -317,7 +309,7 @@ fn compute_c_z_x( ) } -fn sumcheck_verify( +pub fn sumcheck_verify( relation_parameters: RelationParameters

, transcript: &mut transcript::Keccak256Transcript

, alphas: [P::ScalarField; NUM_ALPHAS], @@ -446,8 +438,9 @@ fn scale_by_challenge_and_batch( *result } +// I don't know about this one... // this is the kzg one: -fn reduce_verify( +pub fn reduce_verify( transcript: &mut transcript::Keccak256Transcript

, opening_pair: OpeningClaim

, ) -> [P::G1Affine; 2] { @@ -457,7 +450,7 @@ fn reduce_verify( // Note: The pairing check can be expressed naturally as // e(C - v * [1]_1, [1]_2) = e([W]_1, [X - r]_2) where C =[p(X)]_1. This can be rearranged (e.g. see the plonk // paper) as e(C + r*[W]_1 - v*[1]_1, [1]_2) * e(-[W]_1, [X]_2) = 1, or e(P_0, [1]_2) * e(P_1, [X]_2) = 1 - let mut p0 = opening_pair.commitment + quotient_commitment * opening_pair.challenge - - opening_pair.evaluation * P::G1::ONE; + // let mut p0 = opening_pair.commitment + quotient_commitment * opening_pair.challenge + // - std::ops::Mul::mul(P::G1::generator(), opening_pair.evaluation); todo!() }