Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ harness = false
name = "sumcheck"
harness = false

[[bench]]
name = "whir"
harness = false

# Enable to bench zook std + ZK vs Base WHIR performance
# [[bench]]
# name = "zook_vs_whir"
Expand Down
108 changes: 108 additions & 0 deletions benches/whir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use ark_std::rand::distributions::{Distribution, Standard};
use divan::{black_box, AllocProfiler, Bencher};
use spongefish::Codec;
use whir::{
algebra::{
embedding::{Basefield, Embedding},
fields::Field64_3,
linear_form::{Evaluate, LinearForm, MultilinearExtension},
},
buffer::{Buffer, BufferOps},
cmdline_utils::AvailableHash::Blake3,
parameters::ProtocolParameters,
protocols::{params::DecodingRegime, whir::Config},
transcript::{codecs::Empty, DomainSeparator, ProverState},
};

#[global_allocator]
static ALLOC: AllocProfiler = AllocProfiler::system();

const SIZES: &[u64] = &[1 << 16, 1 << 18, 1 << 20, 1 << 21];
const PROTOCOL_PARAMS: ProtocolParameters = ProtocolParameters {
security_level: 128,
pow_bits: 20,
initial_folding_factor: 4,
folding_factor: 4,
decoding_regime: DecodingRegime::Johnson,
starting_log_inv_rate: 1,
batch_size: 1,
hash_id: Blake3.hash_id(),
};

type WhirEmbedding = Basefield<Field64_3>;
type Target = <WhirEmbedding as Embedding>::Target;

/// run whir as low degree test, no constraints(linear forms) or evaluations
#[divan::bench(args = SIZES)]
fn whir_ldt(bencher: Bencher, size: u64) {
bencher
.with_inputs(|| {
let vector = (0..size)
.map(<WhirEmbedding as Embedding>::Source::from)
.collect::<Vec<_>>();
Buffer::from(vector)
})
.bench_values(|input| {
run_whir::<WhirEmbedding>(&input, vec![], Buffer::from(Vec::new()));
});
}

/// run whir as polynomial commitment scheme
#[divan::bench(args = SIZES)]
fn whir_pcs(bencher: Bencher, size: u64) {
bencher
.with_inputs(|| {
let num_variables = size.trailing_zeros() as usize;
let vector = (0..size)
.map(<WhirEmbedding as Embedding>::Source::from)
.collect::<Vec<_>>();
let points: Vec<_> = (0..2u64)
.map(|i| vec![Target::from(i); num_variables])
.collect();
let mut evaluations = Vec::new();
for point in &points {
let linear_form = MultilinearExtension::new(point.clone());
evaluations.push(linear_form.evaluate(&WhirEmbedding::default(), &vector));
}
let linear_forms: Vec<Box<dyn LinearForm<Target>>> = points
.iter()
.map(|p| {
Box::new(MultilinearExtension::new(p.clone())) as Box<dyn LinearForm<Target>>
})
.collect();

let input = Buffer::from(vector);
(input, linear_forms, evaluations)
})
.bench_values(|(input, linear_forms, evaluations)| {
run_whir::<WhirEmbedding>(&input, linear_forms, Buffer::from(evaluations));
});
}

fn run_whir<M: Embedding + Default>(
input: &Buffer<M::Source>,
linear_forms: Vec<Box<dyn LinearForm<M::Target>>>,
evaluations: Buffer<M::Target>,
) where
Standard: Distribution<M::Source> + Distribution<M::Target>,
M::Target: Codec,
{
let config = Config::<M>::new(input.len(), &PROTOCOL_PARAMS);
let ds = DomainSeparator::protocol(&config)
.session(&"Benchmark".to_string())
.instance(&Empty);
let mut prover_state = ProverState::new_std(&ds);
let witness = config.commit(&mut prover_state, &[input]);
let result = config.prove(
&mut prover_state,
&[input],
vec![&witness],
linear_forms,
evaluations,
);
let _ = black_box(result);
}

fn main() {
divan::main();
}
Loading