From d99cabded9b8f05e46f81665b8f9dc0d844d8f7d Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 15:56:59 +0100 Subject: [PATCH 01/11] Working --- starky/src/fibonacci_stark.rs | 18 ++++++++++++++++++ starky/src/lib.rs | 2 ++ starky/src/stark.rs | 3 +++ system_zero/src/system_zero.rs | 4 ++++ 4 files changed, 27 insertions(+) diff --git a/starky/src/fibonacci_stark.rs b/starky/src/fibonacci_stark.rs index f3ffd8a2..ad9685bb 100644 --- a/starky/src/fibonacci_stark.rs +++ b/starky/src/fibonacci_stark.rs @@ -81,6 +81,10 @@ impl, const D: usize> Stark for FibonacciStar ) { todo!() } + + fn degree(&self) -> usize { + 2 + } } #[cfg(test)] @@ -93,6 +97,7 @@ mod tests { use crate::config::StarkConfig; use crate::fibonacci_stark::FibonacciStark; use crate::prover::prove; + use crate::stark_testing::test_low_degree; use crate::verifier::verify; fn fibonacci(n: usize, x0: usize, x1: usize) -> usize { @@ -125,4 +130,17 @@ mod tests { verify(stark, proof, &config) } + + #[test] + fn test_fibonacci_stark_degree() -> Result<()> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + type S = FibonacciStark; + + let config = StarkConfig::standard_fast_config(); + let num_rows = 1 << 5; + let stark = S::new(num_rows); + test_low_degree(stark) + } } diff --git a/starky/src/lib.rs b/starky/src/lib.rs index e56c0ef6..dd3a6ec3 100644 --- a/starky/src/lib.rs +++ b/starky/src/lib.rs @@ -17,3 +17,5 @@ pub mod verifier; #[cfg(test)] pub mod fibonacci_stark; +#[cfg(test)] +pub mod stark_testing; diff --git a/starky/src/stark.rs b/starky/src/stark.rs index 00441240..9721c203 100644 --- a/starky/src/stark.rs +++ b/starky/src/stark.rs @@ -62,6 +62,9 @@ pub trait Stark, const D: usize>: Sync { yield_constr: &mut RecursiveConstraintConsumer, ); + /// The maximum constraint degree. + fn degree(&self) -> usize; + /// Computes the FRI instance used to prove this Stark. // TODO: Permutation polynomials. fn fri_instance( diff --git a/system_zero/src/system_zero.rs b/system_zero/src/system_zero.rs index 31b8434f..e5990af9 100644 --- a/system_zero/src/system_zero.rs +++ b/system_zero/src/system_zero.rs @@ -80,6 +80,10 @@ impl, const D: usize> Stark for SystemZero usize { + 3 + } } #[cfg(test)] From 1011c302accfe188ba4f73205480f4bab00b5413 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 16:02:45 +0100 Subject: [PATCH 02/11] Add test for system zero --- starky/src/fibonacci_stark.rs | 4 ++-- starky/src/lib.rs | 3 +-- system_zero/src/system_zero.rs | 13 +++++++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/starky/src/fibonacci_stark.rs b/starky/src/fibonacci_stark.rs index ad9685bb..a7cb0a87 100644 --- a/starky/src/fibonacci_stark.rs +++ b/starky/src/fibonacci_stark.rs @@ -97,7 +97,7 @@ mod tests { use crate::config::StarkConfig; use crate::fibonacci_stark::FibonacciStark; use crate::prover::prove; - use crate::stark_testing::test_low_degree; + use crate::stark_testing::test_stark_low_degree; use crate::verifier::verify; fn fibonacci(n: usize, x0: usize, x1: usize) -> usize { @@ -141,6 +141,6 @@ mod tests { let config = StarkConfig::standard_fast_config(); let num_rows = 1 << 5; let stark = S::new(num_rows); - test_low_degree(stark) + test_stark_low_degree(stark) } } diff --git a/starky/src/lib.rs b/starky/src/lib.rs index dd3a6ec3..dc61e7e7 100644 --- a/starky/src/lib.rs +++ b/starky/src/lib.rs @@ -12,10 +12,9 @@ mod get_challenges; pub mod proof; pub mod prover; pub mod stark; +pub mod stark_testing; pub mod vars; pub mod verifier; #[cfg(test)] pub mod fibonacci_stark; -#[cfg(test)] -pub mod stark_testing; diff --git a/system_zero/src/system_zero.rs b/system_zero/src/system_zero.rs index e5990af9..6b8576c9 100644 --- a/system_zero/src/system_zero.rs +++ b/system_zero/src/system_zero.rs @@ -97,6 +97,7 @@ mod tests { use starky::config::StarkConfig; use starky::prover::prove; use starky::stark::Stark; + use starky::stark_testing::test_stark_low_degree; use starky::verifier::verify; use crate::system_zero::SystemZero; @@ -118,4 +119,16 @@ mod tests { verify(system, proof, &config) } + + #[test] + #[ignore] // TODO + fn degree() -> Result<()> { + type F = GoldilocksField; + type C = PoseidonGoldilocksConfig; + const D: usize = 2; + + type S = SystemZero; + let system = S::default(); + test_stark_low_degree(system) + } } From 6b2b8b6e5d6d33eec07981307ff89d3a4951ed80 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 16:36:22 +0100 Subject: [PATCH 03/11] 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); From 978e14030cc6d67801e32a817f28d2d4391444fa Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 16:39:34 +0100 Subject: [PATCH 04/11] Fix degree --- starky/src/fibonacci_stark.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/starky/src/fibonacci_stark.rs b/starky/src/fibonacci_stark.rs index 2a4c8229..ce50dfd5 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 { - 3 + 2 } } From f5ddf32490e1f3aaff836699d11d6a8b3a83143b Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 16:42:22 +0100 Subject: [PATCH 05/11] Add file --- starky/src/stark_testing.rs | 100 ++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 starky/src/stark_testing.rs diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs new file mode 100644 index 00000000..6851ec75 --- /dev/null +++ b/starky/src/stark_testing.rs @@ -0,0 +1,100 @@ +use anyhow::{ensure, Result}; +use plonky2::field::extension_field::Extendable; +use plonky2::field::field_types::Field; +use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; +use plonky2::field::zero_poly_coset::ZeroPolyOnCoset; +use plonky2::hash::hash_types::RichField; +use plonky2::util::transpose; +use plonky2_util::{log2_ceil, log2_strict}; + +use crate::constraint_consumer::ConstraintConsumer; +use crate::stark::Stark; +use crate::vars::StarkEvaluationVars; + +const WITNESS_SIZE: usize = 1 << 5; + +/// Tests that the constraints imposed by the given STARK are low-degree by applying them to random +/// low-degree witness polynomials. +pub fn test_stark_low_degree, S: Stark, const D: usize>( + stark: S, +) -> Result<()> +where + [(); S::COLUMNS]:, + [(); S::PUBLIC_INPUTS]:, +{ + let rate_bits = log2_ceil(stark.degree() + 1); + + let wire_ldes = random_low_degree_matrix::(S::COLUMNS, rate_bits); + let public_inputs = F::rand_arr::<{ S::PUBLIC_INPUTS }>(); + + let lagrange_first = { + let mut evals = PolynomialValues::new(vec![F::ZERO; WITNESS_SIZE]); + evals.values[0] = F::ONE; + evals.lde(rate_bits) + }; + let lagrange_last = { + let mut evals = PolynomialValues::new(vec![F::ZERO; WITNESS_SIZE]); + evals.values[WITNESS_SIZE - 1] = F::ONE; + evals.lde(rate_bits) + }; + + let z_h_on_coset = ZeroPolyOnCoset::::new(log2_strict(WITNESS_SIZE), rate_bits); + + let last = F::primitive_root_of_unity(log2_strict(WITNESS_SIZE)).inverse(); + let subgroup = F::cyclic_subgroup_known_order( + F::primitive_root_of_unity(log2_strict(WITNESS_SIZE) + rate_bits), + WITNESS_SIZE << rate_bits, + ); + let n = wire_ldes.len(); + let alpha = F::rand(); + let constraint_evals = (0..wire_ldes.len()) + .map(|i| { + let vars = StarkEvaluationVars { + local_values: &wire_ldes[i].clone().try_into().unwrap(), + next_values: &wire_ldes[(i + (1 << rate_bits)) % n] + .clone() + .try_into() + .unwrap(), + public_inputs: &public_inputs, + }; + + let mut consumer = ConstraintConsumer::::new( + vec![alpha], + subgroup[i] - last, + lagrange_first.values[i], + lagrange_last.values[i], + ); + stark.eval_packed_base(vars, &mut consumer); + consumer.accumulators()[0] + }) + .collect::>(); + + let constraint_eval_degree = PolynomialValues::new(constraint_evals).degree(); + let maximum_degree = WITNESS_SIZE * stark.degree() - 1; + + ensure!( + constraint_eval_degree <= maximum_degree, + "Expected degrees at most {} * {} - 1 = {}, actual {:?}", + WITNESS_SIZE, + stark.degree(), + maximum_degree, + constraint_eval_degree + ); + + Ok(()) +} + +fn random_low_degree_matrix(num_polys: usize, rate_bits: usize) -> Vec> { + let polys = (0..num_polys) + .map(|_| random_low_degree_values(rate_bits)) + .collect::>(); + + transpose(&polys) +} + +fn random_low_degree_values(rate_bits: usize) -> Vec { + PolynomialCoeffs::new(F::rand_vec(WITNESS_SIZE)) + .lde(rate_bits) + .fft() + .values +} From 01f065b812499116f09161c80603bc959ccd25d8 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 16:46:33 +0100 Subject: [PATCH 06/11] Minor --- starky/src/stark_testing.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs index 6851ec75..b8b31cf9 100644 --- a/starky/src/stark_testing.rs +++ b/starky/src/stark_testing.rs @@ -25,6 +25,7 @@ where let rate_bits = log2_ceil(stark.degree() + 1); let wire_ldes = random_low_degree_matrix::(S::COLUMNS, rate_bits); + let size = wire_ldes.len(); let public_inputs = F::rand_arr::<{ S::PUBLIC_INPUTS }>(); let lagrange_first = { @@ -41,17 +42,14 @@ where let z_h_on_coset = ZeroPolyOnCoset::::new(log2_strict(WITNESS_SIZE), rate_bits); let last = F::primitive_root_of_unity(log2_strict(WITNESS_SIZE)).inverse(); - let subgroup = F::cyclic_subgroup_known_order( - F::primitive_root_of_unity(log2_strict(WITNESS_SIZE) + rate_bits), - WITNESS_SIZE << rate_bits, - ); - let n = wire_ldes.len(); + let subgroup = + F::cyclic_subgroup_known_order(F::primitive_root_of_unity(log2_strict(size)), size); let alpha = F::rand(); - let constraint_evals = (0..wire_ldes.len()) + let constraint_evals = (0..size) .map(|i| { let vars = StarkEvaluationVars { local_values: &wire_ldes[i].clone().try_into().unwrap(), - next_values: &wire_ldes[(i + (1 << rate_bits)) % n] + next_values: &wire_ldes[(i + (1 << rate_bits)) % size] .clone() .try_into() .unwrap(), From 431bde2c72311d5437e03bd84e613540e66ae40a Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 17:04:07 +0100 Subject: [PATCH 07/11] Fix number of quotient polys --- starky/src/fibonacci_stark.rs | 2 +- starky/src/prover.rs | 6 +++--- starky/src/stark.rs | 6 ++++-- starky/src/stark_testing.rs | 6 +++--- starky/src/verifier.rs | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/starky/src/fibonacci_stark.rs b/starky/src/fibonacci_stark.rs index ce50dfd5..c77775e8 100644 --- a/starky/src/fibonacci_stark.rs +++ b/starky/src/fibonacci_stark.rs @@ -82,7 +82,7 @@ impl, const D: usize> Stark for FibonacciStar todo!() } - fn degree(&self) -> usize { + fn constraint_degree(&self) -> usize { 2 } } diff --git a/starky/src/prover.rs b/starky/src/prover.rs index 2bea24ff..171ea92a 100644 --- a/starky/src/prover.rs +++ b/starky/src/prover.rs @@ -82,7 +82,7 @@ where .flat_map(|mut quotient_poly| { quotient_poly.trim(); quotient_poly - .pad(degree << rate_bits) + .pad(degree * (stark.constraint_degree() - 1)) .expect("Quotient has failed, the vanishing polynomial is not divisible by `Z_H"); // Split quotient into degree-n chunks. quotient_poly.chunks(degree) @@ -123,7 +123,7 @@ where timing, "compute openings proof", PolynomialBatch::prove_openings( - &S::fri_instance(zeta, g, rate_bits, config.num_challenges), + &stark.fri_instance(zeta, g, rate_bits, config.num_challenges), initial_merkle_trees, &mut challenger, &fri_params, @@ -162,7 +162,7 @@ where { let degree = 1 << degree_bits; - let max_degree_bits = log2_ceil(stark.degree() - 1); + let max_degree_bits = log2_ceil(stark.constraint_degree() - 1); assert!( max_degree_bits <= rate_bits, "Having constraints of degree higher than the rate is not supported yet." diff --git a/starky/src/stark.rs b/starky/src/stark.rs index 9721c203..8f112939 100644 --- a/starky/src/stark.rs +++ b/starky/src/stark.rs @@ -63,11 +63,12 @@ pub trait Stark, const D: usize>: Sync { ); /// The maximum constraint degree. - fn degree(&self) -> usize; + fn constraint_degree(&self) -> usize; /// Computes the FRI instance used to prove this Stark. // TODO: Permutation polynomials. fn fri_instance( + &self, zeta: F::Extension, g: F::Extension, rate_bits: usize, @@ -75,7 +76,8 @@ pub trait Stark, const D: usize>: Sync { ) -> FriInstanceInfo { let no_blinding_oracle = FriOracleInfo { blinding: false }; let trace_info = FriPolynomialInfo::from_range(0, 0..Self::COLUMNS); - let quotient_info = FriPolynomialInfo::from_range(1, 0..(1 << rate_bits) * num_challenges); + let quotient_info = + FriPolynomialInfo::from_range(1, 0..(self.constraint_degree() - 1) * num_challenges); let zeta_batch = FriBatchInfo { point: zeta, polynomials: [trace_info.clone(), quotient_info].concat(), diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs index b8b31cf9..b28a206e 100644 --- a/starky/src/stark_testing.rs +++ b/starky/src/stark_testing.rs @@ -22,7 +22,7 @@ where [(); S::COLUMNS]:, [(); S::PUBLIC_INPUTS]:, { - let rate_bits = log2_ceil(stark.degree() + 1); + let rate_bits = log2_ceil(stark.constraint_degree() + 1); let wire_ldes = random_low_degree_matrix::(S::COLUMNS, rate_bits); let size = wire_ldes.len(); @@ -68,13 +68,13 @@ where .collect::>(); let constraint_eval_degree = PolynomialValues::new(constraint_evals).degree(); - let maximum_degree = WITNESS_SIZE * stark.degree() - 1; + let maximum_degree = WITNESS_SIZE * stark.constraint_degree() - 1; ensure!( constraint_eval_degree <= maximum_degree, "Expected degrees at most {} * {} - 1 = {}, actual {:?}", WITNESS_SIZE, - stark.degree(), + stark.constraint_degree(), maximum_degree, constraint_eval_degree ); diff --git a/starky/src/verifier.rs b/starky/src/verifier.rs index b91fe457..b04ec684 100644 --- a/starky/src/verifier.rs +++ b/starky/src/verifier.rs @@ -98,7 +98,7 @@ where // So to reconstruct `t(zeta)` we can compute `reduce_with_powers(chunk, zeta^n)` for each // `quotient_degree_factor`-sized chunk of the original evaluations. for (i, chunk) in quotient_polys_zeta - .chunks(1 << config.fri_config.rate_bits) + .chunks(stark.constraint_degree() - 1) .enumerate() { ensure!(vanishing_polys_zeta[i] == z_h_zeta * reduce_with_powers(chunk, zeta_pow_deg)); @@ -108,7 +108,7 @@ where let merkle_caps = &[proof.trace_cap, proof.quotient_polys_cap]; verify_fri_proof::( - &S::fri_instance( + &stark.fri_instance( challenges.stark_zeta, F::primitive_root_of_unity(degree_bits).into(), config.fri_config.rate_bits, From 1c30a5a84e5187834ebc354b40f430ab39d27d00 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 17:16:18 +0100 Subject: [PATCH 08/11] Typo --- system_zero/src/system_zero.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system_zero/src/system_zero.rs b/system_zero/src/system_zero.rs index 6b8576c9..9d78939c 100644 --- a/system_zero/src/system_zero.rs +++ b/system_zero/src/system_zero.rs @@ -81,7 +81,7 @@ impl, const D: usize> Stark for SystemZero usize { + fn constraint_degree(&self) -> usize { 3 } } From 9c6b2394f162a83577d35a56fb34cf1b29fec6bd Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 20:20:12 +0100 Subject: [PATCH 09/11] PR feedback --- starky/src/stark_testing.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs index b28a206e..8d41e645 100644 --- a/starky/src/stark_testing.rs +++ b/starky/src/stark_testing.rs @@ -2,7 +2,6 @@ use anyhow::{ensure, Result}; use plonky2::field::extension_field::Extendable; use plonky2::field::field_types::Field; use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2::field::zero_poly_coset::ZeroPolyOnCoset; use plonky2::hash::hash_types::RichField; use plonky2::util::transpose; use plonky2_util::{log2_ceil, log2_strict}; @@ -24,8 +23,8 @@ where { let rate_bits = log2_ceil(stark.constraint_degree() + 1); - let wire_ldes = random_low_degree_matrix::(S::COLUMNS, rate_bits); - let size = wire_ldes.len(); + let trace_ldes = random_low_degree_matrix::(S::COLUMNS, rate_bits); + let size = trace_ldes.len(); let public_inputs = F::rand_arr::<{ S::PUBLIC_INPUTS }>(); let lagrange_first = { @@ -39,8 +38,6 @@ where evals.lde(rate_bits) }; - let z_h_on_coset = ZeroPolyOnCoset::::new(log2_strict(WITNESS_SIZE), rate_bits); - let last = F::primitive_root_of_unity(log2_strict(WITNESS_SIZE)).inverse(); let subgroup = F::cyclic_subgroup_known_order(F::primitive_root_of_unity(log2_strict(size)), size); @@ -48,8 +45,8 @@ where let constraint_evals = (0..size) .map(|i| { let vars = StarkEvaluationVars { - local_values: &wire_ldes[i].clone().try_into().unwrap(), - next_values: &wire_ldes[(i + (1 << rate_bits)) % size] + local_values: &trace_ldes[i].clone().try_into().unwrap(), + next_values: &trace_ldes[(i + (1 << rate_bits)) % size] .clone() .try_into() .unwrap(), From fc502add01dc90e8fd6ce83fba23e111fa8b374b Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 20:24:58 +0100 Subject: [PATCH 10/11] Add `quotient_degree_factor` function --- starky/src/prover.rs | 4 ++-- starky/src/stark.rs | 7 ++++++- starky/src/verifier.rs | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/starky/src/prover.rs b/starky/src/prover.rs index 171ea92a..335d5384 100644 --- a/starky/src/prover.rs +++ b/starky/src/prover.rs @@ -82,7 +82,7 @@ where .flat_map(|mut quotient_poly| { quotient_poly.trim(); quotient_poly - .pad(degree * (stark.constraint_degree() - 1)) + .pad(degree * stark.quotient_degree_factor()) .expect("Quotient has failed, the vanishing polynomial is not divisible by `Z_H"); // Split quotient into degree-n chunks. quotient_poly.chunks(degree) @@ -162,7 +162,7 @@ where { let degree = 1 << degree_bits; - let max_degree_bits = log2_ceil(stark.constraint_degree() - 1); + let max_degree_bits = log2_ceil(stark.quotient_degree_factor()); assert!( max_degree_bits <= rate_bits, "Having constraints of degree higher than the rate is not supported yet." diff --git a/starky/src/stark.rs b/starky/src/stark.rs index 8f112939..4b20553e 100644 --- a/starky/src/stark.rs +++ b/starky/src/stark.rs @@ -65,6 +65,11 @@ pub trait Stark, const D: usize>: Sync { /// The maximum constraint degree. fn constraint_degree(&self) -> usize; + /// The maximum constraint degree. + fn quotient_degree_factor(&self) -> usize { + 1.max(self.constraint_degree() - 1) + } + /// Computes the FRI instance used to prove this Stark. // TODO: Permutation polynomials. fn fri_instance( @@ -77,7 +82,7 @@ pub trait Stark, const D: usize>: Sync { let no_blinding_oracle = FriOracleInfo { blinding: false }; let trace_info = FriPolynomialInfo::from_range(0, 0..Self::COLUMNS); let quotient_info = - FriPolynomialInfo::from_range(1, 0..(self.constraint_degree() - 1) * num_challenges); + FriPolynomialInfo::from_range(1, 0..self.quotient_degree_factor() * num_challenges); let zeta_batch = FriBatchInfo { point: zeta, polynomials: [trace_info.clone(), quotient_info].concat(), diff --git a/starky/src/verifier.rs b/starky/src/verifier.rs index b04ec684..bb0634f5 100644 --- a/starky/src/verifier.rs +++ b/starky/src/verifier.rs @@ -98,7 +98,7 @@ where // So to reconstruct `t(zeta)` we can compute `reduce_with_powers(chunk, zeta^n)` for each // `quotient_degree_factor`-sized chunk of the original evaluations. for (i, chunk) in quotient_polys_zeta - .chunks(stark.constraint_degree() - 1) + .chunks(stark.quotient_degree_factor()) .enumerate() { ensure!(vanishing_polys_zeta[i] == z_h_zeta * reduce_with_powers(chunk, zeta_pow_deg)); From 511cb863fc7f43da53a0eafa1629735ae02551e6 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 4 Feb 2022 20:42:49 +0100 Subject: [PATCH 11/11] s/max_degree_bits/quotient_degree_bits --- plonky2/src/plonk/prover.rs | 12 ++++++------ starky/src/prover.rs | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 79968b0e..5e23211d 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -333,28 +333,28 @@ fn compute_quotient_polys< alphas: &[F], ) -> Vec> { let num_challenges = common_data.config.num_challenges; - let max_degree_bits = log2_ceil(common_data.quotient_degree_factor); + let quotient_degree_bits = log2_ceil(common_data.quotient_degree_factor); assert!( - max_degree_bits <= common_data.config.fri_config.rate_bits, + quotient_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 `PolynomialBatch`s." ); // 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); + let step = 1 << (common_data.config.fri_config.rate_bits - quotient_degree_bits); // When opening the `Z`s polys at the "next" point in Plonk, need to look at the point `next_step` // steps away since we work on an LDE of degree `max_filtered_constraint_degree`. - let next_step = 1 << max_degree_bits; + let next_step = 1 << quotient_degree_bits; - let points = F::two_adic_subgroup(common_data.degree_bits + max_degree_bits); + let points = F::two_adic_subgroup(common_data.degree_bits + quotient_degree_bits); let lde_size = points.len(); // Retrieve the LDE values at index `i`. let get_at_index = |comm: &'a PolynomialBatch, i: usize| -> &'a [F] { comm.get_lde_values(i * step) }; - let z_h_on_coset = ZeroPolyOnCoset::new(common_data.degree_bits, max_degree_bits); + let z_h_on_coset = ZeroPolyOnCoset::new(common_data.degree_bits, quotient_degree_bits); let points_batches = points.par_chunks(BATCH_SIZE); let quotient_values: Vec> = points_batches diff --git a/starky/src/prover.rs b/starky/src/prover.rs index 335d5384..d8913b9d 100644 --- a/starky/src/prover.rs +++ b/starky/src/prover.rs @@ -162,29 +162,29 @@ where { let degree = 1 << degree_bits; - let max_degree_bits = log2_ceil(stark.quotient_degree_factor()); + let quotient_degree_bits = log2_ceil(stark.quotient_degree_factor()); assert!( - max_degree_bits <= rate_bits, + quotient_degree_bits <= rate_bits, "Having constraints of degree higher than the rate is not supported yet." ); - let step = 1 << (rate_bits - max_degree_bits); + let step = 1 << (rate_bits - quotient_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; + let next_step = 1 << quotient_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(max_degree_bits) + evals.lde_onto_coset(quotient_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(max_degree_bits) + evals.lde_onto_coset(quotient_degree_bits) }; - let z_h_on_coset = ZeroPolyOnCoset::::new(degree_bits, max_degree_bits); + let z_h_on_coset = ZeroPolyOnCoset::::new(degree_bits, quotient_degree_bits); // Retrieve the LDE values at index `i`. let get_at_index = |comm: &PolynomialBatch, i: usize| -> [F; S::COLUMNS] { @@ -192,9 +192,9 @@ where }; // Last element of the subgroup. let last = F::primitive_root_of_unity(degree_bits).inverse(); - let size = degree << max_degree_bits; + let size = degree << quotient_degree_bits; let coset = F::cyclic_subgroup_coset_known_order( - F::primitive_root_of_unity(degree_bits + max_degree_bits), + F::primitive_root_of_unity(degree_bits + quotient_degree_bits), F::coset_shift(), size, );