use super::{SuccinctProof, Whir, WhirParams, protocol};
use crate::envelope::AnySuccinct;
use crate::execution::{ExecutionNoun, ExecutionStatement};
pub const SMALL_MAX_VARS: usize = 16;
pub fn params_for(_vars: usize) -> WhirParams {
WhirParams {
log_inv_rate: 6,
folding_factor: 4,
pow_bits: 24,
..WhirParams::default()
}
}
pub fn device_params(vars: usize) -> WhirParams {
let (folding_factor, pow_bits) = match vars {
0..=16 => (4, 16),
17 => (5, 16),
18 => (5, 22),
_ => (5, 24),
};
WhirParams {
log_inv_rate: 6,
folding_factor,
pow_bits,
..WhirParams::default()
}
}
pub fn prove_default(
program: &ExecutionNoun,
input: &[u64],
budget: u64,
) -> Result<(ExecutionStatement, AnySuccinct), String> {
prove_with(program, input, budget, device_params)
}
pub fn prove_with(
program: &ExecutionNoun,
input: &[u64],
budget: u64,
choose: impl Fn(usize) -> WhirParams,
) -> Result<(ExecutionStatement, AnySuccinct), String> {
let lap = crate::laps::timer("prove_default");
let (statement, relation, witness, public) =
crate::execution::statement::prepare(program, input, budget)?;
lap("relation + witness");
let pins = super::with_constant(public);
let vk = crate::execution::VerifyingKey::new(statement.program_key(), relation);
lap("verifying key");
let vars = protocol::Layout::new(&vk.relation().instance, &pins)?.vars;
let proof: SuccinctProof<Whir> = protocol::prove(
&choose(vars),
&vk.relation().instance,
&witness.z,
&pins,
&super::keyed_statement(&vk, &statement.transcript_bytes()),
)?;
Ok((statement, proof.into()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn device_parameters_meet_the_ledger_at_every_size() {
for vars in 1..=20 {
let p = device_params(vars);
let bits = super::super::admit::<Whir>(&p, vars).unwrap();
let cfg = lens::rspcs::WhirConfig::derive(&p, vars).unwrap();
let bare = cfg.security_bits_without_grinding();
assert!(bits >= 128.0, "2^{vars}: {bits}");
assert!(
bare >= 128.0 - f64::from(p.pow_bits) - 1e-9,
"2^{vars}: bare {bare}"
);
}
}
}