From a1f1b9b03e2a46fec92ca01d0341141b850f0f45 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Tue, 5 Nov 2024 16:22:08 +0800 Subject: [PATCH 01/18] Refactor pcs tests by adding some utility functions. --- mpcs/src/lib.rs | 291 +++++++++++++++++++++++++++--------------------- 1 file changed, 163 insertions(+), 128 deletions(-) diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index 46fbea0ff..8734028ee 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -336,10 +336,45 @@ fn validate_input( poly.num_vars, )); } + #[cfg(test)] + use crate::Evaluation; + #[cfg(test)] + use itertools::chain; + + use crate::PolynomialCommitmentScheme; + use ff_ext::ExtensionField; + use itertools::Itertools; + use multilinear_extensions::mle::DenseMultilinearExtension; + #[cfg(test)] + use multilinear_extensions::{ + mle::MultilinearExtension, virtual_poly_v2::ArcMultilinearExtension, + }; + use rand::rngs::OsRng; + use transcript::Transcript; + + pub fn setup_pcs>( + num_vars: usize, + ) -> (Pcs::ProverParam, Pcs::VerifierParam) { + let poly_size = 1 << num_vars; + let param = Pcs::setup(poly_size).unwrap(); + Pcs::trim(¶m, poly_size).unwrap() } for point in points.iter() { if param_num_vars < point.len() { return Err(err_too_many_variates(function, param_num_vars, point.len())); + pub fn gen_rand_poly( + num_vars: usize, + base: bool, + ) -> DenseMultilinearExtension { + if base { + DenseMultilinearExtension::random(num_vars, &mut OsRng) + } else { + DenseMultilinearExtension::from_evaluations_ext_vec( + num_vars, + (0..(1 << num_vars)) + .map(|_| E::random(&mut OsRng)) + .collect_vec(), + ) } } Ok(()) @@ -356,9 +391,26 @@ fn err_too_many_variates(function: &str, upto: usize, got: usize) -> Error { ) }) } + pub fn gen_rand_polys( + num_vars: impl Fn(usize) -> usize, + batch_size: usize, + base: bool, + ) -> Vec> { + (0..batch_size) + .map(|i| gen_rand_poly(num_vars(i), base)) + .collect_vec() + } #[cfg(test)] pub mod test_util { + pub fn get_point_from_challenge( + num_vars: usize, + transcript: &mut Transcript, + ) -> Vec { + (0..num_vars) + .map(|_| transcript.get_and_append_challenge(b"Point").elements) + .collect() + } use crate::{Evaluation, PolynomialCommitmentScheme}; use ff_ext::ExtensionField; @@ -367,6 +419,30 @@ pub mod test_util { use rand::{prelude::*, rngs::OsRng}; use rand_chacha::ChaCha8Rng; use transcript::Transcript; + pub fn get_points_from_challenge( + num_vars: impl Fn(usize) -> usize, + num_points: usize, + transcript: &mut Transcript, + ) -> Vec> { + (0..num_points) + .map(|i| get_point_from_challenge(num_vars(i), transcript)) + .collect() + } + + pub fn commit_polys_individually>( + pp: &Pcs::ProverParam, + polys: &[DenseMultilinearExtension], + transcript: &mut Transcript, + ) -> Vec { + polys + .iter() + .map(|poly| Pcs::commit_and_write(pp, poly, transcript).unwrap()) + .collect_vec() + } + + pub fn vecs_as_slices(values: &[Vec]) -> Vec<&[T]> { + values.iter().map(|vec| vec.as_slice()).collect::>() + } pub fn run_commit_open_verify( base: bool, @@ -376,30 +452,18 @@ pub mod test_util { Pcs: PolynomialCommitmentScheme, { for num_vars in num_vars_start..num_vars_end { - // Setup - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - Pcs::trim(¶m, poly_size).unwrap() - }; + let (pp, vp) = setup_pcs::(num_vars); + // Commit and open let (comm, eval, proof, challenge) = { let mut transcript = Transcript::new(b"BaseFold"); - let poly = if base { - DenseMultilinearExtension::random(num_vars, &mut OsRng) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars, - (0..1 << num_vars).map(|_| E::random(&mut OsRng)).collect(), - ) - }; - + let poly = gen_rand_poly(num_vars, base); let comm = Pcs::commit_and_write(&pp, &poly, &mut transcript).unwrap(); - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); + let point = get_point_from_challenge(num_vars, &mut transcript); let eval = poly.evaluate(point.as_slice()); + let poly = ArcMultilinearExtension::from(poly); transcript.append_field_element_ext(&eval); + ( Pcs::get_pure_commitment(&comm), eval, @@ -408,25 +472,21 @@ pub mod test_util { ) }; // Verify - let result = { + { let mut transcript = Transcript::new(b"BaseFold"); Pcs::write_commitment(&comm, &mut transcript).unwrap(); - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); + let point = get_point_from_challenge(num_vars, &mut transcript); transcript.append_field_element_ext(&eval); - let result = Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript); + Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript).unwrap(); let v_challenge = transcript.read_challenge(); assert_eq!(challenge, v_challenge); - - result - }; - result.unwrap(); + } } } - pub fn run_batch_commit_open_verify( + #[cfg(test)] + pub fn run_batch_vlmp_commit_open_verify( base: bool, num_vars_start: usize, num_vars_end: usize, @@ -435,15 +495,10 @@ pub mod test_util { Pcs: PolynomialCommitmentScheme, { for num_vars in num_vars_start..num_vars_end { - let batch_size = 2; + let batch_size = 4; let num_points = batch_size >> 1; - let rng = ChaCha8Rng::from_seed([0u8; 32]); - // Setup - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - Pcs::trim(¶m, poly_size).unwrap() - }; + let (pp, vp) = setup_pcs::(num_vars); + // Batch commit and open let evals = chain![ (0..num_points).map(|point| (point * 2, point)), // Every point matches two polys @@ -452,34 +507,15 @@ pub mod test_util { .unique() .collect_vec(); - let (comms, points, evals, proof, challenge) = { + let (comms, evals, proof, challenge) = { let mut transcript = Transcript::new(b"BaseFold"); - let polys = (0..batch_size) - .map(|i| { - if base { - DenseMultilinearExtension::random(num_vars - (i >> 1), &mut rng.clone()) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars, - (0..1 << num_vars).map(|_| E::random(&mut OsRng)).collect(), - ) - } - }) - .collect_vec(); + let polys = gen_rand_polys(|i| num_vars - (i >> 1), batch_size, base); - let comms = polys - .iter() - .map(|poly| Pcs::commit_and_write(&pp, poly, &mut transcript).unwrap()) - .collect_vec(); + let comms = + commit_polys_individually::(&pp, polys.as_slice(), &mut transcript); - let points = (0..num_points) - .map(|i| { - (0..num_vars - i) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>() - }) - .take(num_points) - .collect_vec(); + let points = + get_points_from_challenge(|i| num_vars - i, num_points, &mut transcript); let evals = evals .iter() @@ -497,12 +533,24 @@ pub mod test_util { .collect::>(); transcript.append_field_element_exts(values.as_slice()); - let proof = - Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); - (comms, points, evals, proof, transcript.read_challenge()) + let polys = polys + .iter() + .map(|poly| ArcMultilinearExtension::from(poly.clone())) + .collect_vec(); + + let proof = Pcs::batch_open_vlmp( + &pp, + &polys, + &comms, + &vecs_as_slices(&points), + &evals, + &mut transcript, + ) + .unwrap(); + (comms, evals, proof, transcript.read_challenge()) }; // Batch verify - let result = { + { let mut transcript = Transcript::new(b"BaseFold"); let comms = comms .iter() @@ -513,16 +561,9 @@ pub mod test_util { }) .collect_vec(); - let old_points = points; - let points = (0..num_points) - .map(|i| { - (0..num_vars - i) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>() - }) - .take(num_points) - .collect_vec(); - assert_eq!(points, old_points); + let points = + get_points_from_challenge(|i| num_vars - i, num_points, &mut transcript); + let values: Vec = evals .iter() .map(Evaluation::value) @@ -530,14 +571,18 @@ pub mod test_util { .collect::>(); transcript.append_field_element_exts(values.as_slice()); - let result = - Pcs::batch_verify(&vp, &comms, &points, &evals, &proof, &mut transcript); + Pcs::batch_verify_vlmp( + &vp, + &comms, + &vecs_as_slices(&points), + &evals, + &proof, + &mut transcript, + ) + .unwrap(); let v_challenge = transcript.read_challenge(); assert_eq!(challenge, v_challenge); - result - }; - - result.unwrap(); + } } } @@ -551,79 +596,69 @@ pub mod test_util { Pcs: PolynomialCommitmentScheme, { for num_vars in num_vars_start..num_vars_end { - let rng = ChaCha8Rng::from_seed([0u8; 32]); - // Setup - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - Pcs::trim(¶m, poly_size).unwrap() - }; + let (pp, vp) = setup_pcs::(num_vars); let (comm, evals, proof, challenge) = { let mut transcript = Transcript::new(b"BaseFold"); - let polys = (0..batch_size) - .map(|_| { - if base { - DenseMultilinearExtension::random(num_vars, &mut rng.clone()) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars, - (0..1 << num_vars).map(|_| E::random(&mut OsRng)).collect(), - ) - } - }) + let polys = gen_rand_polys(|_| num_vars, batch_size, base); + let comm = + Pcs::batch_commit_and_write(&pp, polys.as_slice(), &mut transcript).unwrap(); + let point = get_point_from_challenge(num_vars, &mut transcript); + let evals = polys.iter().map(|poly| poly.evaluate(&point)).collect_vec(); + transcript.append_field_element_exts(&evals); + + let polys = polys + .iter() + .map(|poly| ArcMultilinearExtension::from(poly.clone())) .collect_vec(); - let comm = Pcs::batch_commit_and_write(&pp, &polys, &mut transcript).unwrap(); + let proof = + Pcs::simple_batch_open(&pp, &polys, &comm, &point, &evals, &mut transcript) + .unwrap(); + ( + Pcs::get_pure_commitment(&comm), + evals, + proof, + transcript.read_challenge(), + ) + }; + // Batch verify + { + let mut transcript = Transcript::new(b"BaseFold"); + Pcs::write_commitment(&comm, &mut transcript).unwrap(); - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); + let point = get_point_from_challenge(num_vars, &mut transcript); + transcript.append_field_element_exts(&evals); + + Pcs::simple_batch_verify(&vp, &comm, &point, &evals, &proof, &mut transcript) + .unwrap(); + + let v_challenge = transcript.read_challenge(); + assert_eq!(challenge, v_challenge); + } + } + } - let evals = (0..batch_size) - .map(|i| polys[i].evaluate(&point)) .collect_vec(); - transcript.append_field_element_exts(&evals); - let proof = Pcs::simple_batch_open( &pp, - polys - .into_iter() - .map(|x| x.into()) - .collect::>() - .as_slice(), - &comm, &point, - &evals, &mut transcript, ) .unwrap(); ( - Pcs::get_pure_commitment(&comm), evals, proof, transcript.read_challenge(), ) }; // Batch verify - let result = { let mut transcript = Transcript::new(b"BaseFold"); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - transcript.append_field_element_exts(&evals); - let result = - Pcs::simple_batch_verify(&vp, &comm, &point, &evals, &proof, &mut transcript); let v_challenge = transcript.read_challenge(); assert_eq!(challenge, v_challenge); - result - }; - - result.unwrap(); + } } } } From eeec18d5f4a91f5cc69e17f7fd76ba6e74a035ae Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Tue, 5 Nov 2024 16:32:02 +0800 Subject: [PATCH 02/18] Fix compilation errors. --- mpcs/src/lib.rs | 106 +++++++++++++----------------------------------- 1 file changed, 28 insertions(+), 78 deletions(-) diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index 8734028ee..1b98b5542 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -336,9 +336,30 @@ fn validate_input( poly.num_vars, )); } - #[cfg(test)] + } + for point in points.iter() { + if param_num_vars < point.len() { + return Err(err_too_many_variates(function, param_num_vars, point.len())); + } + } + Ok(()) +} + +fn err_too_many_variates(function: &str, upto: usize, got: usize) -> Error { + Error::InvalidPcsParam(if function == "trim" { + format!( + "Too many variates to {function} (param supports variates up to {upto} but got {got})" + ) + } else { + format!( + "Too many variates of poly to {function} (param supports variates up to {upto} but got {got})" + ) + }) +} + +#[cfg(test)] +pub mod test_util { use crate::Evaluation; - #[cfg(test)] use itertools::chain; use crate::PolynomialCommitmentScheme; @@ -359,9 +380,7 @@ fn validate_input( let param = Pcs::setup(poly_size).unwrap(); Pcs::trim(¶m, poly_size).unwrap() } - for point in points.iter() { - if param_num_vars < point.len() { - return Err(err_too_many_variates(function, param_num_vars, point.len())); + pub fn gen_rand_poly( num_vars: usize, base: bool, @@ -377,20 +396,7 @@ fn validate_input( ) } } - Ok(()) -} -fn err_too_many_variates(function: &str, upto: usize, got: usize) -> Error { - Error::InvalidPcsParam(if function == "trim" { - format!( - "Too many variates to {function} (param supports variates up to {upto} but got {got})" - ) - } else { - format!( - "Too many variates of poly to {function} (param supports variates up to {upto} but got {got})" - ) - }) -} pub fn gen_rand_polys( num_vars: impl Fn(usize) -> usize, batch_size: usize, @@ -401,8 +407,6 @@ fn err_too_many_variates(function: &str, upto: usize, got: usize) -> Error { .collect_vec() } -#[cfg(test)] -pub mod test_util { pub fn get_point_from_challenge( num_vars: usize, transcript: &mut Transcript, @@ -411,14 +415,6 @@ pub mod test_util { .map(|_| transcript.get_and_append_challenge(b"Point").elements) .collect() } - - use crate::{Evaluation, PolynomialCommitmentScheme}; - use ff_ext::ExtensionField; - use itertools::{Itertools, chain}; - use multilinear_extensions::mle::{DenseMultilinearExtension, MultilinearExtension}; - use rand::{prelude::*, rngs::OsRng}; - use rand_chacha::ChaCha8Rng; - use transcript::Transcript; pub fn get_points_from_challenge( num_vars: impl Fn(usize) -> usize, num_points: usize, @@ -461,7 +457,6 @@ pub mod test_util { let comm = Pcs::commit_and_write(&pp, &poly, &mut transcript).unwrap(); let point = get_point_from_challenge(num_vars, &mut transcript); let eval = poly.evaluate(point.as_slice()); - let poly = ArcMultilinearExtension::from(poly); transcript.append_field_element_ext(&eval); ( @@ -485,8 +480,7 @@ pub mod test_util { } } - #[cfg(test)] - pub fn run_batch_vlmp_commit_open_verify( + pub fn run_batch_commit_open_verify( base: bool, num_vars_start: usize, num_vars_end: usize, @@ -533,20 +527,8 @@ pub mod test_util { .collect::>(); transcript.append_field_element_exts(values.as_slice()); - let polys = polys - .iter() - .map(|poly| ArcMultilinearExtension::from(poly.clone())) - .collect_vec(); - - let proof = Pcs::batch_open_vlmp( - &pp, - &polys, - &comms, - &vecs_as_slices(&points), - &evals, - &mut transcript, - ) - .unwrap(); + let proof = + Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); (comms, evals, proof, transcript.read_challenge()) }; // Batch verify @@ -571,15 +553,7 @@ pub mod test_util { .collect::>(); transcript.append_field_element_exts(values.as_slice()); - Pcs::batch_verify_vlmp( - &vp, - &comms, - &vecs_as_slices(&points), - &evals, - &proof, - &mut transcript, - ) - .unwrap(); + Pcs::batch_verify(&vp, &comms, &points, &evals, &proof, &mut transcript).unwrap(); let v_challenge = transcript.read_challenge(); assert_eq!(challenge, v_challenge); } @@ -632,30 +606,6 @@ pub mod test_util { Pcs::simple_batch_verify(&vp, &comm, &point, &evals, &proof, &mut transcript) .unwrap(); - let v_challenge = transcript.read_challenge(); - assert_eq!(challenge, v_challenge); - } - } - } - - .collect_vec(); - - &pp, - &point, - &mut transcript, - ) - .unwrap(); - ( - evals, - proof, - transcript.read_challenge(), - ) - }; - // Batch verify - let mut transcript = Transcript::new(b"BaseFold"); - - - let v_challenge = transcript.read_challenge(); assert_eq!(challenge, v_challenge); } From 8206cbcc1bf56b33f2f70bb80616383674f5c7e1 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Tue, 5 Nov 2024 16:36:20 +0800 Subject: [PATCH 03/18] Temporarily avoid a bug that will be fixed by other changes. --- mpcs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index 1b98b5542..a2f1b1d20 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -489,7 +489,7 @@ pub mod test_util { Pcs: PolynomialCommitmentScheme, { for num_vars in num_vars_start..num_vars_end { - let batch_size = 4; + let batch_size = 2; let num_points = batch_size >> 1; let (pp, vp) = setup_pcs::(num_vars); From ce8393fa2f8c34f9d65e185d2f9d2a1a2137c41c Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Tue, 5 Nov 2024 16:39:38 +0800 Subject: [PATCH 04/18] Remove unnecessary cfg(test) --- mpcs/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index a2f1b1d20..05786e06e 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -365,10 +365,9 @@ pub mod test_util { use crate::PolynomialCommitmentScheme; use ff_ext::ExtensionField; use itertools::Itertools; - use multilinear_extensions::mle::DenseMultilinearExtension; - #[cfg(test)] use multilinear_extensions::{ - mle::MultilinearExtension, virtual_poly_v2::ArcMultilinearExtension, + mle::{DenseMultilinearExtension, MultilinearExtension}, + virtual_poly_v2::ArcMultilinearExtension, }; use rand::rngs::OsRng; use transcript::Transcript; From d925cbf663e77047a01d801ed19055b16e8791f7 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Tue, 5 Nov 2024 16:40:24 +0800 Subject: [PATCH 05/18] Remove an extra function. --- mpcs/src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index 05786e06e..ac2cc112e 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -435,10 +435,6 @@ pub mod test_util { .collect_vec() } - pub fn vecs_as_slices(values: &[Vec]) -> Vec<&[T]> { - values.iter().map(|vec| vec.as_slice()).collect::>() - } - pub fn run_commit_open_verify( base: bool, num_vars_start: usize, From c4d69ffabaa1f8fe9dbc29c9b4e9544a1dc634e8 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Tue, 5 Nov 2024 16:43:20 +0800 Subject: [PATCH 06/18] Cleanup use codes. --- mpcs/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index ac2cc112e..8f832ff7e 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -359,12 +359,9 @@ fn err_too_many_variates(function: &str, upto: usize, got: usize) -> Error { #[cfg(test)] pub mod test_util { - use crate::Evaluation; - use itertools::chain; - - use crate::PolynomialCommitmentScheme; + use crate::{Evaluation, PolynomialCommitmentScheme}; use ff_ext::ExtensionField; - use itertools::Itertools; + use itertools::{Itertools, chain}; use multilinear_extensions::{ mle::{DenseMultilinearExtension, MultilinearExtension}, virtual_poly_v2::ArcMultilinearExtension, From d01ebdac0ba60a1bed1b38791fdf569baff21e65 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 07:17:37 +0800 Subject: [PATCH 07/18] Merge the two similar benchmarks. --- mpcs/Cargo.toml | 6 +- mpcs/benches/basefold.rs | 557 ++++++++++++++++++++ mpcs/benches/commit_open_verify_basecode.rs | 400 -------------- mpcs/benches/commit_open_verify_rs.rs | 402 -------------- 4 files changed, 558 insertions(+), 807 deletions(-) create mode 100644 mpcs/benches/basefold.rs delete mode 100644 mpcs/benches/commit_open_verify_basecode.rs delete mode 100644 mpcs/benches/commit_open_verify_rs.rs diff --git a/mpcs/Cargo.toml b/mpcs/Cargo.toml index 26ee123ba..0f53481d0 100644 --- a/mpcs/Cargo.toml +++ b/mpcs/Cargo.toml @@ -37,12 +37,8 @@ print-trace = ["ark-std/print-trace"] sanity-check = [] [[bench]] +name = "basefold" harness = false -name = "commit_open_verify_rs" - -[[bench]] -harness = false -name = "commit_open_verify_basecode" [[bench]] harness = false diff --git a/mpcs/benches/basefold.rs b/mpcs/benches/basefold.rs new file mode 100644 index 000000000..b30866a79 --- /dev/null +++ b/mpcs/benches/basefold.rs @@ -0,0 +1,557 @@ +use std::time::Duration; + +use criterion::*; +use goldilocks::GoldilocksExt2; + +use itertools::{Itertools, chain}; +use mpcs::{ + Basefold, BasefoldBasecodeParams, BasefoldRSParams, Evaluation, PolynomialCommitmentScheme, + test_util::{ + commit_polys_individually, gen_rand_poly, gen_rand_polys, get_point_from_challenge, + get_points_from_challenge, setup_pcs, vecs_as_slices, + }, + util::plonky2_util::log2_ceil, +}; + +use multilinear_extensions::{mle::MultilinearExtension, virtual_poly_v2::ArcMultilinearExtension}; +use transcript::Transcript; + +type PcsGoldilocksRSCode = Basefold; +type PcsGoldilocksBasecode = Basefold; +type T = Transcript; +type E = GoldilocksExt2; + +const NUM_SAMPLES: usize = 10; +const NUM_VARS_START: usize = 20; +const NUM_VARS_END: usize = 20; +const BATCH_SIZE_LOG_START: usize = 6; +const BATCH_SIZE_LOG_END: usize = 6; + +fn bench_commit_open_verify_goldilocks>( + c: &mut Criterion, + is_base: bool, + id: &str, +) { + let mut group = c.benchmark_group(format!( + "commit_open_verify_goldilocks_{}_{}", + id, + if is_base { "base" } else { "ext2" }, + )); + group.sample_size(NUM_SAMPLES); + // Challenge is over extension field, poly over the base field + for num_vars in NUM_VARS_START..=NUM_VARS_END { + let (pp, vp) = { + let poly_size = 1 << num_vars; + let param = Pcs::setup(poly_size).unwrap(); + + group.bench_function(BenchmarkId::new("setup", format!("{}", num_vars)), |b| { + b.iter(|| { + Pcs::setup(poly_size).unwrap(); + }) + }); + Pcs::trim(¶m, poly_size).unwrap() + }; + + let mut transcript = T::new(b"BaseFold"); + let poly = gen_rand_poly(num_vars, is_base); + let comm = Pcs::commit_and_write(&pp, &poly, &mut transcript).unwrap(); + + group.bench_function(BenchmarkId::new("commit", format!("{}", num_vars)), |b| { + b.iter(|| { + Pcs::commit(&pp, &poly).unwrap(); + }) + }); + + let point = get_point_from_challenge(num_vars, &mut transcript); + let eval = poly.evaluate(point.as_slice()); + transcript.append_field_element_ext(&eval); + let transcript_for_bench = transcript.clone(); + let poly = ArcMultilinearExtension::from(poly); + let proof = Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); + + group.bench_function(BenchmarkId::new("open", format!("{}", num_vars)), |b| { + b.iter_batched( + || transcript_for_bench.clone(), + |mut transcript| { + Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); + }, + BatchSize::SmallInput, + ); + }); + // Verify + let comm = Pcs::get_pure_commitment(&comm); + let mut transcript = T::new(b"BaseFold"); + Pcs::write_commitment(&comm, &mut transcript).unwrap(); + let point = get_point_from_challenge(num_vars, &mut transcript); + transcript.append_field_element_ext(&eval); + let transcript_for_bench = transcript.clone(); + Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript).unwrap(); + group.bench_function(BenchmarkId::new("verify", format!("{}", num_vars)), |b| { + b.iter_batched( + || transcript_for_bench.clone(), + |mut transcript| { + Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript).unwrap(); + }, + BatchSize::SmallInput, + ); + }); + } +} + +fn bench_batch_vlmp_commit_open_verify_goldilocks>( + c: &mut Criterion, + is_base: bool, + id: &str, +) { + let mut group = c.benchmark_group(format!( + "batch_commit_open_verify_goldilocks_{}_{}", + id, + if is_base { "base" } else { "ext2" }, + )); + group.sample_size(NUM_SAMPLES); + // Challenge is over extension field, poly over the base field + for num_vars in NUM_VARS_START..=NUM_VARS_END { + for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { + let batch_size = 1 << batch_size_log; + let num_points = batch_size >> 1; + // Setup + let (pp, vp) = setup_pcs::(num_vars); + // Batch commit and open + let evals = chain![ + (0..num_points).map(|point| (point * 2, point)), // Every point matches two polys + (0..num_points).map(|point| (point * 2 + 1, point)), + ] + .unique() + .collect_vec(); + + let mut transcript = T::new(b"BaseFold"); + let polys = gen_rand_polys(|i| num_vars - log2_ceil((i >> 1) + 1), batch_size, is_base); + let comms = commit_polys_individually::(&pp, &polys, &mut transcript); + + let points = get_points_from_challenge( + |i| num_vars - log2_ceil(i + 1), + num_points, + &mut transcript, + ); + + let evals = evals + .iter() + .copied() + .map(|(poly, point)| { + Evaluation::new(poly, point, polys[poly].evaluate(&points[point])) + }) + .collect_vec(); + let values: Vec = evals + .iter() + .map(Evaluation::value) + .map(|x| *x) + .collect::>(); + transcript.append_field_element_exts(values.as_slice()); + let transcript_for_bench = transcript.clone(); + let polys = polys + .iter() + .map(|poly| ArcMultilinearExtension::from(poly.clone())) + .collect::>(); + let proof = Pcs::batch_open_vlmp( + &pp, + &polys, + &comms, + &vecs_as_slices(&points), + &evals, + &mut transcript, + ) + .unwrap(); + + group.bench_function( + BenchmarkId::new("batch_open", format!("{}-{}", num_vars, batch_size)), + |b| { + b.iter_batched( + || transcript_for_bench.clone(), + |mut transcript| { + Pcs::batch_open_vlmp( + &pp, + &polys, + &comms, + &vecs_as_slices(&points), + &evals, + &mut transcript, + ) + .unwrap(); + }, + BatchSize::SmallInput, + ); + }, + ); + // Batch verify + let mut transcript = T::new(b"BaseFold"); + let comms = comms + .iter() + .map(|comm| { + let comm = Pcs::get_pure_commitment(comm); + Pcs::write_commitment(&comm, &mut transcript).unwrap(); + comm + }) + .collect_vec(); + let points = get_points_from_challenge( + |i| num_vars - log2_ceil(i + 1), + num_points, + &mut transcript, + ); + + let values: Vec = evals + .iter() + .map(Evaluation::value) + .map(|x| *x) + .collect::>(); + transcript.append_field_element_exts(values.as_slice()); + + let backup_transcript = transcript.clone(); + + Pcs::batch_verify_vlmp( + &vp, + &comms, + &vecs_as_slices(&points), + &evals, + &proof, + &mut transcript, + ) + .unwrap(); + + group.bench_function( + BenchmarkId::new("batch_verify", format!("{}-{}", num_vars, batch_size)), + |b| { + b.iter_batched( + || backup_transcript.clone(), + |mut transcript| { + Pcs::batch_verify_vlmp( + &vp, + &comms, + &vecs_as_slices(&points), + &evals, + &proof, + &mut transcript, + ) + .unwrap(); + }, + BatchSize::SmallInput, + ); + }, + ); + } + } +} + +fn bench_simple_batch_commit_open_verify_goldilocks>( + c: &mut Criterion, + is_base: bool, + id: &str, +) { + let mut group = c.benchmark_group(format!( + "simple_batch_commit_open_verify_goldilocks_{}_{}", + id, + if is_base { "base" } else { "extension" }, + )); + group.sample_size(NUM_SAMPLES); + // Challenge is over extension field, poly over the base field + for num_vars in NUM_VARS_START..=NUM_VARS_END { + for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { + let batch_size = 1 << batch_size_log; + let (pp, vp) = setup_pcs::(num_vars); + let mut transcript = T::new(b"BaseFold"); + let polys = gen_rand_polys(|_| num_vars, batch_size, is_base); + let comm = Pcs::batch_commit_and_write(&pp, &polys, &mut transcript).unwrap(); + + group.bench_function( + BenchmarkId::new("batch_commit", format!("{}-{}", num_vars, batch_size)), + |b| { + b.iter(|| { + Pcs::batch_commit(&pp, &polys).unwrap(); + }) + }, + ); + let point = get_point_from_challenge(num_vars, &mut transcript); + let evals = polys.iter().map(|poly| poly.evaluate(&point)).collect_vec(); + transcript.append_field_element_exts(&evals); + let transcript_for_bench = transcript.clone(); + let polys = polys + .iter() + .map(|poly| ArcMultilinearExtension::from(poly.clone())) + .collect::>(); + let proof = Pcs::simple_batch_open(&pp, &polys, &comm, &point, &evals, &mut transcript) + .unwrap(); + + group.bench_function( + BenchmarkId::new("batch_open", format!("{}-{}", num_vars, batch_size)), + |b| { + b.iter_batched( + || transcript_for_bench.clone(), + |mut transcript| { + Pcs::simple_batch_open( + &pp, + &polys, + &comm, + &point, + &evals, + &mut transcript, + ) + .unwrap(); + }, + BatchSize::SmallInput, + ); + }, + ); + let comm = Pcs::get_pure_commitment(&comm); + + // Batch verify + let mut transcript = Transcript::new(b"BaseFold"); + Pcs::write_commitment(&comm, &mut transcript).unwrap(); + + let point = get_point_from_challenge(num_vars, &mut transcript); + transcript.append_field_element_exts(&evals); + let backup_transcript = transcript.clone(); + + Pcs::simple_batch_verify(&vp, &comm, &point, &evals, &proof, &mut transcript).unwrap(); + + group.bench_function( + BenchmarkId::new("batch_verify", format!("{}-{}", num_vars, batch_size)), + |b| { + b.iter_batched( + || backup_transcript.clone(), + |mut transcript| { + Pcs::simple_batch_verify( + &vp, + &comm, + &point, + &evals, + &proof, + &mut transcript, + ) + .unwrap(); + }, + BatchSize::SmallInput, + ); + }, + ); + } + } +} + +fn bench_batch_vlop_commit_open_verify_goldilocks>( + c: &mut Criterion, + is_base: bool, + id: &str, +) { + let mut group = c.benchmark_group(format!( + "batch_vlop_commit_open_verify_goldilocks_{}_{}", + id, + if is_base { "base" } else { "extension" }, + )); + group.sample_size(NUM_SAMPLES); + // Challenge is over extension field, poly over the base field + for num_vars in NUM_VARS_START..=NUM_VARS_END { + for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { + let batch_size_outer_log = batch_size_log / 2; + let batch_size_inner_log = batch_size_log - batch_size_outer_log; + let batch_size_outer = 1 << batch_size_outer_log; + let batch_size_inner = 1 << batch_size_inner_log; + + let (pp, vp) = setup_pcs::(num_vars); + + let mut transcript = Transcript::new(b"BaseFold"); + let (polys, comms) = (0..batch_size_outer) + .map(|i| { + let polys = gen_rand_polys(|_| num_vars - i, batch_size_inner, is_base); + let comm = Pcs::batch_commit_and_write(&pp, &polys, &mut transcript).unwrap(); + (polys, comm) + }) + .collect::<(Vec<_>, Vec<_>)>(); + + let point = get_point_from_challenge(num_vars, &mut transcript); + let evals = polys + .iter() + .map(|polys| { + let evals = polys + .iter() + .map(|poly| poly.evaluate(&point[..poly.num_vars()])) + .collect_vec(); + transcript.append_field_element_exts(&evals); + evals + }) + .collect_vec(); + let transcript_for_bench = transcript.clone(); + let polys = polys + .iter() + .map(|polys| { + polys + .iter() + .map(|poly| ArcMultilinearExtension::from(poly.clone())) + .collect_vec() + }) + .collect_vec(); + + let proof = Pcs::batch_open_vlop( + &pp, + &vecs_as_slices(&polys), + &comms, + &point, + &vecs_as_slices(&evals), + &mut transcript, + ) + .unwrap(); + + group.bench_function( + BenchmarkId::new( + "batch_open", + format!("{}-{}-{}", num_vars, batch_size_outer, batch_size_inner), + ), + |b| { + b.iter_batched( + || transcript_for_bench.clone(), + |mut transcript| { + Pcs::batch_open_vlop( + &pp, + &vecs_as_slices(&polys), + &comms, + &point, + &vecs_as_slices(&evals), + &mut transcript, + ) + .unwrap(); + }, + BatchSize::SmallInput, + ); + }, + ); + + // Batch verify + + let mut transcript = Transcript::new(b"BaseFold"); + let comms = comms + .iter() + .map(|comm| { + let comm = Pcs::get_pure_commitment(comm); + Pcs::write_commitment(&comm, &mut transcript).unwrap(); + comm + }) + .collect_vec(); + + let point = get_point_from_challenge(num_vars, &mut transcript); + evals.iter().for_each(|evals| { + transcript.append_field_element_exts(evals); + }); + let backup_transcript = transcript.clone(); + + Pcs::batch_verify_vlop( + &vp, + &comms, + &point, + num_vars, + &vecs_as_slices(&evals), + &proof, + &mut transcript, + ) + .unwrap(); + + group.bench_function( + BenchmarkId::new( + "batch_verify", + format!("{}-{}-{}", num_vars, batch_size_outer, batch_size_inner), + ), + |b| { + b.iter_batched( + || backup_transcript.clone(), + |mut transcript| { + Pcs::batch_verify_vlop( + &vp, + &comms, + &point, + num_vars, + &vecs_as_slices(&evals), + &proof, + &mut transcript, + ) + .unwrap(); + }, + BatchSize::SmallInput, + ); + }, + ); + } + } +} + +fn bench_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { + bench_commit_open_verify_goldilocks::(c, false, "rs"); +} + +fn bench_commit_open_verify_goldilocks_ext_basecode(c: &mut Criterion) { + bench_commit_open_verify_goldilocks::(c, false, "basecode"); +} + +fn bench_commit_open_verify_goldilocks_base_rs(c: &mut Criterion) { + bench_commit_open_verify_goldilocks::(c, true, "rs"); +} + +fn bench_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { + bench_commit_open_verify_goldilocks::(c, true, "basecode"); +} + +fn bench_batch_vlmp_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { + bench_batch_vlmp_commit_open_verify_goldilocks::(c, false, "rs"); +} + +fn bench_batch_vlmp_commit_open_verify_goldilocks_ext_basecode(c: &mut Criterion) { + bench_batch_vlmp_commit_open_verify_goldilocks::(c, false, "basecode"); +} + +fn bench_batch_vlmp_commit_open_verify_goldilocks_base_rs(c: &mut Criterion) { + bench_batch_vlmp_commit_open_verify_goldilocks::(c, true, "rs"); +} + +fn bench_batch_vlmp_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { + bench_batch_vlmp_commit_open_verify_goldilocks::(c, true, "basecode"); +} + +fn bench_simple_batch_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { + bench_simple_batch_commit_open_verify_goldilocks::(c, false, "rs"); +} + +fn bench_simple_batch_commit_open_verify_goldilocks_ext_basecode(c: &mut Criterion) { + bench_simple_batch_commit_open_verify_goldilocks::(c, false, "basecode"); +} + +fn bench_simple_batch_commit_open_verify_goldilocks_base_rs(c: &mut Criterion) { + bench_simple_batch_commit_open_verify_goldilocks::(c, true, "rs"); +} + +fn bench_simple_batch_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { + bench_simple_batch_commit_open_verify_goldilocks::(c, true, "basecode"); +} + +fn bench_batch_vlop_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { + bench_batch_vlop_commit_open_verify_goldilocks::(c, false, "rs"); +} + +fn bench_batch_vlop_commit_open_verify_goldilocks_ext_basecode(c: &mut Criterion) { + bench_batch_vlop_commit_open_verify_goldilocks::(c, false, "basecode"); +} + +fn bench_batch_vlop_commit_open_verify_goldilocks_base_rs(c: &mut Criterion) { + bench_batch_vlop_commit_open_verify_goldilocks::(c, true, "rs"); +} + +fn bench_batch_vlop_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { + bench_batch_vlop_commit_open_verify_goldilocks::(c, true, "basecode"); +} + +criterion_group! { + name = bench_basefold; + config = Criterion::default().warm_up_time(Duration::from_millis(3000)); + targets = + bench_simple_batch_commit_open_verify_goldilocks_base_rs, bench_simple_batch_commit_open_verify_goldilocks_ext_rs, + bench_batch_vlop_commit_open_verify_goldilocks_base_rs, bench_batch_vlop_commit_open_verify_goldilocks_ext_rs, + bench_batch_vlmp_commit_open_verify_goldilocks_base_rs, bench_batch_vlmp_commit_open_verify_goldilocks_ext_rs, bench_commit_open_verify_goldilocks_base_rs, bench_commit_open_verify_goldilocks_ext_rs,bench_batch_vlop_commit_open_verify_goldilocks_base_basecode, bench_batch_vlop_commit_open_verify_goldilocks_ext_basecode, + bench_simple_batch_commit_open_verify_goldilocks_base_basecode, bench_simple_batch_commit_open_verify_goldilocks_ext_basecode, bench_batch_vlmp_commit_open_verify_goldilocks_base_basecode, bench_batch_vlmp_commit_open_verify_goldilocks_ext_basecode, bench_commit_open_verify_goldilocks_base_basecode, bench_commit_open_verify_goldilocks_ext_basecode, +} + +criterion_main!(bench_basefold); diff --git a/mpcs/benches/commit_open_verify_basecode.rs b/mpcs/benches/commit_open_verify_basecode.rs deleted file mode 100644 index 1a22e9171..000000000 --- a/mpcs/benches/commit_open_verify_basecode.rs +++ /dev/null @@ -1,400 +0,0 @@ -use std::time::Duration; - -use criterion::*; -use ff::Field; -use goldilocks::GoldilocksExt2; - -use itertools::{Itertools, chain}; -use mpcs::{ - Basefold, BasefoldBasecodeParams, Evaluation, PolynomialCommitmentScheme, - util::plonky2_util::log2_ceil, -}; - -use multilinear_extensions::mle::{DenseMultilinearExtension, MultilinearExtension}; -use rand::{SeedableRng, rngs::OsRng}; -use rand_chacha::ChaCha8Rng; -use transcript::Transcript; - -type Pcs = Basefold; -type T = Transcript; -type E = GoldilocksExt2; - -const NUM_SAMPLES: usize = 10; -const NUM_VARS_START: usize = 20; -const NUM_VARS_END: usize = 20; -const BATCH_SIZE_LOG_START: usize = 6; -const BATCH_SIZE_LOG_END: usize = 6; - -fn bench_commit_open_verify_goldilocks(c: &mut Criterion, is_base: bool) { - let mut group = c.benchmark_group(format!( - "commit_open_verify_goldilocks_basecode_{}", - if is_base { "base" } else { "ext2" } - )); - group.sample_size(NUM_SAMPLES); - // Challenge is over extension field, poly over the base field - for num_vars in NUM_VARS_START..=NUM_VARS_END { - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - - group.bench_function(BenchmarkId::new("setup", format!("{}", num_vars)), |b| { - b.iter(|| { - Pcs::setup(poly_size).unwrap(); - }) - }); - Pcs::trim(¶m, poly_size).unwrap() - }; - - let mut transcript = T::new(b"BaseFold"); - let poly = if is_base { - DenseMultilinearExtension::random(num_vars, &mut OsRng) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars, - (0..1 << num_vars).map(|_| E::random(&mut OsRng)).collect(), - ) - }; - - let comm = Pcs::commit_and_write(&pp, &poly, &mut transcript).unwrap(); - - group.bench_function(BenchmarkId::new("commit", format!("{}", num_vars)), |b| { - b.iter(|| { - Pcs::commit(&pp, &poly).unwrap(); - }) - }); - - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - let eval = poly.evaluate(point.as_slice()); - transcript.append_field_element_ext(&eval); - let transcript_for_bench = transcript.clone(); - let proof = Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); - - group.bench_function(BenchmarkId::new("open", format!("{}", num_vars)), |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); - }, - BatchSize::SmallInput, - ); - }); - // Verify - let comm = Pcs::get_pure_commitment(&comm); - let mut transcript = T::new(b"BaseFold"); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - transcript.append_field_element_ext(&eval); - let transcript_for_bench = transcript.clone(); - Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript).unwrap(); - group.bench_function(BenchmarkId::new("verify", format!("{}", num_vars)), |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript).unwrap(); - }, - BatchSize::SmallInput, - ); - }); - } -} - -fn bench_batch_commit_open_verify_goldilocks(c: &mut Criterion, is_base: bool) { - let mut group = c.benchmark_group(format!( - "batch_commit_open_verify_goldilocks_basecode_{}", - if is_base { "base" } else { "ext2" } - )); - group.sample_size(NUM_SAMPLES); - // Challenge is over extension field, poly over the base field - for num_vars in NUM_VARS_START..=NUM_VARS_END { - for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { - let batch_size = 1 << batch_size_log; - let num_points = batch_size >> 1; - let rng = ChaCha8Rng::from_seed([0u8; 32]); - // Setup - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - Pcs::trim(¶m, poly_size).unwrap() - }; - // Batch commit and open - let evals = chain![ - (0..num_points).map(|point| (point * 2, point)), // Every point matches two polys - (0..num_points).map(|point| (point * 2 + 1, point)), - ] - .unique() - .collect_vec(); - - let mut transcript = T::new(b"BaseFold"); - let polys = (0..batch_size) - .map(|i| { - if is_base { - DenseMultilinearExtension::random( - num_vars - log2_ceil((i >> 1) + 1), - &mut rng.clone(), - ) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars - log2_ceil((i >> 1) + 1), - (0..1 << (num_vars - log2_ceil((i >> 1) + 1))) - .map(|_| E::random(&mut OsRng)) - .collect(), - ) - } - }) - .collect_vec(); - let comms = polys - .iter() - .map(|poly| Pcs::commit_and_write(&pp, poly, &mut transcript).unwrap()) - .collect_vec(); - - let points = (0..num_points) - .map(|i| { - (0..num_vars - i) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>() - }) - .take(num_points) - .collect_vec(); - - let evals = evals - .iter() - .copied() - .map(|(poly, point)| { - Evaluation::new(poly, point, polys[poly].evaluate(&points[point])) - }) - .collect_vec(); - let values: Vec = evals - .iter() - .map(Evaluation::value) - .copied() - .collect::>(); - transcript.append_field_element_exts(values.as_slice()); - let transcript_for_bench = transcript.clone(); - let proof = - Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_open", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - // Batch verify - let mut transcript = T::new(b"BaseFold"); - let comms = comms - .iter() - .map(|comm| { - let comm = Pcs::get_pure_commitment(comm); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - comm - }) - .collect_vec(); - let points = (0..num_points) - .map(|i| { - (0..num_vars - i) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>() - }) - .take(num_points) - .collect_vec(); - - let values: Vec = evals - .iter() - .map(Evaluation::value) - .copied() - .collect::>(); - transcript.append_field_element_exts(values.as_slice()); - - let backup_transcript = transcript.clone(); - - Pcs::batch_verify(&vp, &comms, &points, &evals, &proof, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_verify", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || backup_transcript.clone(), - |mut transcript| { - Pcs::batch_verify( - &vp, - &comms, - &points, - &evals, - &proof, - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - } - } -} - -fn bench_simple_batch_commit_open_verify_goldilocks(c: &mut Criterion, is_base: bool) { - let mut group = c.benchmark_group(format!( - "simple_batch_commit_open_verify_goldilocks_basecode_{}", - if is_base { "base" } else { "extension" } - )); - group.sample_size(NUM_SAMPLES); - // Challenge is over extension field, poly over the base field - for num_vars in NUM_VARS_START..=NUM_VARS_END { - for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { - let batch_size = 1 << batch_size_log; - let rng = ChaCha8Rng::from_seed([0u8; 32]); - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - Pcs::trim(¶m, poly_size).unwrap() - }; - let mut transcript = T::new(b"BaseFold"); - let polys = (0..batch_size) - .map(|_| { - if is_base { - DenseMultilinearExtension::random(num_vars, &mut rng.clone()) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars, - (0..1 << num_vars).map(|_| E::random(&mut OsRng)).collect(), - ) - } - }) - .collect_vec(); - let comm = Pcs::batch_commit_and_write(&pp, &polys, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_commit", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter(|| { - Pcs::batch_commit(&pp, &polys).unwrap(); - }) - }, - ); - - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - - let evals = (0..batch_size) - .map(|i| polys[i].evaluate(&point)) - .collect_vec(); - - transcript.append_field_element_exts(&evals); - let transcript_for_bench = transcript.clone(); - let polys = polys - .clone() - .into_iter() - .map(|x| x.into()) - .collect::>(); - let proof = Pcs::simple_batch_open( - &pp, - polys.as_slice(), - &comm, - &point, - &evals, - &mut transcript, - ) - .unwrap(); - - group.bench_function( - BenchmarkId::new("batch_open", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::simple_batch_open( - &pp, - polys.as_slice(), - &comm, - &point, - &evals, - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - let comm = Pcs::get_pure_commitment(&comm); - - // Batch verify - let mut transcript = Transcript::new(b"BaseFold"); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - transcript.append_field_element_exts(&evals); - let backup_transcript = transcript.clone(); - - Pcs::simple_batch_verify(&vp, &comm, &point, &evals, &proof, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_verify", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || backup_transcript.clone(), - |mut transcript| { - Pcs::simple_batch_verify( - &vp, - &comm, - &point, - &evals, - &proof, - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - } - } -} - -fn bench_commit_open_verify_goldilocks_2(c: &mut Criterion) { - bench_commit_open_verify_goldilocks(c, false); -} - -fn bench_commit_open_verify_goldilocks_base(c: &mut Criterion) { - bench_commit_open_verify_goldilocks(c, true); -} - -fn bench_batch_commit_open_verify_goldilocks_2(c: &mut Criterion) { - bench_batch_commit_open_verify_goldilocks(c, false); -} - -fn bench_batch_commit_open_verify_goldilocks_base(c: &mut Criterion) { - bench_batch_commit_open_verify_goldilocks(c, true); -} - -fn bench_simple_batch_commit_open_verify_goldilocks_2(c: &mut Criterion) { - bench_simple_batch_commit_open_verify_goldilocks(c, false); -} - -fn bench_simple_batch_commit_open_verify_goldilocks_base(c: &mut Criterion) { - bench_simple_batch_commit_open_verify_goldilocks(c, true); -} - -criterion_group! { - name = bench_basefold; - config = Criterion::default().warm_up_time(Duration::from_millis(3000)); - targets = bench_simple_batch_commit_open_verify_goldilocks_base, bench_simple_batch_commit_open_verify_goldilocks_2,bench_batch_commit_open_verify_goldilocks_base, bench_batch_commit_open_verify_goldilocks_2, bench_commit_open_verify_goldilocks_base, bench_commit_open_verify_goldilocks_2, -} - -criterion_main!(bench_basefold); diff --git a/mpcs/benches/commit_open_verify_rs.rs b/mpcs/benches/commit_open_verify_rs.rs deleted file mode 100644 index 686253218..000000000 --- a/mpcs/benches/commit_open_verify_rs.rs +++ /dev/null @@ -1,402 +0,0 @@ -use std::time::Duration; - -use criterion::*; -use ff::Field; -use goldilocks::GoldilocksExt2; - -use itertools::{Itertools, chain}; -use mpcs::{ - Basefold, BasefoldRSParams, Evaluation, PolynomialCommitmentScheme, - util::plonky2_util::log2_ceil, -}; - -use multilinear_extensions::{ - mle::{DenseMultilinearExtension, MultilinearExtension}, - virtual_poly_v2::ArcMultilinearExtension, -}; -use rand::{SeedableRng, rngs::OsRng}; -use rand_chacha::ChaCha8Rng; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; -use transcript::Transcript; - -type Pcs = Basefold; -type T = Transcript; -type E = GoldilocksExt2; - -const NUM_SAMPLES: usize = 10; -const NUM_VARS_START: usize = 20; -const NUM_VARS_END: usize = 20; -const BATCH_SIZE_LOG_START: usize = 6; -const BATCH_SIZE_LOG_END: usize = 6; - -fn bench_commit_open_verify_goldilocks(c: &mut Criterion, is_base: bool) { - let mut group = c.benchmark_group(format!( - "commit_open_verify_goldilocks_rs_{}", - if is_base { "base" } else { "ext2" } - )); - group.sample_size(NUM_SAMPLES); - // Challenge is over extension field, poly over the base field - for num_vars in NUM_VARS_START..=NUM_VARS_END { - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - - group.bench_function(BenchmarkId::new("setup", format!("{}", num_vars)), |b| { - b.iter(|| { - Pcs::setup(poly_size).unwrap(); - }) - }); - Pcs::trim(¶m, poly_size).unwrap() - }; - - let mut transcript = T::new(b"BaseFold"); - let poly = if is_base { - DenseMultilinearExtension::random(num_vars, &mut OsRng) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars, - (0..1 << num_vars) - .into_par_iter() - .map(|_| E::random(&mut OsRng)) - .collect(), - ) - }; - - let comm = Pcs::commit_and_write(&pp, &poly, &mut transcript).unwrap(); - - group.bench_function(BenchmarkId::new("commit", format!("{}", num_vars)), |b| { - b.iter(|| { - Pcs::commit(&pp, &poly).unwrap(); - }) - }); - - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - let eval = poly.evaluate(point.as_slice()); - transcript.append_field_element_ext(&eval); - let transcript_for_bench = transcript.clone(); - let proof = Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); - - group.bench_function(BenchmarkId::new("open", format!("{}", num_vars)), |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); - }, - BatchSize::SmallInput, - ); - }); - // Verify - let comm = Pcs::get_pure_commitment(&comm); - let mut transcript = T::new(b"BaseFold"); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - transcript.append_field_element_ext(&eval); - let transcript_for_bench = transcript.clone(); - Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript).unwrap(); - group.bench_function(BenchmarkId::new("verify", format!("{}", num_vars)), |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::verify(&vp, &comm, &point, &eval, &proof, &mut transcript).unwrap(); - }, - BatchSize::SmallInput, - ); - }); - } -} - -fn bench_batch_commit_open_verify_goldilocks(c: &mut Criterion, is_base: bool) { - let mut group = c.benchmark_group(format!( - "batch_commit_open_verify_goldilocks_rs_{}", - if is_base { "base" } else { "ext2" } - )); - group.sample_size(NUM_SAMPLES); - // Challenge is over extension field, poly over the base field - for num_vars in NUM_VARS_START..=NUM_VARS_END { - for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { - let batch_size = 1 << batch_size_log; - let num_points = batch_size >> 1; - let rng = ChaCha8Rng::from_seed([0u8; 32]); - // Setup - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - Pcs::trim(¶m, poly_size).unwrap() - }; - // Batch commit and open - let evals = chain![ - (0..num_points).map(|point| (point * 2, point)), // Every point matches two polys - (0..num_points).map(|point| (point * 2 + 1, point)), - ] - .unique() - .collect_vec(); - - let mut transcript = T::new(b"BaseFold"); - let polys = (0..batch_size) - .map(|i| { - if is_base { - DenseMultilinearExtension::random( - num_vars - log2_ceil((i >> 1) + 1), - &mut rng.clone(), - ) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars - log2_ceil((i >> 1) + 1), - (0..1 << (num_vars - log2_ceil((i >> 1) + 1))) - .into_par_iter() - .map(|_| E::random(&mut OsRng)) - .collect(), - ) - } - }) - .collect_vec(); - let comms = polys - .iter() - .map(|poly| Pcs::commit_and_write(&pp, poly, &mut transcript).unwrap()) - .collect_vec(); - - let points = (0..num_points) - .map(|i| { - (0..num_vars - i) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>() - }) - .take(num_points) - .collect_vec(); - - let evals = evals - .iter() - .copied() - .map(|(poly, point)| { - Evaluation::new(poly, point, polys[poly].evaluate(&points[point])) - }) - .collect_vec(); - let values: Vec = evals - .iter() - .map(Evaluation::value) - .copied() - .collect::>(); - transcript.append_field_element_exts(values.as_slice()); - let transcript_for_bench = transcript.clone(); - let proof = - Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_open", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - // Batch verify - let mut transcript = T::new(b"BaseFold"); - let comms = comms - .iter() - .map(|comm| { - let comm = Pcs::get_pure_commitment(comm); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - comm - }) - .collect_vec(); - let points = (0..num_points) - .map(|i| { - (0..num_vars - i) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>() - }) - .take(num_points) - .collect_vec(); - - let values: Vec = evals - .iter() - .map(Evaluation::value) - .copied() - .collect::>(); - transcript.append_field_element_exts(values.as_slice()); - - let backup_transcript = transcript.clone(); - - Pcs::batch_verify(&vp, &comms, &points, &evals, &proof, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_verify", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || backup_transcript.clone(), - |mut transcript| { - Pcs::batch_verify( - &vp, - &comms, - &points, - &evals, - &proof, - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - } - } -} - -fn bench_simple_batch_commit_open_verify_goldilocks(c: &mut Criterion, is_base: bool) { - let mut group = c.benchmark_group(format!( - "simple_batch_commit_open_verify_goldilocks_rs_{}", - if is_base { "base" } else { "extension" } - )); - group.sample_size(NUM_SAMPLES); - // Challenge is over extension field, poly over the base field - for num_vars in NUM_VARS_START..=NUM_VARS_END { - for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { - let batch_size = 1 << batch_size_log; - let rng = ChaCha8Rng::from_seed([0u8; 32]); - let (pp, vp) = { - let poly_size = 1 << num_vars; - let param = Pcs::setup(poly_size).unwrap(); - Pcs::trim(¶m, poly_size).unwrap() - }; - let mut transcript = T::new(b"BaseFold"); - let polys = (0..batch_size) - .map(|_| { - if is_base { - DenseMultilinearExtension::random(num_vars, &mut rng.clone()) - } else { - DenseMultilinearExtension::from_evaluations_ext_vec( - num_vars, - (0..1 << num_vars) - .into_par_iter() - .map(|_| E::random(&mut OsRng)) - .collect(), - ) - } - }) - .collect_vec(); - let comm = Pcs::batch_commit_and_write(&pp, &polys, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_commit", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter(|| { - Pcs::batch_commit(&pp, &polys).unwrap(); - }) - }, - ); - - let polys: Vec> = - polys.into_iter().map(|poly| poly.into()).collect_vec(); - - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - - let evals = (0..batch_size) - .map(|i| polys[i].evaluate(&point)) - .collect_vec(); - - transcript.append_field_element_exts(&evals); - let transcript_for_bench = transcript.clone(); - let proof = Pcs::simple_batch_open(&pp, &polys, &comm, &point, &evals, &mut transcript) - .unwrap(); - - group.bench_function( - BenchmarkId::new("batch_open", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::simple_batch_open( - &pp, - &polys, - &comm, - &point, - &evals, - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - let comm = Pcs::get_pure_commitment(&comm); - - // Batch verify - let mut transcript = Transcript::new(b"BaseFold"); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - - let point = (0..num_vars) - .map(|_| transcript.get_and_append_challenge(b"Point").elements) - .collect::>(); - transcript.append_field_element_exts(&evals); - let backup_transcript = transcript.clone(); - - Pcs::simple_batch_verify(&vp, &comm, &point, &evals, &proof, &mut transcript).unwrap(); - - group.bench_function( - BenchmarkId::new("batch_verify", format!("{}-{}", num_vars, batch_size)), - |b| { - b.iter_batched( - || backup_transcript.clone(), - |mut transcript| { - Pcs::simple_batch_verify( - &vp, - &comm, - &point, - &evals, - &proof, - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - } - } -} - -fn bench_commit_open_verify_goldilocks_2(c: &mut Criterion) { - bench_commit_open_verify_goldilocks(c, false); -} - -fn bench_commit_open_verify_goldilocks_base(c: &mut Criterion) { - bench_commit_open_verify_goldilocks(c, true); -} - -fn bench_batch_commit_open_verify_goldilocks_2(c: &mut Criterion) { - bench_batch_commit_open_verify_goldilocks(c, false); -} - -fn bench_batch_commit_open_verify_goldilocks_base(c: &mut Criterion) { - bench_batch_commit_open_verify_goldilocks(c, true); -} - -fn bench_simple_batch_commit_open_verify_goldilocks_2(c: &mut Criterion) { - bench_simple_batch_commit_open_verify_goldilocks(c, false); -} - -fn bench_simple_batch_commit_open_verify_goldilocks_base(c: &mut Criterion) { - bench_simple_batch_commit_open_verify_goldilocks(c, true); -} - -criterion_group! { - name = bench_basefold; - config = Criterion::default().warm_up_time(Duration::from_millis(3000)); - targets = bench_simple_batch_commit_open_verify_goldilocks_base, bench_simple_batch_commit_open_verify_goldilocks_2, bench_batch_commit_open_verify_goldilocks_base, bench_batch_commit_open_verify_goldilocks_2, bench_commit_open_verify_goldilocks_base, bench_commit_open_verify_goldilocks_2, -} - -criterion_main!(bench_basefold); From dc6b59925122ad609e894d22b9c95c4a7a2f405a Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 07:23:32 +0800 Subject: [PATCH 08/18] Merge two benchmarks sharing similar codes. --- mpcs/benches/basefold.rs | 226 ++++----------------------------------- mpcs/src/lib.rs | 17 ++- 2 files changed, 31 insertions(+), 212 deletions(-) diff --git a/mpcs/benches/basefold.rs b/mpcs/benches/basefold.rs index b30866a79..9170612a1 100644 --- a/mpcs/benches/basefold.rs +++ b/mpcs/benches/basefold.rs @@ -8,7 +8,7 @@ use mpcs::{ Basefold, BasefoldBasecodeParams, BasefoldRSParams, Evaluation, PolynomialCommitmentScheme, test_util::{ commit_polys_individually, gen_rand_poly, gen_rand_polys, get_point_from_challenge, - get_points_from_challenge, setup_pcs, vecs_as_slices, + get_points_from_challenge, setup_pcs, }, util::plonky2_util::log2_ceil, }; @@ -66,7 +66,6 @@ fn bench_commit_open_verify_goldilocks>( let eval = poly.evaluate(point.as_slice()); transcript.append_field_element_ext(&eval); let transcript_for_bench = transcript.clone(); - let poly = ArcMultilinearExtension::from(poly); let proof = Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); group.bench_function(BenchmarkId::new("open", format!("{}", num_vars)), |b| { @@ -98,7 +97,7 @@ fn bench_commit_open_verify_goldilocks>( } } -fn bench_batch_vlmp_commit_open_verify_goldilocks>( +fn bench_batch_commit_open_verify_goldilocks>( c: &mut Criterion, is_base: bool, id: &str, @@ -148,19 +147,8 @@ fn bench_batch_vlmp_commit_open_verify_goldilocks>(); transcript.append_field_element_exts(values.as_slice()); let transcript_for_bench = transcript.clone(); - let polys = polys - .iter() - .map(|poly| ArcMultilinearExtension::from(poly.clone())) - .collect::>(); - let proof = Pcs::batch_open_vlmp( - &pp, - &polys, - &comms, - &vecs_as_slices(&points), - &evals, - &mut transcript, - ) - .unwrap(); + let proof = + Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); group.bench_function( BenchmarkId::new("batch_open", format!("{}-{}", num_vars, batch_size)), @@ -168,15 +156,8 @@ fn bench_batch_vlmp_commit_open_verify_goldilocks>( - c: &mut Criterion, - is_base: bool, - id: &str, -) { - let mut group = c.benchmark_group(format!( - "batch_vlop_commit_open_verify_goldilocks_{}_{}", - id, - if is_base { "base" } else { "extension" }, - )); - group.sample_size(NUM_SAMPLES); - // Challenge is over extension field, poly over the base field - for num_vars in NUM_VARS_START..=NUM_VARS_END { - for batch_size_log in BATCH_SIZE_LOG_START..=BATCH_SIZE_LOG_END { - let batch_size_outer_log = batch_size_log / 2; - let batch_size_inner_log = batch_size_log - batch_size_outer_log; - let batch_size_outer = 1 << batch_size_outer_log; - let batch_size_inner = 1 << batch_size_inner_log; - - let (pp, vp) = setup_pcs::(num_vars); - - let mut transcript = Transcript::new(b"BaseFold"); - let (polys, comms) = (0..batch_size_outer) - .map(|i| { - let polys = gen_rand_polys(|_| num_vars - i, batch_size_inner, is_base); - let comm = Pcs::batch_commit_and_write(&pp, &polys, &mut transcript).unwrap(); - (polys, comm) - }) - .collect::<(Vec<_>, Vec<_>)>(); - - let point = get_point_from_challenge(num_vars, &mut transcript); - let evals = polys - .iter() - .map(|polys| { - let evals = polys - .iter() - .map(|poly| poly.evaluate(&point[..poly.num_vars()])) - .collect_vec(); - transcript.append_field_element_exts(&evals); - evals - }) - .collect_vec(); - let transcript_for_bench = transcript.clone(); - let polys = polys - .iter() - .map(|polys| { - polys - .iter() - .map(|poly| ArcMultilinearExtension::from(poly.clone())) - .collect_vec() - }) - .collect_vec(); - - let proof = Pcs::batch_open_vlop( - &pp, - &vecs_as_slices(&polys), - &comms, - &point, - &vecs_as_slices(&evals), - &mut transcript, - ) - .unwrap(); - - group.bench_function( - BenchmarkId::new( - "batch_open", - format!("{}-{}-{}", num_vars, batch_size_outer, batch_size_inner), - ), - |b| { - b.iter_batched( - || transcript_for_bench.clone(), - |mut transcript| { - Pcs::batch_open_vlop( - &pp, - &vecs_as_slices(&polys), - &comms, - &point, - &vecs_as_slices(&evals), - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - - // Batch verify - - let mut transcript = Transcript::new(b"BaseFold"); - let comms = comms - .iter() - .map(|comm| { - let comm = Pcs::get_pure_commitment(comm); - Pcs::write_commitment(&comm, &mut transcript).unwrap(); - comm - }) - .collect_vec(); - - let point = get_point_from_challenge(num_vars, &mut transcript); - evals.iter().for_each(|evals| { - transcript.append_field_element_exts(evals); - }); - let backup_transcript = transcript.clone(); - - Pcs::batch_verify_vlop( - &vp, - &comms, - &point, - num_vars, - &vecs_as_slices(&evals), - &proof, - &mut transcript, - ) - .unwrap(); - - group.bench_function( - BenchmarkId::new( - "batch_verify", - format!("{}-{}-{}", num_vars, batch_size_outer, batch_size_inner), - ), - |b| { - b.iter_batched( - || backup_transcript.clone(), - |mut transcript| { - Pcs::batch_verify_vlop( - &vp, - &comms, - &point, - num_vars, - &vecs_as_slices(&evals), - &proof, - &mut transcript, - ) - .unwrap(); - }, - BatchSize::SmallInput, - ); - }, - ); - } - } -} - fn bench_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { bench_commit_open_verify_goldilocks::(c, false, "rs"); } @@ -496,20 +325,20 @@ fn bench_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { bench_commit_open_verify_goldilocks::(c, true, "basecode"); } -fn bench_batch_vlmp_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { - bench_batch_vlmp_commit_open_verify_goldilocks::(c, false, "rs"); +fn bench_batch_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { + bench_batch_commit_open_verify_goldilocks::(c, false, "rs"); } -fn bench_batch_vlmp_commit_open_verify_goldilocks_ext_basecode(c: &mut Criterion) { - bench_batch_vlmp_commit_open_verify_goldilocks::(c, false, "basecode"); +fn bench_batch_commit_open_verify_goldilocks_ext_basecode(c: &mut Criterion) { + bench_batch_commit_open_verify_goldilocks::(c, false, "basecode"); } -fn bench_batch_vlmp_commit_open_verify_goldilocks_base_rs(c: &mut Criterion) { - bench_batch_vlmp_commit_open_verify_goldilocks::(c, true, "rs"); +fn bench_batch_commit_open_verify_goldilocks_base_rs(c: &mut Criterion) { + bench_batch_commit_open_verify_goldilocks::(c, true, "rs"); } -fn bench_batch_vlmp_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { - bench_batch_vlmp_commit_open_verify_goldilocks::(c, true, "basecode"); +fn bench_batch_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { + bench_batch_commit_open_verify_goldilocks::(c, true, "basecode"); } fn bench_simple_batch_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { @@ -528,30 +357,13 @@ fn bench_simple_batch_commit_open_verify_goldilocks_base_basecode(c: &mut Criter bench_simple_batch_commit_open_verify_goldilocks::(c, true, "basecode"); } -fn bench_batch_vlop_commit_open_verify_goldilocks_ext_rs(c: &mut Criterion) { - bench_batch_vlop_commit_open_verify_goldilocks::(c, false, "rs"); -} - -fn bench_batch_vlop_commit_open_verify_goldilocks_ext_basecode(c: &mut Criterion) { - bench_batch_vlop_commit_open_verify_goldilocks::(c, false, "basecode"); -} - -fn bench_batch_vlop_commit_open_verify_goldilocks_base_rs(c: &mut Criterion) { - bench_batch_vlop_commit_open_verify_goldilocks::(c, true, "rs"); -} - -fn bench_batch_vlop_commit_open_verify_goldilocks_base_basecode(c: &mut Criterion) { - bench_batch_vlop_commit_open_verify_goldilocks::(c, true, "basecode"); -} - criterion_group! { name = bench_basefold; config = Criterion::default().warm_up_time(Duration::from_millis(3000)); targets = bench_simple_batch_commit_open_verify_goldilocks_base_rs, bench_simple_batch_commit_open_verify_goldilocks_ext_rs, - bench_batch_vlop_commit_open_verify_goldilocks_base_rs, bench_batch_vlop_commit_open_verify_goldilocks_ext_rs, - bench_batch_vlmp_commit_open_verify_goldilocks_base_rs, bench_batch_vlmp_commit_open_verify_goldilocks_ext_rs, bench_commit_open_verify_goldilocks_base_rs, bench_commit_open_verify_goldilocks_ext_rs,bench_batch_vlop_commit_open_verify_goldilocks_base_basecode, bench_batch_vlop_commit_open_verify_goldilocks_ext_basecode, - bench_simple_batch_commit_open_verify_goldilocks_base_basecode, bench_simple_batch_commit_open_verify_goldilocks_ext_basecode, bench_batch_vlmp_commit_open_verify_goldilocks_base_basecode, bench_batch_vlmp_commit_open_verify_goldilocks_ext_basecode, bench_commit_open_verify_goldilocks_base_basecode, bench_commit_open_verify_goldilocks_ext_basecode, + bench_batch_commit_open_verify_goldilocks_base_rs, bench_batch_commit_open_verify_goldilocks_ext_rs, bench_commit_open_verify_goldilocks_base_rs, bench_commit_open_verify_goldilocks_ext_rs, + bench_simple_batch_commit_open_verify_goldilocks_base_basecode, bench_simple_batch_commit_open_verify_goldilocks_ext_basecode, bench_batch_commit_open_verify_goldilocks_base_basecode, bench_batch_commit_open_verify_goldilocks_ext_basecode, bench_commit_open_verify_goldilocks_base_basecode, bench_commit_open_verify_goldilocks_ext_basecode, } criterion_main!(bench_basefold); diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index 8f832ff7e..3ef0e743c 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -357,15 +357,21 @@ fn err_too_many_variates(function: &str, upto: usize, got: usize) -> Error { }) } -#[cfg(test)] +// TODO: Need to use some functions here in the integration benchmarks. But +// unfortunately integration benchmarks do not compile the #[cfg(test)] +// code. So remove the gate for the entire module, only gate the test +// functions. +// +// This is not the best way: the test utility functions should not be +// compiled in the release build. Need a better solution. +#[doc(hidden)] pub mod test_util { use crate::{Evaluation, PolynomialCommitmentScheme}; use ff_ext::ExtensionField; use itertools::{Itertools, chain}; - use multilinear_extensions::{ - mle::{DenseMultilinearExtension, MultilinearExtension}, - virtual_poly_v2::ArcMultilinearExtension, - }; + use multilinear_extensions::mle::{DenseMultilinearExtension, MultilinearExtension}; + #[cfg(test)] + use multilinear_extensions::virtual_poly_v2::ArcMultilinearExtension; use rand::rngs::OsRng; use transcript::Transcript; @@ -552,6 +558,7 @@ pub mod test_util { } } + #[cfg(test)] pub(super) fn run_simple_batch_commit_open_verify( base: bool, num_vars_start: usize, From 7dfda1202c68e4f69dc0cc86c65b54c68f507ede Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 07:31:34 +0800 Subject: [PATCH 09/18] Gate more test functions. --- mpcs/src/lib.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index 3ef0e743c..e98f84e50 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -366,12 +366,18 @@ fn err_too_many_variates(function: &str, upto: usize, got: usize) -> Error { // compiled in the release build. Need a better solution. #[doc(hidden)] pub mod test_util { - use crate::{Evaluation, PolynomialCommitmentScheme}; + #[cfg(test)] + use crate::Evaluation; + use crate::PolynomialCommitmentScheme; use ff_ext::ExtensionField; - use itertools::{Itertools, chain}; - use multilinear_extensions::mle::{DenseMultilinearExtension, MultilinearExtension}; + use itertools::Itertools; + #[cfg(test)] + use itertools::chain; + use multilinear_extensions::mle::DenseMultilinearExtension; #[cfg(test)] - use multilinear_extensions::virtual_poly_v2::ArcMultilinearExtension; + use multilinear_extensions::{ + mle::MultilinearExtension, virtual_poly_v2::ArcMultilinearExtension, + }; use rand::rngs::OsRng; use transcript::Transcript; @@ -438,6 +444,7 @@ pub mod test_util { .collect_vec() } + #[cfg(test)] pub fn run_commit_open_verify( base: bool, num_vars_start: usize, @@ -478,6 +485,7 @@ pub mod test_util { } } + #[cfg(test)] pub fn run_batch_commit_open_verify( base: bool, num_vars_start: usize, From a6c618163fc151c4a593efebf6e6ebe4a0663e2d Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 08:24:10 +0800 Subject: [PATCH 10/18] Refactor tests in basefold.rs. --- mpcs/src/basefold.rs | 139 +++++++++++++------------------------------ 1 file changed, 42 insertions(+), 97 deletions(-) diff --git a/mpcs/src/basefold.rs b/mpcs/src/basefold.rs index 3f85022cc..fcd1eb748 100644 --- a/mpcs/src/basefold.rs +++ b/mpcs/src/basefold.rs @@ -1191,108 +1191,53 @@ mod test { type PcsGoldilocksBaseCode = Basefold; #[test] - fn commit_open_verify_goldilocks_basecode_base() { - // Challenge is over extension field, poly over the base field - run_commit_open_verify::(true, 10, 11); - // Test trivial proof with small num vars - run_commit_open_verify::(true, 4, 6); - } - - #[test] - fn commit_open_verify_goldilocks_rscode_base() { - // Challenge is over extension field, poly over the base field - run_commit_open_verify::(true, 10, 11); - // Test trivial proof with small num vars - run_commit_open_verify::(true, 4, 6); - } - - #[test] - fn commit_open_verify_goldilocks_basecode_2() { - // Both challenge and poly are over extension field - run_commit_open_verify::(false, 10, 11); - // Test trivial proof with small num vars - run_commit_open_verify::(false, 4, 6); - } - - #[test] - fn commit_open_verify_goldilocks_rscode_2() { - // Both challenge and poly are over extension field - run_commit_open_verify::(false, 10, 11); - // Test trivial proof with small num vars - run_commit_open_verify::(false, 4, 6); - } - - #[test] - fn simple_batch_commit_open_verify_goldilocks_basecode_base() { - // Both challenge and poly are over base field - run_simple_batch_commit_open_verify::( - true, 10, 11, 1, - ); - run_simple_batch_commit_open_verify::( - true, 10, 11, 4, - ); - // Test trivial proof with small num vars - run_simple_batch_commit_open_verify::(true, 4, 6, 4); - } - - #[test] - fn simple_batch_commit_open_verify_goldilocks_rscode_base() { - // Both challenge and poly are over base field - run_simple_batch_commit_open_verify::(true, 10, 11, 1); - run_simple_batch_commit_open_verify::(true, 10, 11, 4); - // Test trivial proof with small num vars - run_simple_batch_commit_open_verify::(true, 4, 6, 4); - } - - #[test] - fn simple_batch_commit_open_verify_goldilocks_basecode_2() { - // Both challenge and poly are over extension field - run_simple_batch_commit_open_verify::( - false, 10, 11, 1, - ); - run_simple_batch_commit_open_verify::( - false, 10, 11, 4, - ); - // Test trivial proof with small num vars - run_simple_batch_commit_open_verify::( - false, 4, 6, 4, - ); - } - - #[test] - fn simple_batch_commit_open_verify_goldilocks_rscode_2() { - // Both challenge and poly are over extension field - run_simple_batch_commit_open_verify::( - false, 10, 11, 1, - ); - run_simple_batch_commit_open_verify::( - false, 10, 11, 4, - ); - // Test trivial proof with small num vars - run_simple_batch_commit_open_verify::(false, 4, 6, 4); - } - - #[test] - fn batch_commit_open_verify_goldilocks_basecode_base() { - // Both challenge and poly are over base field - run_batch_commit_open_verify::(true, 10, 11); - } - - #[test] - fn batch_commit_open_verify_goldilocks_rscode_base() { - // Both challenge and poly are over base field - run_batch_commit_open_verify::(true, 10, 11); + fn commit_open_verify_goldilocks() { + for base in [true, false].into_iter() { + // Challenge is over extension field, poly over the base field + run_commit_open_verify::(base, 10, 11); + // Test trivial proof with small num vars + run_commit_open_verify::(base, 4, 6); + // Challenge is over extension field, poly over the base field + run_commit_open_verify::(base, 10, 11); + // Test trivial proof with small num vars + run_commit_open_verify::(base, 4, 6); + } } #[test] - fn batch_commit_open_verify_goldilocks_basecode_2() { - // Both challenge and poly are over extension field - run_batch_commit_open_verify::(false, 10, 11); + fn simple_batch_commit_open_verify_goldilocks() { + for base in [true, false].into_iter() { + // Both challenge and poly are over base field + run_simple_batch_commit_open_verify::( + base, 10, 11, 1, + ); + run_simple_batch_commit_open_verify::( + base, 10, 11, 4, + ); + // Test trivial proof with small num vars + run_simple_batch_commit_open_verify::( + base, 4, 6, 4, + ); + // Both challenge and poly are over base field + run_simple_batch_commit_open_verify::( + base, 10, 11, 1, + ); + run_simple_batch_commit_open_verify::( + base, 10, 11, 4, + ); + // Test trivial proof with small num vars + run_simple_batch_commit_open_verify::( + base, 4, 6, 4, + ); + } } #[test] - fn batch_commit_open_verify_goldilocks_rscode_2() { - // Both challenge and poly are over extension field - run_batch_commit_open_verify::(false, 10, 11); + fn batch_commit_open_verify() { + for base in [true, false].iter() { + // Both challenge and poly are over base field + run_batch_commit_open_verify::(*base, 10, 11); + run_batch_commit_open_verify::(*base, 10, 11); + } } } From 44c5c691a81f753a1456bf672d05c46f350d838f Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 15:00:16 +0800 Subject: [PATCH 11/18] Use Arc in open APIs. --- mpcs/benches/basefold.rs | 5 ++ mpcs/src/basefold.rs | 58 +++++++++-------- mpcs/src/lib.rs | 24 ++++--- mpcs/src/util.rs | 132 +++++++++++++-------------------------- 4 files changed, 95 insertions(+), 124 deletions(-) diff --git a/mpcs/benches/basefold.rs b/mpcs/benches/basefold.rs index 9170612a1..63ed9c1ad 100644 --- a/mpcs/benches/basefold.rs +++ b/mpcs/benches/basefold.rs @@ -66,6 +66,7 @@ fn bench_commit_open_verify_goldilocks>( let eval = poly.evaluate(point.as_slice()); transcript.append_field_element_ext(&eval); let transcript_for_bench = transcript.clone(); + let poly = ArcMultilinearExtension::from(poly); let proof = Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); group.bench_function(BenchmarkId::new("open", format!("{}", num_vars)), |b| { @@ -147,6 +148,10 @@ fn bench_batch_commit_open_verify_goldilocks> .collect::>(); transcript.append_field_element_exts(values.as_slice()); let transcript_for_bench = transcript.clone(); + let polys = polys + .iter() + .map(|poly| ArcMultilinearExtension::from(poly.clone())) + .collect::>(); let proof = Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); diff --git a/mpcs/src/basefold.rs b/mpcs/src/basefold.rs index fcd1eb748..7ad751c75 100644 --- a/mpcs/src/basefold.rs +++ b/mpcs/src/basefold.rs @@ -34,7 +34,6 @@ use query_phase::{ prover_query_phase, simple_batch_prover_query_phase, simple_batch_verifier_query_phase, verifier_query_phase, }; -use std::{borrow::BorrowMut, ops::Deref}; pub use structure::BasefoldSpec; use structure::{BasefoldProof, ProofQueriesResultWithMerklePath}; use transcript::Transcript; @@ -51,7 +50,6 @@ use rayon::{ iter::IntoParallelIterator, prelude::{IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator}, }; -use std::borrow::Cow; pub use sumcheck::{one_level_eval_hc, one_level_interp_hc}; type SumCheck = ClassicSumCheck>; @@ -466,7 +464,7 @@ where /// will panic. fn open( pp: &Self::ProverParam, - poly: &DenseMultilinearExtension, + poly: &ArcMultilinearExtension, comm: &Self::CommitmentWithData, point: &[E], _eval: &E, // Opening does not need eval, except for sanity check @@ -480,7 +478,7 @@ where // the protocol won't work, and saves no verifier work anyway. // In this case, simply return the evaluations as trivial proof. if comm.is_trivial::() { - return Ok(Self::Proof::trivial(vec![poly.evaluations.clone()])); + return Ok(Self::Proof::trivial(vec![poly.evaluations().clone()])); } assert!(comm.num_vars >= Spec::get_basecode_msg_size_log()); @@ -499,8 +497,8 @@ where point, comm, transcript, - poly.num_vars, - poly.num_vars - Spec::get_basecode_msg_size_log(), + poly.num_vars(), + poly.num_vars() - Spec::get_basecode_msg_size_log(), ); // 2. Query phase. --------------------------------------- @@ -546,15 +544,15 @@ where /// not very useful in ceno. fn batch_open( pp: &Self::ProverParam, - polys: &[DenseMultilinearExtension], + polys: &[ArcMultilinearExtension], comms: &[Self::CommitmentWithData], points: &[Vec], evals: &[Evaluation], transcript: &mut Transcript, ) -> Result { let timer = start_timer!(|| "Basefold::batch_open"); - let num_vars = polys.iter().map(|poly| poly.num_vars).max().unwrap(); - let min_num_vars = polys.iter().map(|p| p.num_vars).min().unwrap(); + let num_vars = polys.iter().map(|poly| poly.num_vars()).max().unwrap(); + let min_num_vars = polys.iter().map(|p| p.num_vars()).min().unwrap(); assert!(min_num_vars >= Spec::get_basecode_msg_size_log()); comms.iter().for_each(|comm| { @@ -603,28 +601,31 @@ where let merged_polys = evals.iter().zip(poly_iter_ext(&eq_xt)).fold( // This folding will generate a vector of |points| pairs of (scalar, polynomial) // The polynomials are initialized to zero, and the scalars are initialized to one - vec![(E::ONE, Cow::>::default()); points.len()], + vec![(E::ONE, Vec::::new()); points.len()], |mut merged_polys, (eval, eq_xt_i)| { // For each polynomial to open, eval.point() specifies which point it is to be opened at. - if merged_polys[eval.point()].1.num_vars == 0 { + if merged_polys[eval.point()].1.is_empty() { // If the accumulator for this point is still the zero polynomial, // directly assign the random coefficient and the polynomial to open to // this accumulator - merged_polys[eval.point()] = (eq_xt_i, Cow::Borrowed(&polys[eval.poly()])); + merged_polys[eval.point()] = ( + eq_xt_i, + field_type_to_ext_vec(&polys[eval.poly()].evaluations()), + ); } else { // If the accumulator is unempty now, first force its scalar to 1, i.e., // make (scalar, polynomial) to (1, scalar * polynomial) let coeff = merged_polys[eval.point()].0; if coeff != E::ONE { merged_polys[eval.point()].0 = E::ONE; - multiply_poly(merged_polys[eval.point()].1.to_mut().borrow_mut(), &coeff); + multiply_poly(&mut merged_polys[eval.point()].1, &coeff); } // Equivalent to merged_poly += poly * batch_coeff. Note that // add_assign_mixed_with_coeff allows adding two polynomials with // different variables, and the result has the same number of vars // with the larger one of the two added polynomials. add_polynomial_with_coeff( - merged_polys[eval.point()].1.to_mut().borrow_mut(), + &mut merged_polys[eval.point()].1, &polys[eval.poly()], &eq_xt_i, ); @@ -642,18 +643,16 @@ where .iter() .zip(&points) .map(|((scalar, poly), point)| { - inner_product( - &poly_iter_ext(poly).collect_vec(), - build_eq_x_r_vec(point).iter(), - ) * scalar - * E::from(1 << (num_vars - poly.num_vars)) + inner_product(poly, build_eq_x_r_vec(point).iter()) + * scalar + * E::from(1 << (num_vars - log2_strict(poly.len()))) // When this polynomial is smaller, it will be repeatedly summed over the cosets of the hypercube }) .sum::(); assert_eq!(expected_sum, target_sum); merged_polys.iter().enumerate().for_each(|(i, (_, poly))| { - assert_eq!(points[i].len(), poly.num_vars); + assert_eq!(points[i].len(), log2_strict(poly.len())); }); } @@ -666,12 +665,17 @@ where * scalar }) .sum(); - let sumcheck_polys: Vec<&DenseMultilinearExtension> = merged_polys + let sumcheck_polys: Vec> = merged_polys .iter() - .map(|(_, poly)| poly.deref()) + .map(|(_, poly)| { + DenseMultilinearExtension::from_evaluations_ext_vec( + log2_strict(poly.len()), + poly.clone(), + ) + }) .collect_vec(); let virtual_poly = - VirtualPolynomial::new(&expression, sumcheck_polys, &[], points.as_slice()); + VirtualPolynomial::new(&expression, sumcheck_polys.iter(), &[], points.as_slice()); let (challenges, merged_poly_evals, sumcheck_proof) = SumCheck::prove(&(), num_vars, virtual_poly, target_sum, transcript)?; @@ -695,7 +699,7 @@ where if cfg!(feature = "sanity-check") { let poly_evals = polys .iter() - .map(|poly| poly.evaluate(&challenges[..poly.num_vars])) + .map(|poly| poly.evaluate(&challenges[..poly.num_vars()])) .collect_vec(); let new_target_sum = inner_product(&poly_evals, &coeffs); let desired_sum = merged_polys @@ -705,7 +709,11 @@ where .map(|(((scalar, poly), point), evals_from_sum_check)| { assert_eq!( evals_from_sum_check, - poly.evaluate(&challenges[..poly.num_vars]) + DenseMultilinearExtension::from_evaluations_ext_vec( + log2_strict(poly.len()), + poly.clone() + ) + .evaluate(&challenges[..log2_strict(poly.len())]) ); *scalar * evals_from_sum_check diff --git a/mpcs/src/lib.rs b/mpcs/src/lib.rs index e98f84e50..332dfd746 100644 --- a/mpcs/src/lib.rs +++ b/mpcs/src/lib.rs @@ -62,7 +62,7 @@ pub fn pcs_batch_commit_and_write>( pp: &Pcs::ProverParam, - poly: &DenseMultilinearExtension, + poly: &ArcMultilinearExtension, comm: &Pcs::CommitmentWithData, point: &[E], eval: &E, @@ -73,7 +73,7 @@ pub fn pcs_open>( pub fn pcs_batch_open>( pp: &Pcs::ProverParam, - polys: &[DenseMultilinearExtension], + polys: &[ArcMultilinearExtension], comms: &[Pcs::CommitmentWithData], points: &[Vec], evals: &[Evaluation], @@ -162,7 +162,7 @@ pub trait PolynomialCommitmentScheme: Clone + Debug { fn open( pp: &Self::ProverParam, - poly: &DenseMultilinearExtension, + poly: &ArcMultilinearExtension, comm: &Self::CommitmentWithData, point: &[E], eval: &E, @@ -171,7 +171,7 @@ pub trait PolynomialCommitmentScheme: Clone + Debug { fn batch_open( pp: &Self::ProverParam, - polys: &[DenseMultilinearExtension], + polys: &[ArcMultilinearExtension], comms: &[Self::CommitmentWithData], points: &[Vec], evals: &[Evaluation], @@ -226,7 +226,7 @@ where { fn ni_open( pp: &Self::ProverParam, - poly: &DenseMultilinearExtension, + poly: &ArcMultilinearExtension, comm: &Self::CommitmentWithData, point: &[E], eval: &E, @@ -237,7 +237,7 @@ where fn ni_batch_open( pp: &Self::ProverParam, - polys: &[DenseMultilinearExtension], + polys: &[ArcMultilinearExtension], comms: &[Self::CommitmentWithData], points: &[Vec], evals: &[Evaluation], @@ -323,17 +323,17 @@ use multilinear_extensions::virtual_poly_v2::ArcMultilinearExtension; fn validate_input( function: &str, param_num_vars: usize, - polys: &[DenseMultilinearExtension], + polys: &[ArcMultilinearExtension], points: &[Vec], ) -> Result<(), Error> { let polys = polys.iter().collect_vec(); let points = points.iter().collect_vec(); for poly in polys.iter() { - if param_num_vars < poly.num_vars { + if param_num_vars < poly.num_vars() { return Err(err_too_many_variates( function, param_num_vars, - poly.num_vars, + poly.num_vars(), )); } } @@ -462,6 +462,7 @@ pub mod test_util { let comm = Pcs::commit_and_write(&pp, &poly, &mut transcript).unwrap(); let point = get_point_from_challenge(num_vars, &mut transcript); let eval = poly.evaluate(point.as_slice()); + let poly = ArcMultilinearExtension::from(poly); transcript.append_field_element_ext(&eval); ( @@ -533,6 +534,11 @@ pub mod test_util { .collect::>(); transcript.append_field_element_exts(values.as_slice()); + let polys = polys + .iter() + .map(|poly| ArcMultilinearExtension::from(poly.clone())) + .collect_vec(); + let proof = Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); (comms, evals, proof, transcript.read_challenge()) diff --git a/mpcs/src/util.rs b/mpcs/src/util.rs index 80ecf2535..6aff42fd7 100644 --- a/mpcs/src/util.rs +++ b/mpcs/src/util.rs @@ -6,8 +6,11 @@ pub mod plonky2_util; use ff::{Field, PrimeField}; use ff_ext::ExtensionField; use goldilocks::SmallField; -use itertools::{Itertools, izip}; -use multilinear_extensions::mle::{DenseMultilinearExtension, FieldType}; +use itertools::{Either, Itertools, izip}; +use multilinear_extensions::{ + mle::{DenseMultilinearExtension, FieldType}, + virtual_poly_v2::ArcMultilinearExtension, +}; use serde::{Deserialize, Serialize, de::DeserializeOwned}; pub mod merkle_tree; use crate::{Error, util::parallel::parallelize}; @@ -183,118 +186,67 @@ pub fn field_type_iter_ext(evaluations: &FieldType) -> Fie } } -pub fn multiply_poly(poly: &mut DenseMultilinearExtension, scalar: &E) { - match &mut poly.evaluations { +pub fn field_type_iter_range_base<'a, E: ExtensionField>( + values: &'a FieldType, + range: impl IntoIterator + 'a, +) -> impl Iterator + 'a { + match values { FieldType::Ext(coeffs) => { - for coeff in coeffs.iter_mut() { - *coeff *= scalar; - } - } - FieldType::Base(coeffs) => { - *poly = DenseMultilinearExtension::::from_evaluations_ext_vec( - poly.num_vars, - coeffs.iter().map(|x| E::from(*x) * scalar).collect(), - ); + Either::Left(range.into_iter().flat_map(|i| coeffs[i].as_bases())) } + FieldType::Base(coeffs) => Either::Right(range.into_iter().map(|i| &coeffs[i])), _ => unreachable!(), } } +pub fn multiply_poly(poly: &mut [E], scalar: &E) { + for coeff in poly.iter_mut() { + *coeff *= scalar; + } +} + /// Resize to the new number of variables, which must be greater than or equal to /// the current number of variables. -pub fn resize_num_vars( - poly: &mut DenseMultilinearExtension, - num_vars: usize, -) { - assert!(num_vars >= poly.num_vars); - if num_vars == poly.num_vars { +pub fn resize_num_vars(poly: &mut Vec, num_vars: usize) { + assert!(num_vars >= log2_strict(poly.len())); + if num_vars == log2_strict(poly.len()) { return; } - match &mut poly.evaluations { - FieldType::Base(evaluations) => { - evaluations.resize(1 << num_vars, E::BaseField::ZERO); - // When evaluate a multilinear polynomial outside of its original interpolated hypercube, - // the evaluations are just repetitions of the original evaluations - (1 << poly.num_vars..1 << num_vars) - .for_each(|i| evaluations[i] = evaluations[i & ((1 << poly.num_vars) - 1)]); - } - FieldType::Ext(evaluations) => { - evaluations.resize(1 << num_vars, E::ZERO); - (1 << poly.num_vars..1 << num_vars) - .for_each(|i| evaluations[i] = evaluations[i & ((1 << poly.num_vars) - 1)]) - } - _ => unreachable!(), - } - poly.num_vars = num_vars; + poly.resize(1 << num_vars, E::ZERO); + (log2_strict(poly.len())..1 << num_vars).for_each(|i| poly[i] = poly[i & ((poly.len()) - 1)]) } pub fn add_polynomial_with_coeff( - lhs: &mut DenseMultilinearExtension, - rhs: &DenseMultilinearExtension, + lhs: &mut Vec, + rhs: &ArcMultilinearExtension, coeff: &E, ) { - match (lhs.num_vars == 0, rhs.num_vars == 0) { + match (lhs.is_empty(), rhs.num_vars() == 0) { (_, true) => {} (true, false) => { - *lhs = rhs.clone(); + *lhs = field_type_to_ext_vec(rhs.evaluations()); multiply_poly(lhs, coeff); } (false, false) => { - if lhs.num_vars < rhs.num_vars { - resize_num_vars(lhs, rhs.num_vars); + if log2_strict(lhs.len()) < rhs.num_vars() { + resize_num_vars(lhs, rhs.num_vars()); } - if rhs.num_vars < lhs.num_vars { - match &mut lhs.evaluations { - FieldType::Ext(ref mut lhs) => { - parallelize(lhs, |(lhs, start)| { - for (index, lhs) in lhs.iter_mut().enumerate() { - *lhs += *coeff - * poly_index_ext( - rhs, - (start + index) & ((1 << rhs.num_vars) - 1), - ); - } - }); - } - FieldType::Base(ref mut lhs_evals) => { - *lhs = DenseMultilinearExtension::::from_evaluations_ext_vec( - lhs.num_vars, - lhs_evals - .iter() - .enumerate() - .map(|(index, lhs)| { - E::from(*lhs) - + *coeff - * poly_index_ext(rhs, index & ((1 << rhs.num_vars) - 1)) - }) - .collect(), - ); + if rhs.num_vars() < log2_strict(lhs.len()) { + parallelize(lhs, |(lhs, start)| { + for (index, lhs) in lhs.iter_mut().enumerate() { + *lhs += *coeff + * field_type_index_ext( + rhs.evaluations(), + (start + index) & ((1 << rhs.num_vars()) - 1), + ); } - _ => unreachable!(), - } + }); } else { - match &mut lhs.evaluations { - FieldType::Ext(ref mut lhs) => { - parallelize(lhs, |(lhs, start)| { - for (index, lhs) in lhs.iter_mut().enumerate() { - *lhs += *coeff * poly_index_ext(rhs, start + index); - } - }); - } - FieldType::Base(ref mut lhs_evals) => { - *lhs = DenseMultilinearExtension::::from_evaluations_ext_vec( - lhs.num_vars, - lhs_evals - .iter() - .enumerate() - .map(|(index, lhs)| { - E::from(*lhs) + *coeff * poly_index_ext(rhs, index) - }) - .collect(), - ); + parallelize(lhs, |(lhs, start)| { + for (index, lhs) in lhs.iter_mut().enumerate() { + *lhs += *coeff * field_type_index_ext(rhs.evaluations(), start + index); } - _ => unreachable!(), - } + }); } } } From 23b10dfdf61ef6f56202cc4e934b163b06007836 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 15:01:57 +0800 Subject: [PATCH 12/18] Add a missing utility function. --- mpcs/src/basefold.rs | 2 +- mpcs/src/util.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mpcs/src/basefold.rs b/mpcs/src/basefold.rs index 7ad751c75..7659bf07b 100644 --- a/mpcs/src/basefold.rs +++ b/mpcs/src/basefold.rs @@ -11,7 +11,7 @@ use crate::{ inner_product, inner_product_three, interpolate_field_type_over_boolean_hypercube, }, expression::{Expression, Query, Rotation}, - ext_to_usize, + ext_to_usize, field_type_to_ext_vec, hash::{Digest, write_digest_to_transcript}, log2_strict, merkle_tree::MerkleTree, diff --git a/mpcs/src/util.rs b/mpcs/src/util.rs index 6aff42fd7..ab21ec242 100644 --- a/mpcs/src/util.rs +++ b/mpcs/src/util.rs @@ -199,6 +199,14 @@ pub fn field_type_iter_range_base<'a, E: ExtensionField>( } } +pub fn field_type_to_ext_vec(evaluations: &FieldType) -> Vec { + match evaluations { + FieldType::Ext(coeffs) => coeffs.to_vec(), + FieldType::Base(coeffs) => coeffs.iter().map(|x| (*x).into()).collect(), + _ => unreachable!(), + } +} + pub fn multiply_poly(poly: &mut [E], scalar: &E) { for coeff in poly.iter_mut() { *coeff *= scalar; From e644740c7197a2c0724e6b1686c66ac47a8a012e Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 15:08:25 +0800 Subject: [PATCH 13/18] Remove a redundant function that should be added in another PR. --- mpcs/src/util.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/mpcs/src/util.rs b/mpcs/src/util.rs index ab21ec242..ca5cc654e 100644 --- a/mpcs/src/util.rs +++ b/mpcs/src/util.rs @@ -6,7 +6,7 @@ pub mod plonky2_util; use ff::{Field, PrimeField}; use ff_ext::ExtensionField; use goldilocks::SmallField; -use itertools::{Either, Itertools, izip}; +use itertools::{Itertools, izip}; use multilinear_extensions::{ mle::{DenseMultilinearExtension, FieldType}, virtual_poly_v2::ArcMultilinearExtension, @@ -186,19 +186,6 @@ pub fn field_type_iter_ext(evaluations: &FieldType) -> Fie } } -pub fn field_type_iter_range_base<'a, E: ExtensionField>( - values: &'a FieldType, - range: impl IntoIterator + 'a, -) -> impl Iterator + 'a { - match values { - FieldType::Ext(coeffs) => { - Either::Left(range.into_iter().flat_map(|i| coeffs[i].as_bases())) - } - FieldType::Base(coeffs) => Either::Right(range.into_iter().map(|i| &coeffs[i])), - _ => unreachable!(), - } -} - pub fn field_type_to_ext_vec(evaluations: &FieldType) -> Vec { match evaluations { FieldType::Ext(coeffs) => coeffs.to_vec(), From b5924bfbb3ebf131ae73cd7fca89d2854be01db3 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 15:11:56 +0800 Subject: [PATCH 14/18] Fix clippy. --- mpcs/src/basefold.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpcs/src/basefold.rs b/mpcs/src/basefold.rs index 7659bf07b..dfeec7f92 100644 --- a/mpcs/src/basefold.rs +++ b/mpcs/src/basefold.rs @@ -610,7 +610,7 @@ where // this accumulator merged_polys[eval.point()] = ( eq_xt_i, - field_type_to_ext_vec(&polys[eval.poly()].evaluations()), + field_type_to_ext_vec(polys[eval.poly()].evaluations()), ); } else { // If the accumulator is unempty now, first force its scalar to 1, i.e., From d42f7944451bba180c20d77f9371d66f4bb7aa50 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 15:24:44 +0800 Subject: [PATCH 15/18] Fix clippy. --- mpcs/benches/basefold.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mpcs/benches/basefold.rs b/mpcs/benches/basefold.rs index 63ed9c1ad..4fe8b4094 100644 --- a/mpcs/benches/basefold.rs +++ b/mpcs/benches/basefold.rs @@ -143,8 +143,7 @@ fn bench_batch_commit_open_verify_goldilocks> .collect_vec(); let values: Vec = evals .iter() - .map(Evaluation::value) - .map(|x| *x) + .map(Evaluation::value).copied() .collect::>(); transcript.append_field_element_exts(values.as_slice()); let transcript_for_bench = transcript.clone(); @@ -186,8 +185,7 @@ fn bench_batch_commit_open_verify_goldilocks> let values: Vec = evals .iter() - .map(Evaluation::value) - .map(|x| *x) + .map(Evaluation::value).copied() .collect::>(); transcript.append_field_element_exts(values.as_slice()); From 8d8273253e185ebc3b96fe6715c7348bc2804274 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 15:26:00 +0800 Subject: [PATCH 16/18] Cargo fmt. --- mpcs/benches/basefold.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mpcs/benches/basefold.rs b/mpcs/benches/basefold.rs index 4fe8b4094..767bc8baa 100644 --- a/mpcs/benches/basefold.rs +++ b/mpcs/benches/basefold.rs @@ -143,7 +143,8 @@ fn bench_batch_commit_open_verify_goldilocks> .collect_vec(); let values: Vec = evals .iter() - .map(Evaluation::value).copied() + .map(Evaluation::value) + .copied() .collect::>(); transcript.append_field_element_exts(values.as_slice()); let transcript_for_bench = transcript.clone(); @@ -185,7 +186,8 @@ fn bench_batch_commit_open_verify_goldilocks> let values: Vec = evals .iter() - .map(Evaluation::value).copied() + .map(Evaluation::value) + .copied() .collect::>(); transcript.append_field_element_exts(values.as_slice()); From 4883bf7296b701431000e3afb6b7772d827afc62 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Wed, 6 Nov 2024 15:29:33 +0800 Subject: [PATCH 17/18] Fix Cargo.toml. --- mpcs/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpcs/Cargo.toml b/mpcs/Cargo.toml index 0f53481d0..1100cb133 100644 --- a/mpcs/Cargo.toml +++ b/mpcs/Cargo.toml @@ -37,8 +37,8 @@ print-trace = ["ark-std/print-trace"] sanity-check = [] [[bench]] -name = "basefold" harness = false +name = "basefold" [[bench]] harness = false From 1e80c7e0f849d0cb9e91e64b980e8416d7a8d6c3 Mon Sep 17 00:00:00 2001 From: Yuncong Zhang Date: Thu, 28 Nov 2024 14:28:37 +0800 Subject: [PATCH 18/18] Update basefold.rs --- mpcs/benches/basefold.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mpcs/benches/basefold.rs b/mpcs/benches/basefold.rs index 4278d2fbc..1aa55ddb9 100644 --- a/mpcs/benches/basefold.rs +++ b/mpcs/benches/basefold.rs @@ -201,11 +201,7 @@ fn bench_batch_commit_open_verify_goldilocks> &mut transcript, ); - let values: Vec = evals - .iter() - .map(Evaluation::value) - .copied() - .collect::>(); + let values: Vec = evals.iter().map(Evaluation::value).copied().collect(); transcript.append_field_element_exts(values.as_slice()); let backup_transcript = transcript.clone();