diff --git a/benches/whir.rs b/benches/whir.rs index 16e39005..8567d78c 100644 --- a/benches/whir.rs +++ b/benches/whir.rs @@ -9,7 +9,6 @@ use rand::{ rngs::{SmallRng, StdRng}, }; use whir_p3::{ - dft::EvalsDft, fiat_shamir::domain_separator::DomainSeparator, parameters::{DEFAULT_MAX_POW, FoldingFactor, ProtocolParameters, errors::SecurityAssumption}, poly::{evals::EvaluationsList, multilinear::MultilinearPoint}, @@ -33,7 +32,6 @@ type MyChallenger = DuplexChallenger; #[allow(clippy::type_complexity)] fn prepare_inputs() -> ( WhirConfig, - EvalsDft, EvaluationsList, Statement, MyChallenger, @@ -121,24 +119,19 @@ fn prepare_inputs() -> ( // Instantiate the Fiat-Shamir challenger from an empty seed and Keccak. let challenger = MyChallenger::new(poseidon16); - // DFT backend setup - - // Construct a Radix-2 FFT backend that supports small batch DFTs over `F`. - let dft = EvalsDft::::new(1 << params.max_fft_size()); - // Return all preprocessed components needed to run commit/prove/verify benchmarks. - (params, dft, polynomial, statement, challenger, domainsep) + (params, polynomial, statement, challenger, domainsep) } fn benchmark_commit_and_prove(c: &mut Criterion) { - let (params, dft, polynomial, statement, challenger, domainsep) = prepare_inputs(); + let (params, polynomial, statement, challenger, domainsep) = prepare_inputs(); c.bench_function("commit", |b| { b.iter(|| { let mut prover_state = domainsep.to_prover_state(challenger.clone()); let committer = CommitmentWriter::new(¶ms); let _witness = committer - .commit(&dft, &mut prover_state, polynomial.clone()) + .commit(&mut prover_state, polynomial.clone()) .unwrap(); }); }); @@ -148,12 +141,12 @@ fn benchmark_commit_and_prove(c: &mut Criterion) { let mut prover_state = domainsep.to_prover_state(challenger.clone()); let committer = CommitmentWriter::new(¶ms); let witness = committer - .commit(&dft, &mut prover_state, polynomial.clone()) + .commit(&mut prover_state, polynomial.clone()) .unwrap(); let prover = Prover(¶ms); prover - .prove(&dft, &mut prover_state, statement.clone(), witness) + .prove(&mut prover_state, statement.clone(), witness) .unwrap(); }); }); diff --git a/src/bin/main.rs b/src/bin/main.rs index eec78e22..4fd7d162 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -14,7 +14,6 @@ use rand::{ use tracing_forest::{ForestLayer, util::LevelFilter}; use tracing_subscriber::{EnvFilter, Registry, layer::SubscriberExt, util::SubscriberInitExt}; use whir_p3::{ - dft::EvalsDft, fiat_shamir::domain_separator::DomainSeparator, parameters::{DEFAULT_MAX_POW, FoldingFactor, ProtocolParameters, errors::SecurityAssumption}, poly::{evals::EvaluationsList, multilinear::MultilinearPoint}, @@ -164,12 +163,8 @@ fn main() { // Commit to the polynomial and produce a witness let committer = CommitmentWriter::new(¶ms); - let dft = EvalsDft::::new(1 << params.max_fft_size()); - let time = Instant::now(); - let witness = committer - .commit(&dft, &mut prover_state, polynomial) - .unwrap(); + let witness = committer.commit(&mut prover_state, polynomial).unwrap(); let commit_time = time.elapsed(); // Generate a proof using the prover @@ -178,7 +173,7 @@ fn main() { // Generate a proof for the given statement and witness let time = Instant::now(); prover - .prove(&dft, &mut prover_state, statement.clone(), witness) + .prove(&mut prover_state, statement.clone(), witness) .unwrap(); let opening_time = time.elapsed(); diff --git a/src/whir/committer/reader.rs b/src/whir/committer/reader.rs index a2977588..c0b4c3ad 100644 --- a/src/whir/committer/reader.rs +++ b/src/whir/committer/reader.rs @@ -180,7 +180,6 @@ mod tests { use super::*; use crate::{ - dft::EvalsDft, parameters::{FoldingFactor, ProtocolParameters, errors::SecurityAssumption}, poly::{evals::EvaluationsList, multilinear::MultilinearPoint}, whir::{DomainSeparator, committer::writer::CommitmentWriter}, @@ -248,9 +247,6 @@ mod tests { // Instantiate the committer using the test config. let committer = CommitmentWriter::new(¶ms); - // Use a DFT engine to expand/fold the polynomial for evaluation. - let dft = EvalsDft::default(); - // Set up Fiat-Shamir transcript and commit the protocol parameters. let mut ds = DomainSeparator::new(vec![]); ds.commit_statement::<_, _, _, 8>(¶ms); @@ -262,9 +258,7 @@ mod tests { let mut prover_state = ds.to_prover_state(challenger.clone()); // Commit the polynomial and obtain a witness (root, Merkle proof, OOD evaluations). - let witness = committer - .commit(&dft, &mut prover_state, polynomial) - .unwrap(); + let witness = committer.commit(&mut prover_state, polynomial).unwrap(); // Simulate verifier state using transcript view of prover’s nonce string. let mut verifier_state = @@ -290,9 +284,8 @@ mod tests { // Generate a polynomial with 16 random coefficients. let polynomial = EvaluationsList::new((0..16).map(|_| rng.random()).collect()); - // Set up the committer and DFT engine. + // Set up the committer let committer = CommitmentWriter::new(¶ms); - let dft = EvalsDft::default(); // Begin the transcript and commit to the statement parameters. let mut ds = DomainSeparator::new(vec![]); @@ -304,9 +297,7 @@ mod tests { let mut prover_state = ds.to_prover_state(challenger.clone()); // Commit the polynomial to obtain the witness. - let witness = committer - .commit(&dft, &mut prover_state, polynomial) - .unwrap(); + let witness = committer.commit(&mut prover_state, polynomial).unwrap(); // Initialize the verifier view of the transcript. let mut verifier_state = @@ -335,9 +326,8 @@ mod tests { // Generate a large polynomial with 1024 random coefficients. let polynomial = EvaluationsList::new((0..1024).map(|_| rng.random()).collect()); - // Initialize the committer and DFT engine. + // Initialize the committer let committer = CommitmentWriter::new(¶ms); - let dft = EvalsDft::default(); // Start a new transcript and commit to the public parameters. let mut ds = DomainSeparator::new(vec![]); @@ -350,9 +340,7 @@ mod tests { let mut prover_state = ds.to_prover_state(challenger.clone()); // Commit the polynomial and obtain the witness. - let witness = committer - .commit(&dft, &mut prover_state, polynomial) - .unwrap(); + let witness = committer.commit(&mut prover_state, polynomial).unwrap(); // Initialize verifier view from prover's transcript string. let mut verifier_state = @@ -376,9 +364,8 @@ mod tests { // Generate a multilinear polynomial with 16 coefficients. let polynomial = EvaluationsList::new((0..16).map(|_| rng.random()).collect()); - // Instantiate a committer and DFT backend. + // Instantiate a committer let committer = CommitmentWriter::new(¶ms); - let dft = EvalsDft::default(); // Set up Fiat-Shamir transcript and commit to the public parameters. let mut ds = DomainSeparator::new(vec![]); @@ -389,9 +376,7 @@ mod tests { let challenger = MyChallenger::new(Perm::new_from_rng_128(&mut rng)); let mut prover_state = ds.to_prover_state(challenger.clone()); - let _ = committer - .commit(&dft, &mut prover_state, polynomial) - .unwrap(); + let _ = committer.commit(&mut prover_state, polynomial).unwrap(); let mut verifier_state = ds.to_verifier_state(prover_state.proof_data().to_vec(), challenger); diff --git a/src/whir/committer/writer.rs b/src/whir/committer/writer.rs index 07e3777b..e89a9dbb 100644 --- a/src/whir/committer/writer.rs +++ b/src/whir/committer/writer.rs @@ -11,7 +11,6 @@ use tracing::{info_span, instrument}; use super::Witness; use crate::{ - dft::EvalsDft, fiat_shamir::{errors::FiatShamirError, prover::ProverState}, poly::evals::EvaluationsList, utils::parallel_repeat, @@ -56,7 +55,6 @@ where #[instrument(skip_all)] pub fn commit( &self, - dft: &EvalsDft, prover_state: &mut ProverState, polynomial: EvaluationsList, ) -> Result, DIGEST_ELEMS>, FiatShamirError> @@ -76,7 +74,9 @@ where let width = 1 << self.folding_factor.at_round(0); let folded_matrix = info_span!("dft", height = evals_repeated.len() / width, width) .in_scope(|| { - dft.dft_batch_by_evals(RowMajorMatrix::new(evals_repeated, width)) + self.0 + .dft + .dft_batch_by_evals(RowMajorMatrix::new(evals_repeated, width)) .to_row_major_matrix() }); @@ -192,9 +192,8 @@ mod tests { // Run the Commitment Phase let committer = CommitmentWriter::new(¶ms); - let dft_committer = EvalsDft::::default(); let witness = committer - .commit(&dft_committer, &mut prover_state, polynomial.clone()) + .commit(&mut prover_state, polynomial.clone()) .unwrap(); // Ensure OOD (out-of-domain) points are generated. @@ -268,11 +267,8 @@ mod tests { let mut prover_state = domainsep.to_prover_state(challenger); - let dft_committer = EvalsDft::::default(); let committer = CommitmentWriter::new(¶ms); - let _ = committer - .commit(&dft_committer, &mut prover_state, polynomial) - .unwrap(); + let _ = committer.commit(&mut prover_state, polynomial).unwrap(); } #[test] @@ -323,11 +319,8 @@ mod tests { let mut prover_state = domainsep.to_prover_state(challenger); - let dft_committer = EvalsDft::::default(); let committer = CommitmentWriter::new(¶ms); - let witness = committer - .commit(&dft_committer, &mut prover_state, polynomial) - .unwrap(); + let witness = committer.commit(&mut prover_state, polynomial).unwrap(); assert!( witness.ood_points.is_empty(), diff --git a/src/whir/mod.rs b/src/whir/mod.rs index d4ef1b07..38e55675 100644 --- a/src/whir/mod.rs +++ b/src/whir/mod.rs @@ -10,7 +10,6 @@ use rand::{SeedableRng, rngs::SmallRng}; use verifier::Verifier; use crate::{ - dft::EvalsDft, fiat_shamir::domain_separator::DomainSeparator, parameters::{FoldingFactor, ProtocolParameters, errors::SecurityAssumption}, poly::{coeffs::CoefficientList, multilinear::MultilinearPoint}, @@ -111,22 +110,16 @@ pub fn make_whir_things( // Create polynomial commitment using Merkle tree over evaluation domain let committer = CommitmentWriter::new(¶ms); - // DFT evaluator for polynomial - let dft_committer = EvalsDft::::default(); // Commit to polynomial evaluations and generate cryptographic witness - let witness = committer - .commit(&dft_committer, &mut prover_state, polynomial) - .unwrap(); + let witness = committer.commit(&mut prover_state, polynomial).unwrap(); // Initialize WHIR prover with the configured parameters let prover = Prover(¶ms); - // DFT evaluator for proving - let dft_prover = EvalsDft::::default(); // Generate WHIR proof prover - .prove(&dft_prover, &mut prover_state, statement.clone(), witness) + .prove(&mut prover_state, statement.clone(), witness) .unwrap(); // Sample final challenge to ensure transcript consistency between prover/verifier diff --git a/src/whir/parameters.rs b/src/whir/parameters.rs index 0108ae93..6cee1e01 100644 --- a/src/whir/parameters.rs +++ b/src/whir/parameters.rs @@ -3,7 +3,10 @@ use std::{f64::consts::LOG2_10, marker::PhantomData}; use p3_challenger::{FieldChallenger, GrindingChallenger}; use p3_field::{ExtensionField, Field, TwoAdicField}; -use crate::parameters::{FoldingFactor, ProtocolParameters, errors::SecurityAssumption}; +use crate::{ + dft::EvalsDft, + parameters::{FoldingFactor, ProtocolParameters, errors::SecurityAssumption}, +}; #[derive(Debug, Clone)] pub struct RoundConfig { @@ -49,6 +52,9 @@ where pub final_sumcheck_rounds: usize, pub final_folding_pow_bits: usize, + // Cached DFT + pub dft: EvalsDft, + // Merkle tree parameters pub merkle_hash: Hash, pub merkle_compress: C, @@ -237,6 +243,10 @@ where final_sumcheck_rounds, final_folding_pow_bits: final_folding_pow_bits as usize, final_log_inv_rate: log_inv_rate, + dft: EvalsDft::::new( + 1 << (initial_num_variables + whir_parameters.starting_log_inv_rate + - whir_parameters.folding_factor.at_round(0)), + ), merkle_hash: whir_parameters.merkle_hash, merkle_compress: whir_parameters.merkle_compress, univariate_skip: whir_parameters.univariate_skip, diff --git a/src/whir/prover/mod.rs b/src/whir/prover/mod.rs index 44daeeeb..33c0e39d 100644 --- a/src/whir/prover/mod.rs +++ b/src/whir/prover/mod.rs @@ -14,7 +14,6 @@ use tracing::{info_span, instrument}; use super::{committer::Witness, constraints::statement::Statement, parameters::WhirConfig}; use crate::{ constant::K_SKIP_SUMCHECK, - dft::EvalsDft, fiat_shamir::{errors::FiatShamirError, prover::ProverState}, poly::{evals::EvaluationsList, multilinear::MultilinearPoint}, utils::parallel_repeat, @@ -137,7 +136,6 @@ where #[instrument(skip_all)] pub fn prove( &self, - dft: &EvalsDft, prover_state: &mut ProverState, statement: Statement, witness: Witness, DIGEST_ELEMS>, @@ -165,7 +163,7 @@ where // Run the WHIR protocol round-by-round for round in 0..=self.n_rounds() { - self.round(round, dft, prover_state, &mut round_state)?; + self.round(round, prover_state, &mut round_state)?; } // Reverse the vector of verifier challenges (used as evaluation point) @@ -183,7 +181,6 @@ where fn round( &self, round_index: usize, - dft: &EvalsDft, prover_state: &mut ProverState, round_state: &mut RoundState, DIGEST_ELEMS>, ) -> Result<(), FiatShamirError> @@ -224,7 +221,7 @@ where width = 1 << folding_factor_next ) .in_scope(|| { - dft.dft_algebra_batch_by_evals(RowMajorMatrix::new( + self.0.dft.dft_algebra_batch_by_evals(RowMajorMatrix::new( evals_repeated, 1 << folding_factor_next, )) diff --git a/src/whir/prover/round_state/tests.rs b/src/whir/prover/round_state/tests.rs index 0e36f6fa..e4b5b113 100644 --- a/src/whir/prover/round_state/tests.rs +++ b/src/whir/prover/round_state/tests.rs @@ -6,7 +6,6 @@ use p3_symmetric::{PaddingFreeSponge, TruncatedPermutation}; use rand::{SeedableRng, rngs::SmallRng}; use crate::{ - dft::EvalsDft, fiat_shamir::{domain_separator::DomainSeparator, prover::ProverState}, parameters::{FoldingFactor, ProtocolParameters, errors::SecurityAssumption}, poly::{coeffs::CoefficientList, evals::EvaluationsList, multilinear::MultilinearPoint}, @@ -107,9 +106,7 @@ fn setup_domain_and_commitment( // Perform DFT-based commitment to the polynomial, producing a witness // which includes the Merkle tree and polynomial values. - let witness = committer - .commit(&EvalsDft::::default(), &mut prover_state, poly) - .unwrap(); + let witness = committer.commit(&mut prover_state, poly).unwrap(); // Return all initialized components needed for round state setup. (domsep, prover_state, witness)