From 6b2b8b6e5d6d33eec07981307ff89d3a4951ed80 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 16:36:22 +0100 Subject: [PATCH] Use stark degree in compute_quotient --- plonky2/src/plonk/prover.rs | 4 ++-- starky/src/fibonacci_stark.rs | 12 ++++-------- starky/src/prover.rs | 33 +++++++++++++++++++-------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 6178bba1..79968b0e 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -337,10 +337,10 @@ fn compute_quotient_polys< assert!( max_degree_bits <= common_data.config.fri_config.rate_bits, "Having constraints of degree higher than the rate is not supported yet. \ - If we need this in the future, we can precompute the larger LDE before computing the `ListPolynomialCommitment`s." + If we need this in the future, we can precompute the larger LDE before computing the `PolynomialBatch`s." ); - // We reuse the LDE computed in `ListPolynomialCommitment` and extract every `step` points to get + // We reuse the LDE computed in `PolynomialBatch` and extract every `step` points to get // an LDE matching `max_filtered_constraint_degree`. let step = 1 << (common_data.config.fri_config.rate_bits - max_degree_bits); // When opening the `Z`s polys at the "next" point in Plonk, need to look at the point `next_step` diff --git a/starky/src/fibonacci_stark.rs b/starky/src/fibonacci_stark.rs index a7cb0a87..2a4c8229 100644 --- a/starky/src/fibonacci_stark.rs +++ b/starky/src/fibonacci_stark.rs @@ -83,7 +83,7 @@ impl, const D: usize> Stark for FibonacciStar } fn degree(&self) -> usize { - 2 + 3 } } @@ -100,8 +100,8 @@ mod tests { use crate::stark_testing::test_stark_low_degree; use crate::verifier::verify; - fn fibonacci(n: usize, x0: usize, x1: usize) -> usize { - (0..n).fold((0, 1), |x, _| (x.1, x.0 + x.1)).1 + fn fibonacci(n: usize, x0: F, x1: F) -> F { + (0..n).fold((x0, x1), |x, _| (x.1, x.0 + x.1)).1 } #[test] @@ -113,11 +113,7 @@ mod tests { let config = StarkConfig::standard_fast_config(); let num_rows = 1 << 5; - let public_inputs = [ - F::ZERO, - F::ONE, - F::from_canonical_usize(fibonacci(num_rows - 1, 0, 1)), - ]; + let public_inputs = [F::ZERO, F::ONE, fibonacci(num_rows - 1, F::ZERO, F::ONE)]; let stark = S::new(num_rows); let trace = stark.generate_trace(public_inputs[0], public_inputs[1]); let proof = prove::( diff --git a/starky/src/prover.rs b/starky/src/prover.rs index 080ab317..2bea24ff 100644 --- a/starky/src/prover.rs +++ b/starky/src/prover.rs @@ -11,7 +11,7 @@ use plonky2::plonk::config::GenericConfig; use plonky2::timed; use plonky2::util::timing::TimingTree; use plonky2::util::transpose; -use plonky2_util::log2_strict; +use plonky2_util::{log2_ceil, log2_strict}; use rayon::prelude::*; use crate::config::StarkConfig; @@ -145,8 +145,6 @@ where /// Computes the quotient polynomials `(sum alpha^i C_i(x)) / Z_H(x)` for `alpha` in `alphas`, /// where the `C_i`s are the Stark constraints. -// TODO: This won't work for the Fibonacci example because the constraints wrap around the subgroup. -// The denominator should be the vanishing polynomial of `H` without its last element. fn compute_quotient_polys( stark: &S, trace_commitment: &PolynomialBatch, @@ -164,34 +162,44 @@ where { let degree = 1 << degree_bits; + let max_degree_bits = log2_ceil(stark.degree() - 1); + assert!( + max_degree_bits <= rate_bits, + "Having constraints of degree higher than the rate is not supported yet." + ); + let step = 1 << (rate_bits - max_degree_bits); + // When opening the `Z`s polys at the "next" point, need to look at the point `next_step` steps away. + let next_step = 1 << max_degree_bits; + // Evaluation of the first Lagrange polynomial on the LDE domain. let lagrange_first = { let mut evals = PolynomialValues::new(vec![F::ZERO; degree]); evals.values[0] = F::ONE; - evals.lde_onto_coset(rate_bits) + evals.lde_onto_coset(max_degree_bits) }; // Evaluation of the last Lagrange polynomial on the LDE domain. let lagrange_last = { let mut evals = PolynomialValues::new(vec![F::ZERO; degree]); evals.values[degree - 1] = F::ONE; - evals.lde_onto_coset(rate_bits) + evals.lde_onto_coset(max_degree_bits) }; - let z_h_on_coset = ZeroPolyOnCoset::::new(degree_bits, rate_bits); + let z_h_on_coset = ZeroPolyOnCoset::::new(degree_bits, max_degree_bits); // Retrieve the LDE values at index `i`. let get_at_index = |comm: &PolynomialBatch, i: usize| -> [F; S::COLUMNS] { - comm.get_lde_values(i).try_into().unwrap() + comm.get_lde_values(i * step).try_into().unwrap() }; // Last element of the subgroup. let last = F::primitive_root_of_unity(degree_bits).inverse(); + let size = degree << max_degree_bits; let coset = F::cyclic_subgroup_coset_known_order( - F::primitive_root_of_unity(degree_bits + rate_bits), + F::primitive_root_of_unity(degree_bits + max_degree_bits), F::coset_shift(), - degree << rate_bits, + size, ); - let quotient_values = (0..degree << rate_bits) + let quotient_values = (0..size) .into_par_iter() .map(|i| { // TODO: Set `P` to a genuine `PackedField` here. @@ -203,10 +211,7 @@ where ); let vars = StarkEvaluationVars:: { local_values: &get_at_index(trace_commitment, i), - next_values: &get_at_index( - trace_commitment, - (i + (1 << rate_bits)) % (degree << rate_bits), - ), + next_values: &get_at_index(trace_commitment, (i + next_step) % size), public_inputs: &public_inputs, }; stark.eval_packed_base(vars, &mut consumer);