-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add basefold to master. * Refactor. Remove unnecessary module and codes. Refactor the code. * Fixes. * Profile speed. * Remove unnecessary features. * Move expensive tests to benchmarks. * Make sumcheck test cheap. * Remove unnecessary timers that cause failure in parallel. * Remove `print-trace` feature. * Update Cargo.toml * Use criterion for benchmark. * Split the benchmarks.
- Loading branch information
1 parent
0cc384a
commit 0cb729d
Showing
12 changed files
with
390 additions
and
239 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
use std::time::Duration; | ||
|
||
use criterion::*; | ||
use ff::Field; | ||
use goldilocks::GoldilocksExt2; | ||
|
||
use itertools::{chain, Itertools}; | ||
use mpcs::{ | ||
util::transcript::{ | ||
FieldTranscript, FieldTranscriptRead, FieldTranscriptWrite, InMemoryTranscript, | ||
PoseidonTranscript, | ||
}, | ||
Basefold, BasefoldDefaultParams, Evaluation, PolynomialCommitmentScheme, | ||
}; | ||
|
||
use multilinear_extensions::mle::DenseMultilinearExtension; | ||
use rand::{rngs::OsRng, SeedableRng}; | ||
use rand_chacha::ChaCha8Rng; | ||
|
||
type Pcs = Basefold<GoldilocksExt2, BasefoldDefaultParams>; | ||
type T = PoseidonTranscript<GoldilocksExt2>; | ||
type E = GoldilocksExt2; | ||
|
||
const NUM_SAMPLES: usize = 10; | ||
|
||
fn bench_commit_open_verify_goldilocks(c: &mut Criterion, is_base: bool) { | ||
let mut group = c.benchmark_group(format!( | ||
"commit_open_verify_goldilocks_{}", | ||
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 10..=20 { | ||
let (pp, vp) = { | ||
let rng = ChaCha8Rng::from_seed([0u8; 32]); | ||
let poly_size = 1 << num_vars; | ||
let param = Pcs::setup(poly_size, &rng).unwrap(); | ||
|
||
group.bench_function(BenchmarkId::new("setup", format!("{}", num_vars)), |b| { | ||
b.iter(|| { | ||
Pcs::setup(poly_size, &rng).unwrap(); | ||
}) | ||
}); | ||
Pcs::trim(¶m).unwrap() | ||
}; | ||
|
||
let proof = { | ||
let mut transcript = T::new(); | ||
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 = transcript.squeeze_challenges(num_vars); | ||
let eval = poly.evaluate(point.as_slice()); | ||
transcript.write_field_element_ext(&eval).unwrap(); | ||
Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); | ||
|
||
group.bench_function(BenchmarkId::new("open", format!("{}", num_vars)), |b| { | ||
b.iter_batched( | ||
|| transcript.clone(), | ||
|mut transcript| { | ||
Pcs::open(&pp, &poly, &comm, &point, &eval, &mut transcript).unwrap(); | ||
}, | ||
BatchSize::SmallInput, | ||
); | ||
}); | ||
|
||
transcript.into_proof() | ||
}; | ||
// Verify | ||
let mut transcript = T::from_proof(proof.as_slice()); | ||
Pcs::verify( | ||
&vp, | ||
&Pcs::read_commitment(&vp, &mut transcript).unwrap(), | ||
&transcript.squeeze_challenges(num_vars), | ||
&transcript.read_field_element_ext().unwrap(), | ||
&mut transcript, | ||
) | ||
.unwrap(); | ||
group.bench_function(BenchmarkId::new("verify", format!("{}", num_vars)), |b| { | ||
b.iter_batched( | ||
|| T::from_proof(proof.as_slice()), | ||
|mut transcript| { | ||
Pcs::verify( | ||
&vp, | ||
&Pcs::read_commitment(&vp, &mut transcript).unwrap(), | ||
&transcript.squeeze_challenges(num_vars), | ||
&transcript.read_field_element_ext().unwrap(), | ||
&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!( | ||
"commit_batch_open_verify_goldilocks_{}", | ||
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 10..=20 { | ||
for batch_size_log in 1..=6 { | ||
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, &rng).unwrap(); | ||
Pcs::trim(¶m).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 proof = { | ||
let mut transcript = T::new(); | ||
let polys = (0..batch_size) | ||
.map(|i| { | ||
if is_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 comms = Pcs::batch_commit_and_write(&pp, &polys, &mut transcript).unwrap(); | ||
|
||
group.bench_function( | ||
BenchmarkId::new("batch_commit", format!("{}", num_vars)), | ||
|b| { | ||
b.iter(|| { | ||
Pcs::batch_commit(&pp, &polys).unwrap(); | ||
}) | ||
}, | ||
); | ||
|
||
let points = (0..num_points) | ||
.map(|i| transcript.squeeze_challenges(num_vars - i)) | ||
.take(num_points) | ||
.collect_vec(); | ||
|
||
let evals = evals | ||
.iter() | ||
.copied() | ||
.map(|(poly, point)| { | ||
Evaluation::new(poly, point, polys[poly].evaluate(&points[point])) | ||
}) | ||
.collect_vec(); | ||
transcript | ||
.write_field_elements_ext(evals.iter().map(Evaluation::value)) | ||
.unwrap(); | ||
Pcs::batch_open(&pp, &polys, &comms, &points, &evals, &mut transcript).unwrap(); | ||
|
||
group.bench_function( | ||
BenchmarkId::new("batch_open", format!("{}", num_vars)), | ||
|b| { | ||
b.iter_batched( | ||
|| transcript.clone(), | ||
|mut transcript| { | ||
Pcs::batch_open( | ||
&pp, | ||
&polys, | ||
&comms, | ||
&points, | ||
&evals, | ||
&mut transcript, | ||
) | ||
.unwrap(); | ||
}, | ||
BatchSize::SmallInput, | ||
); | ||
}, | ||
); | ||
|
||
transcript.into_proof() | ||
}; | ||
// Batch verify | ||
let mut transcript = T::from_proof(proof.as_slice()); | ||
let comms = &Pcs::read_commitments(&vp, batch_size, &mut transcript).unwrap(); | ||
|
||
let points = (0..num_points) | ||
.map(|i| transcript.squeeze_challenges(num_vars - i)) | ||
.take(num_points) | ||
.collect_vec(); | ||
|
||
let evals2 = transcript.read_field_elements_ext(evals.len()).unwrap(); | ||
|
||
Pcs::batch_verify( | ||
&vp, | ||
comms, | ||
&points, | ||
&evals | ||
.iter() | ||
.copied() | ||
.zip(evals2.clone()) | ||
.map(|((poly, point), eval)| Evaluation::new(poly, point, eval)) | ||
.collect_vec(), | ||
&mut transcript, | ||
) | ||
.unwrap(); | ||
|
||
group.bench_function( | ||
BenchmarkId::new("batch_verify", format!("{}", num_vars)), | ||
|b| { | ||
b.iter_batched( | ||
|| transcript.clone(), | ||
|mut transcript| { | ||
Pcs::batch_verify( | ||
&vp, | ||
comms, | ||
&points, | ||
&evals | ||
.iter() | ||
.copied() | ||
.zip(evals2.clone()) | ||
.map(|((poly, point), eval)| Evaluation::new(poly, point, eval)) | ||
.collect_vec(), | ||
&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); | ||
} | ||
|
||
criterion_group! { | ||
name = bench_basefold; | ||
config = Criterion::default().warm_up_time(Duration::from_millis(3000)); | ||
targets = bench_commit_open_verify_goldilocks_base, bench_commit_open_verify_goldilocks_2, bench_batch_commit_open_verify_goldilocks_base, bench_batch_commit_open_verify_goldilocks_2 | ||
} | ||
|
||
criterion_main!(bench_basefold); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Oops, something went wrong.