Skip to content

Commit da25e7c

Browse files
committed
benchmark VM overhead for a chain of poseidons
1 parent 182d63e commit da25e7c

File tree

15 files changed

+142
-12
lines changed

15 files changed

+142
-12
lines changed

Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ rand.workspace = true
9191
p3-poseidon2-air.workspace = true
9292
p3-matrix.workspace = true
9393
p3-challenger.workspace = true
94-
p3-symmetric.workspace = true
9594
whir-p3.workspace = true
9695
p3-uni-stark.workspace = true
9796
utils.workspace = true

benches/poseidon2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{hint::black_box, time::Duration};
22

3+
use air::examples::prove_poseidon2::{Poseidon2Config, prove_poseidon2};
34
use criterion::{Criterion, Throughput, criterion_group, criterion_main};
4-
use lean_multisig::examples::prove_poseidon2::{Poseidon2Config, prove_poseidon2};
55
use whir_p3::{FoldingFactor, SecurityAssumption};
66

77
fn bench_poseidon2(c: &mut Criterion) {

crates/air/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ p3-uni-stark.workspace = true
1515
p3-matrix.workspace = true
1616
p3-util.workspace = true
1717
multilinear-toolkit.workspace = true
18+
p3-symmetric.workspace = true
19+
p3-koala-bear.workspace = true
20+
rand.workspace = true
21+
whir-p3.workspace = true
22+
packed_pcs.workspace = true
23+
1824

1925
[dev-dependencies]
2026
p3-koala-bear.workspace = true

crates/air/src/examples/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[cfg(test)]
2+
mod simple_air;
3+
4+
pub mod prove_poseidon2;

src/examples/prove_poseidon2.rs renamed to crates/air/src/examples/prove_poseidon2.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use air::table::AirTable;
1+
use crate::table::AirTable;
22
use multilinear_toolkit::prelude::*;
33
use p3_air::BaseAir;
44
use p3_field::PrimeField64;
@@ -297,7 +297,6 @@ fn run_verifier_phase(
297297
start.elapsed()
298298
}
299299

300-
#[must_use]
301300
pub fn prove_poseidon2(config: &Poseidon2Config) -> Poseidon2Benchmark {
302301
if config.display_logs {
303302
init_tracing();

crates/air/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ mod uni_skip_utils;
1212
mod utils;
1313
mod verify;
1414

15-
#[cfg(test)]
16-
mod test;
15+
pub mod examples;
1716

1817
pub trait NormalAir<EF: ExtensionField<PF<EF>>>:
1918
Air<SymbolicAirBuilder<PF<EF>>>

crates/lean_prover/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ lean_compiler.workspace = true
3232
witness_generation.workspace = true
3333
vm_air.workspace = true
3434
multilinear-toolkit.workspace = true
35+
36+
[dev-dependencies]
37+
xmss.workspace = true
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use std::time::Instant;
2+
3+
use air::examples::prove_poseidon2::{Poseidon2Config, prove_poseidon2};
4+
use lean_compiler::*;
5+
use lean_prover::{
6+
prove_execution::prove_execution, verify_execution::verify_execution, whir_config_builder,
7+
};
8+
use lean_vm::{F, execute_bytecode};
9+
use p3_field::PrimeCharacteristicRing;
10+
use whir_p3::{FoldingFactor, SecurityAssumption};
11+
use xmss::iterate_hash;
12+
13+
#[test]
14+
fn benchmark_poseidon_chain() {
15+
let program_str = r#"
16+
17+
const LOG_CHAIN_LENGTH = LOG_CHAIN_LENGTH_PLACEHOLDER;
18+
const CHAIN_LENGTH = 2 ** LOG_CHAIN_LENGTH;
19+
const COMPRESSION = 1;
20+
const UNROLLED_STEPS = 2**7;
21+
22+
fn main() {
23+
24+
// current implem panics if some precompiles are not used... (TODO)
25+
poseidon_24_null_hash_ptr = 5;
26+
zero = 0;
27+
for i in 0..2**9 {
28+
poseidon24(0, 0, poseidon_24_null_hash_ptr);
29+
dot_product(0, 0, zero, 1);
30+
}
31+
32+
buff = malloc_vec(CHAIN_LENGTH + 1);
33+
poseidon16(0, 0, buff, COMPRESSION);
34+
35+
for i in 0..CHAIN_LENGTH / UNROLLED_STEPS {
36+
offset = buff + i * UNROLLED_STEPS;
37+
for j in 0..UNROLLED_STEPS unroll {
38+
poseidon16(offset + j, 0, offset + (j + 1), COMPRESSION);
39+
}
40+
}
41+
42+
buff_ptr = (buff + (CHAIN_LENGTH-1)) * 8;
43+
public_input = public_input_start;
44+
for i in 0..8 {
45+
assert buff_ptr[i] == public_input[i];
46+
}
47+
48+
return;
49+
}
50+
"#
51+
.to_string();
52+
53+
const LOG_CHAIN_LENGTH: usize = 17;
54+
const CHAIN_LENGTH: usize = 1 << LOG_CHAIN_LENGTH;
55+
56+
let program_str = program_str.replace(
57+
"LOG_CHAIN_LENGTH_PLACEHOLDER",
58+
&LOG_CHAIN_LENGTH.to_string(),
59+
);
60+
61+
let mut public_input = F::zero_vec(1 << 13);
62+
public_input[0..8].copy_from_slice(&iterate_hash(&Default::default(), CHAIN_LENGTH));
63+
64+
let private_input = vec![];
65+
66+
utils::init_tracing();
67+
let (bytecode, function_locations) = compile_program(&program_str);
68+
let no_vec_runtime_memory = execute_bytecode(
69+
&bytecode,
70+
&public_input,
71+
&private_input,
72+
&program_str,
73+
&function_locations,
74+
1 << (3 + LOG_CHAIN_LENGTH),
75+
(false, true),
76+
)
77+
.no_vec_runtime_memory;
78+
79+
let time = Instant::now();
80+
let proof_data = prove_execution(
81+
&bytecode,
82+
&program_str,
83+
&function_locations,
84+
(&public_input, &private_input),
85+
whir_config_builder(),
86+
no_vec_runtime_memory,
87+
false,
88+
)
89+
.0;
90+
let vm_time = time.elapsed();
91+
verify_execution(&bytecode, &public_input, proof_data, whir_config_builder()).unwrap();
92+
93+
let raw_proof = prove_poseidon2(&Poseidon2Config {
94+
log_n_poseidons_16: LOG_CHAIN_LENGTH,
95+
log_n_poseidons_24: 10, // (almost invisible cost)
96+
univariate_skips: 4,
97+
folding_factor: FoldingFactor::new(7, 4),
98+
log_inv_rate: 1,
99+
soundness_type: SecurityAssumption::CapacityBound,
100+
pow_bits: 16,
101+
security_level: 128,
102+
rs_domain_initial_reduction_factor: 5,
103+
max_num_variables_to_send_coeffs: 7,
104+
display_logs: true,
105+
});
106+
107+
println!("VM proof time: {:?}", vm_time);
108+
println!("Raw Poseidon proof time: {:?}", raw_proof.prover_time);
109+
110+
println!(
111+
"VM overhead: {:.2}x",
112+
vm_time.as_secs_f64() / raw_proof.prover_time.as_secs_f64()
113+
);
114+
}

0 commit comments

Comments
 (0)