From ea3e31504a636210cf1f5e736d085c8f04b49042 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Wed, 6 Oct 2021 15:50:56 +0200 Subject: [PATCH 01/10] First pass --- src/plonk/get_challenges.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index 34034260..5815774f 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -1,11 +1,13 @@ use crate::field::extension_field::Extendable; -use crate::field::field_types::RichField; +use crate::field::field_types::{Field, RichField}; +use crate::fri::verifier::compute_evaluation; use crate::hash::hashing::hash_n_to_1; use crate::iop::challenger::Challenger; use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::proof::{ CompressedProofWithPublicInputs, ProofChallenges, ProofWithPublicInputs, }; +use crate::util::reverse_bits; impl, const D: usize> ProofWithPublicInputs { pub(crate) fn fri_query_indices( @@ -83,6 +85,7 @@ impl, const D: usize> ProofWithPublicInputs { fri_betas, fri_pow_response, fri_query_indices, + fri_query_inferred_elements: None, }) } } @@ -154,6 +157,31 @@ impl, const D: usize> CompressedProofWithPublicInpu .map(|_| challenger.get_challenge().to_canonical_u64() as usize % lde_size) .collect(); + let mut fri_query_inferred_elements = Vec::new(); + let log_n = common_data.degree_bits + common_data.config.rate_bits; + for query_round in 0..common_data.config.fri_config.num_query_rounds { + let mut query_round_inferred_elements = Vec::new(); + let mut x_index = fri_query_indices[query_round]; + let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR + * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); + let evals = &self.proof.opening_proof..steps[query_round].evals; + for &arity_bits in &common_data.config.fri_config.reduction_strategy { + let arity = 1 << arity_bits; + let x_index_within_coset = x_index & (arity - 1); + let elmt = compute_evaluation( + subgroup_x, + x_index_within_coset, + arity_bits, + evals, + challenges.fri_betas[i], + ); + query_round_inferred_elements.push(elmt); + subgroup_x = subgroup_x.exp_power_of_2(arity_bits); + x_index >>= arity_bits; + } + fri_query_inferred_elements.push(query_round_inferred_elements); + } + Ok(ProofChallenges { plonk_betas, plonk_gammas, @@ -163,6 +191,7 @@ impl, const D: usize> CompressedProofWithPublicInpu fri_betas, fri_pow_response, fri_query_indices, + fri_query_inferred_elements: Some(fri_query_inferred_elements), }) } } From d2a5e679803e6d215f9c5d90cf53aac1287237cb Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 7 Oct 2021 19:30:39 +0200 Subject: [PATCH 02/10] Somewhat working --- src/fri/proof.rs | 33 ++++++++++++++++++++++------- src/fri/verifier.rs | 26 +++++++++++++++-------- src/plonk/get_challenges.rs | 17 ++++++++++----- src/plonk/proof.rs | 41 +++++++++++++++++++++++++++++-------- src/plonk/verifier.rs | 14 ++++++++++--- 5 files changed, 99 insertions(+), 32 deletions(-) diff --git a/src/fri/proof.rs b/src/fri/proof.rs index 793d0798..130cf57d 100644 --- a/src/fri/proof.rs +++ b/src/fri/proof.rs @@ -14,6 +14,7 @@ use crate::hash::path_compression::{compress_merkle_proofs, decompress_merkle_pr use crate::iop::target::Target; use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::plonk_common::PolynomialsIndexBlinding; +use crate::plonk::proof::ProofChallenges; use crate::polynomial::polynomial::PolynomialCoeffs; /// Evaluations and Merkle proof produced by the prover in a FRI query step. @@ -164,9 +165,12 @@ impl, const D: usize> FriProof { initial_trees_proofs[i].push(proof); } for (i, query_step) in steps.into_iter().enumerate() { + let index_within_coset = index & ((1 << reduction_arity_bits[i]) - 1); index >>= reduction_arity_bits[i]; steps_indices[i].push(index); - steps_evals[i].push(query_step.evals); + let mut evals = query_step.evals; + evals.remove(index_within_coset); + steps_evals[i].push(evals); steps_proofs[i].push(query_step.merkle_proof); } } @@ -228,9 +232,9 @@ impl, const D: usize> FriProof { impl, const D: usize> CompressedFriProof { /// Decompress all the Merkle paths in the FRI proof and reinsert duplicate indices. - pub fn decompress( + pub(crate) fn decompress( self, - indices: &[usize], + challenges: &ProofChallenges, common_data: &CommonCircuitData, ) -> FriProof { let CompressedFriProof { @@ -240,6 +244,16 @@ impl, const D: usize> CompressedFriProof { pow_witness, .. } = self; + let ProofChallenges { + fri_query_indices: indices, + fri_query_inferred_elements, + .. + } = challenges; + let fri_query_inferred_elements = if let Some(v) = fri_query_inferred_elements { + v + } else { + panic!() + }; let cap_height = common_data.config.cap_height; let reduction_arity_bits = &common_data.fri_params.reduction_arity_bits; let num_reductions = reduction_arity_bits.len(); @@ -267,7 +281,7 @@ impl, const D: usize> CompressedFriProof { }) .collect::>(); - for mut index in indices.iter().copied() { + for (round, mut index) in indices.iter().copied().enumerate() { let initial_trees_proof = query_round_proofs.initial_trees_proofs[&index].clone(); for (i, (leaves_data, proof)) in initial_trees_proof.evals_proofs.into_iter().enumerate() @@ -277,11 +291,16 @@ impl, const D: usize> CompressedFriProof { initial_trees_proofs[i].push(proof); } for i in 0..num_reductions { + let index_within_coset = index & ((1 << reduction_arity_bits[i]) - 1); index >>= reduction_arity_bits[i]; - let query_step = query_round_proofs.steps[i][&index].clone(); + let FriQueryStep { + mut evals, + merkle_proof, + } = query_round_proofs.steps[i][&index].clone(); steps_indices[i].push(index); - steps_evals[i].push(flatten(&query_step.evals)); - steps_proofs[i].push(query_step.merkle_proof); + evals.insert(index_within_coset, fri_query_inferred_elements[round][i]); + steps_evals[i].push(flatten(&evals)); + steps_proofs[i].push(merkle_proof); } } diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index 0aae124d..23739639 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -15,7 +15,7 @@ use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place}; /// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity /// and P' is the FRI reduced polynomial. -fn compute_evaluation, const D: usize>( +pub(crate) fn compute_evaluation, const D: usize>( x: F, x_index_within_coset: usize, arity_bits: usize, @@ -83,10 +83,11 @@ pub(crate) fn verify_fri_proof, const D: usize>( let precomputed_reduced_evals = PrecomputedReducedEvals::from_os_and_alpha(os, challenges.fri_alpha); - for (&x_index, round_proof) in challenges + for (round, (&x_index, round_proof)) in challenges .fri_query_indices .iter() .zip(&proof.query_round_proofs) + .enumerate() { fri_verifier_query_round( challenges, @@ -95,6 +96,7 @@ pub(crate) fn verify_fri_proof, const D: usize>( &proof, x_index, n, + round, round_proof, common_data, )?; @@ -218,6 +220,7 @@ fn fri_verifier_query_round, const D: usize>( proof: &FriProof, mut x_index: usize, n: usize, + round: usize, round_proof: &FriQueryRound, common_data: &CommonCircuitData, ) -> Result<()> { @@ -259,13 +262,18 @@ fn fri_verifier_query_round, const D: usize>( ensure!(evals[x_index_within_coset] == old_eval); // Infer P(y) from {P(x)}_{x^arity=y}. - old_eval = compute_evaluation( - subgroup_x, - x_index_within_coset, - arity_bits, - evals, - challenges.fri_betas[i], - ); + old_eval = if let Some(v) = &challenges.fri_query_inferred_elements { + dbg!("yo"); + v[round][i] + } else { + compute_evaluation( + subgroup_x, + x_index_within_coset, + arity_bits, + evals, + challenges.fri_betas[i], + ) + }; verify_merkle_proof( flatten(evals), diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index 5815774f..e3fa54c8 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -138,7 +138,7 @@ impl, const D: usize> CompressedProofWithPublicInpu challenger.observe_cap(cap); challenger.get_extension_challenge() }) - .collect(); + .collect::>(); challenger.observe_extension_elements(&self.proof.opening_proof.final_poly.coeffs); @@ -155,7 +155,7 @@ impl, const D: usize> CompressedProofWithPublicInpu let fri_query_indices = (0..num_fri_queries) .map(|_| challenger.get_challenge().to_canonical_u64() as usize % lde_size) - .collect(); + .collect::>(); let mut fri_query_inferred_elements = Vec::new(); let log_n = common_data.degree_bits + common_data.config.rate_bits; @@ -164,16 +164,23 @@ impl, const D: usize> CompressedProofWithPublicInpu let mut x_index = fri_query_indices[query_round]; let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); - let evals = &self.proof.opening_proof..steps[query_round].evals; - for &arity_bits in &common_data.config.fri_config.reduction_strategy { + for (i, &arity_bits) in common_data + .fri_params + .reduction_arity_bits + .iter() + .enumerate() + { let arity = 1 << arity_bits; + let evals = &self.proof.opening_proof.query_round_proofs.steps[i] + [&(x_index >> arity_bits)] + .evals; let x_index_within_coset = x_index & (arity - 1); let elmt = compute_evaluation( subgroup_x, x_index_within_coset, arity_bits, evals, - challenges.fri_betas[i], + fri_betas[i], ); query_round_inferred_elements.push(elmt); subgroup_x = subgroup_x.exp_power_of_2(arity_bits); diff --git a/src/plonk/proof.rs b/src/plonk/proof.rs index 4021f3cb..0bc8ef96 100644 --- a/src/plonk/proof.rs +++ b/src/plonk/proof.rs @@ -10,7 +10,8 @@ use crate::hash::hash_types::{HashOut, MerkleCapTarget}; use crate::hash::hashing::hash_n_to_hash; use crate::hash::merkle_tree::MerkleCap; use crate::iop::target::Target; -use crate::plonk::circuit_data::CommonCircuitData; +use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData}; +use crate::plonk::verifier::verify_with_challenges; use crate::util::serialization::Buffer; #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] @@ -118,9 +119,9 @@ pub struct CompressedProof, const D: usize> { impl, const D: usize> CompressedProof { /// Decompress the proof. - pub fn decompress( + pub(crate) fn decompress( self, - indices: &[usize], + challenges: &ProofChallenges, common_data: &CommonCircuitData, ) -> Proof { let CompressedProof { @@ -136,7 +137,7 @@ impl, const D: usize> CompressedProof { plonk_zs_partial_products_cap, quotient_polys_cap, openings, - opening_proof: opening_proof.decompress(indices, common_data), + opening_proof: opening_proof.decompress(challenges, common_data), } } } @@ -153,14 +154,33 @@ impl, const D: usize> CompressedProofWithPublicInpu self, common_data: &CommonCircuitData, ) -> anyhow::Result> { - let indices = self.fri_query_indices(common_data)?; - let compressed_proof = self.proof.decompress(&indices, common_data); + let challenges = self.get_challenges(common_data)?; + let compressed_proof = self.proof.decompress(&challenges, common_data); Ok(ProofWithPublicInputs { public_inputs: self.public_inputs, proof: compressed_proof, }) } + pub(crate) fn verify( + self, + verifier_data: &VerifierOnlyCircuitData, + common_data: &CommonCircuitData, + ) -> anyhow::Result<()> { + let challenges = self.get_challenges(common_data)?; + dbg!(&challenges.fri_query_inferred_elements); + let compressed_proof = self.proof.decompress(&challenges, common_data); + verify_with_challenges( + ProofWithPublicInputs { + public_inputs: self.public_inputs, + proof: compressed_proof, + }, + challenges, + verifier_data, + common_data, + ) + } + pub(crate) fn get_public_inputs_hash(&self) -> HashOut { hash_n_to_hash(self.public_inputs.clone(), true) } @@ -203,6 +223,8 @@ pub(crate) struct ProofChallenges, const D: usize> pub fri_pow_response: F, pub fri_query_indices: Vec, + + pub fri_query_inferred_elements: Option>>, } pub struct ProofWithPublicInputsTarget { @@ -273,6 +295,7 @@ mod tests { use crate::field::crandall_field::CrandallField; use crate::field::field_types::Field; + use crate::fri::reduction_strategies::FriReductionStrategy; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; @@ -284,6 +307,7 @@ mod tests { const D: usize = 4; let mut config = CircuitConfig::large_config(); + config.fri_config.reduction_strategy = FriReductionStrategy::Fixed(vec![1]); config.fri_config.num_query_rounds = 50; let pw = PartialWitness::new(); @@ -303,9 +327,10 @@ mod tests { // Verify that `decompress ∘ compress = identity`. let compressed_proof = proof.clone().compress(&data.common)?; - let decompressed_compressed_proof = compressed_proof.decompress(&data.common)?; + let decompressed_compressed_proof = compressed_proof.clone().decompress(&data.common)?; assert_eq!(proof, decompressed_compressed_proof); - verify(proof, &data.verifier_only, &data.common) + verify(proof, &data.verifier_only, &data.common)?; + compressed_proof.verify(&data.verifier_only, &data.common) } } diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index 0ce9e3d0..e21fe328 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -5,7 +5,7 @@ use crate::field::field_types::{Field, RichField}; use crate::fri::verifier::verify_fri_proof; use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData}; use crate::plonk::plonk_common::reduce_with_powers; -use crate::plonk::proof::ProofWithPublicInputs; +use crate::plonk::proof::{ProofChallenges, ProofWithPublicInputs}; use crate::plonk::vanishing_poly::eval_vanishing_poly; use crate::plonk::vars::EvaluationVars; @@ -14,9 +14,17 @@ pub(crate) fn verify, const D: usize>( verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, ) -> Result<()> { - let public_inputs_hash = &proof_with_pis.get_public_inputs_hash(); - let challenges = proof_with_pis.get_challenges(common_data)?; + verify_with_challenges(proof_with_pis, challenges, verifier_data, common_data) +} + +pub(crate) fn verify_with_challenges, const D: usize>( + proof_with_pis: ProofWithPublicInputs, + challenges: ProofChallenges, + verifier_data: &VerifierOnlyCircuitData, + common_data: &CommonCircuitData, +) -> Result<()> { + let public_inputs_hash = &proof_with_pis.get_public_inputs_hash(); let ProofWithPublicInputs { proof, .. } = proof_with_pis; From ea69a873389d82242cdd797a605f07b342d40bc9 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 11 Oct 2021 16:40:31 +0200 Subject: [PATCH 03/10] Working --- src/fri/proof.rs | 18 +++++++++++++++--- src/fri/verifier.rs | 33 ++++++++++++++------------------- src/plonk/get_challenges.rs | 37 +++++++++++++++++++++++++++++-------- src/plonk/proof.rs | 17 +++++++++++++++-- src/util/serialization.rs | 9 ++++++--- 5 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/fri/proof.rs b/src/fri/proof.rs index 130cf57d..3cbfaa0a 100644 --- a/src/fri/proof.rs +++ b/src/fri/proof.rs @@ -249,8 +249,8 @@ impl, const D: usize> CompressedFriProof { fri_query_inferred_elements, .. } = challenges; - let fri_query_inferred_elements = if let Some(v) = fri_query_inferred_elements { - v + let mut fri_query_inferred_elements = if let Some(v) = fri_query_inferred_elements { + v.iter().copied() } else { panic!() }; @@ -281,6 +281,10 @@ impl, const D: usize> CompressedFriProof { }) .collect::>(); + let mut evals_by_depth = vec![ + HashMap::>::new(); + common_data.fri_params.reduction_arity_bits.len() + ]; for (round, mut index) in indices.iter().copied().enumerate() { let initial_trees_proof = query_round_proofs.initial_trees_proofs[&index].clone(); for (i, (leaves_data, proof)) in @@ -298,7 +302,15 @@ impl, const D: usize> CompressedFriProof { merkle_proof, } = query_round_proofs.steps[i][&index].clone(); steps_indices[i].push(index); - evals.insert(index_within_coset, fri_query_inferred_elements[round][i]); + if let Some(v) = evals_by_depth[i].get(&index) { + evals = v.to_vec(); + } else { + evals.insert( + index_within_coset, + fri_query_inferred_elements.next().unwrap(), + ); + evals_by_depth[i].insert(index, evals.clone()); + } steps_evals[i].push(flatten(&evals)); steps_proofs[i].push(merkle_proof); } diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index 23739639..c1d97118 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -120,14 +120,14 @@ fn fri_verify_initial_proof( /// Holds the reduced (by `alpha`) evaluations at `zeta` for the polynomial opened just at /// zeta, for `Z` at zeta and for `Z` at `g*zeta`. #[derive(Copy, Clone, Debug)] -struct PrecomputedReducedEvals, const D: usize> { +pub(crate) struct PrecomputedReducedEvals, const D: usize> { pub single: F::Extension, pub zs: F::Extension, pub zs_right: F::Extension, } impl, const D: usize> PrecomputedReducedEvals { - fn from_os_and_alpha(os: &OpeningSet, alpha: F::Extension) -> Self { + pub(crate) fn from_os_and_alpha(os: &OpeningSet, alpha: F::Extension) -> Self { let mut alpha = ReducingFactor::new(alpha); let single = alpha.reduce( os.constants @@ -148,7 +148,7 @@ impl, const D: usize> PrecomputedReducedEvals { } } -fn fri_combine_initial, const D: usize>( +pub(crate) fn fri_combine_initial, const D: usize>( proof: &FriInitialTreeProof, alpha: F::Extension, zeta: F::Extension, @@ -159,10 +159,10 @@ fn fri_combine_initial, const D: usize>( let config = &common_data.config; assert!(D > 1, "Not implemented for D=1."); let degree_log = common_data.degree_bits; - debug_assert_eq!( - degree_log, - common_data.config.cap_height + proof.evals_proofs[0].1.siblings.len() - config.rate_bits - ); + // debug_assert_eq!( + // degree_log, + // common_data.config.cap_height + proof.evals_proofs[0].1.siblings.len() - config.rate_bits + // ); let subgroup_x = F::Extension::from_basefield(subgroup_x); let mut alpha = ReducingFactor::new(alpha); let mut sum = F::Extension::ZERO; @@ -262,18 +262,13 @@ fn fri_verifier_query_round, const D: usize>( ensure!(evals[x_index_within_coset] == old_eval); // Infer P(y) from {P(x)}_{x^arity=y}. - old_eval = if let Some(v) = &challenges.fri_query_inferred_elements { - dbg!("yo"); - v[round][i] - } else { - compute_evaluation( - subgroup_x, - x_index_within_coset, - arity_bits, - evals, - challenges.fri_betas[i], - ) - }; + old_eval = compute_evaluation( + subgroup_x, + x_index_within_coset, + arity_bits, + evals, + challenges.fri_betas[i], + ); verify_merkle_proof( flatten(evals), diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index e3fa54c8..97907138 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -1,6 +1,8 @@ +use std::collections::HashSet; + use crate::field::extension_field::Extendable; use crate::field::field_types::{Field, RichField}; -use crate::fri::verifier::compute_evaluation; +use crate::fri::verifier::{compute_evaluation, fri_combine_initial, PrecomputedReducedEvals}; use crate::hash::hashing::hash_n_to_1; use crate::iop::challenger::Challenger; use crate::plonk::circuit_data::CommonCircuitData; @@ -157,36 +159,55 @@ impl, const D: usize> CompressedProofWithPublicInpu .map(|_| challenger.get_challenge().to_canonical_u64() as usize % lde_size) .collect::>(); + let mut seen_indices_by_depth = + vec![HashSet::new(); common_data.fri_params.reduction_arity_bits.len()]; + let precomputed_reduced_evals = + PrecomputedReducedEvals::from_os_and_alpha(&self.proof.openings, fri_alpha); let mut fri_query_inferred_elements = Vec::new(); let log_n = common_data.degree_bits + common_data.config.rate_bits; for query_round in 0..common_data.config.fri_config.num_query_rounds { - let mut query_round_inferred_elements = Vec::new(); let mut x_index = fri_query_indices[query_round]; let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); + let mut old_eval = fri_combine_initial( + &self + .proof + .opening_proof + .query_round_proofs + .initial_trees_proofs[&x_index], + fri_alpha, + plonk_zeta, + subgroup_x, + precomputed_reduced_evals, + common_data, + ); for (i, &arity_bits) in common_data .fri_params .reduction_arity_bits .iter() .enumerate() { + if !seen_indices_by_depth[i].insert(x_index >> arity_bits) { + break; + } + fri_query_inferred_elements.push(old_eval); let arity = 1 << arity_bits; - let evals = &self.proof.opening_proof.query_round_proofs.steps[i] + let mut evals = self.proof.opening_proof.query_round_proofs.steps[i] [&(x_index >> arity_bits)] - .evals; + .evals + .clone(); let x_index_within_coset = x_index & (arity - 1); - let elmt = compute_evaluation( + evals.insert(x_index_within_coset, old_eval); + old_eval = compute_evaluation( subgroup_x, x_index_within_coset, arity_bits, - evals, + &evals, fri_betas[i], ); - query_round_inferred_elements.push(elmt); subgroup_x = subgroup_x.exp_power_of_2(arity_bits); x_index >>= arity_bits; } - fri_query_inferred_elements.push(query_round_inferred_elements); } Ok(ProofChallenges { diff --git a/src/plonk/proof.rs b/src/plonk/proof.rs index 0bc8ef96..ecc4e3a4 100644 --- a/src/plonk/proof.rs +++ b/src/plonk/proof.rs @@ -224,7 +224,7 @@ pub(crate) struct ProofChallenges, const D: usize> pub fri_query_indices: Vec, - pub fri_query_inferred_elements: Option>>, + pub fri_query_inferred_elements: Option>, } pub struct ProofWithPublicInputsTarget { @@ -307,7 +307,7 @@ mod tests { const D: usize = 4; let mut config = CircuitConfig::large_config(); - config.fri_config.reduction_strategy = FriReductionStrategy::Fixed(vec![1]); + config.fri_config.reduction_strategy = FriReductionStrategy::Fixed(vec![2, 1]); config.fri_config.num_query_rounds = 50; let pw = PartialWitness::new(); @@ -324,10 +324,23 @@ mod tests { builder.connect(zt, comp_zt); let data = builder.build(); let proof = data.prove(pw)?; + verify(proof.clone(), &data.verifier_only, &data.common)?; // Verify that `decompress ∘ compress = identity`. let compressed_proof = proof.clone().compress(&data.common)?; let decompressed_compressed_proof = compressed_proof.clone().decompress(&data.common)?; + for i in 0..proof.proof.opening_proof.query_round_proofs.len() { + let qrp = proof.proof.opening_proof.query_round_proofs[i].clone(); + let dqrp = decompressed_compressed_proof + .proof + .opening_proof + .query_round_proofs[i] + .clone(); + for j in 0..qrp.steps.len() { + dbg!(&qrp.steps[j].evals); + dbg!(&dqrp.steps[j].evals); + } + } assert_eq!(proof, decompressed_compressed_proof); verify(proof, &data.verifier_only, &data.common)?; diff --git a/src/util/serialization.rs b/src/util/serialization.rs index d4a4ea1e..e9164687 100644 --- a/src/util/serialization.rs +++ b/src/util/serialization.rs @@ -242,14 +242,17 @@ impl Buffer { &mut self, fqs: &FriQueryStep, ) -> Result<()> { + dbg!(self.0.position()); self.write_field_ext_vec::(&fqs.evals)?; self.write_merkle_proof(&fqs.merkle_proof) } fn read_fri_query_step, const D: usize>( &mut self, arity: usize, + compressed: bool, ) -> Result> { - let evals = self.read_field_ext_vec::(arity)?; + dbg!(self.0.position()); + let evals = self.read_field_ext_vec::(arity - if compressed { 1 } else { 0 })?; let merkle_proof = self.read_merkle_proof()?; Ok(FriQueryStep { evals, @@ -281,7 +284,7 @@ impl Buffer { .fri_params .reduction_arity_bits .iter() - .map(|&ar| self.read_fri_query_step(1 << ar)) + .map(|&ar| self.read_fri_query_step(1 << ar, false)) .collect::>()?; fqrs.push(FriQueryRound { initial_trees_proof, @@ -424,7 +427,7 @@ impl Buffer { }); indices.dedup(); let query_steps = (0..indices.len()) - .map(|_| self.read_fri_query_step(1 << a)) + .map(|_| self.read_fri_query_step(1 << a, true)) .collect::>>()?; steps.push( indices From acadd64371f0df8fd628bb6c2c2c9be16556ac89 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 11 Oct 2021 16:51:30 +0200 Subject: [PATCH 04/10] Clippy --- src/fri/proof.rs | 2 +- src/fri/verifier.rs | 7 ++----- src/plonk/get_challenges.rs | 12 ++---------- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/fri/proof.rs b/src/fri/proof.rs index 3cbfaa0a..264e2e9e 100644 --- a/src/fri/proof.rs +++ b/src/fri/proof.rs @@ -285,7 +285,7 @@ impl, const D: usize> CompressedFriProof { HashMap::>::new(); common_data.fri_params.reduction_arity_bits.len() ]; - for (round, mut index) in indices.iter().copied().enumerate() { + for &(mut index) in indices { let initial_trees_proof = query_round_proofs.initial_trees_proofs[&index].clone(); for (i, (leaves_data, proof)) in initial_trees_proof.evals_proofs.into_iter().enumerate() diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index c1d97118..dce20c38 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -83,20 +83,18 @@ pub(crate) fn verify_fri_proof, const D: usize>( let precomputed_reduced_evals = PrecomputedReducedEvals::from_os_and_alpha(os, challenges.fri_alpha); - for (round, (&x_index, round_proof)) in challenges + for (&x_index, round_proof) in challenges .fri_query_indices .iter() .zip(&proof.query_round_proofs) - .enumerate() { fri_verifier_query_round( challenges, precomputed_reduced_evals, initial_merkle_caps, - &proof, + proof, x_index, n, - round, round_proof, common_data, )?; @@ -220,7 +218,6 @@ fn fri_verifier_query_round, const D: usize>( proof: &FriProof, mut x_index: usize, n: usize, - round: usize, round_proof: &FriQueryRound, common_data: &CommonCircuitData, ) -> Result<()> { diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index 97907138..c579aa46 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use crate::field::extension_field::Extendable; -use crate::field::field_types::{Field, RichField}; +use crate::field::field_types::RichField; use crate::fri::verifier::{compute_evaluation, fri_combine_initial, PrecomputedReducedEvals}; use crate::hash::hashing::hash_n_to_1; use crate::iop::challenger::Challenger; @@ -93,13 +93,6 @@ impl, const D: usize> ProofWithPublicInputs { } impl, const D: usize> CompressedProofWithPublicInputs { - pub(crate) fn fri_query_indices( - &self, - common_data: &CommonCircuitData, - ) -> anyhow::Result> { - Ok(self.get_challenges(common_data)?.fri_query_indices) - } - pub(crate) fn get_challenges( &self, common_data: &CommonCircuitData, @@ -165,8 +158,7 @@ impl, const D: usize> CompressedProofWithPublicInpu PrecomputedReducedEvals::from_os_and_alpha(&self.proof.openings, fri_alpha); let mut fri_query_inferred_elements = Vec::new(); let log_n = common_data.degree_bits + common_data.config.rate_bits; - for query_round in 0..common_data.config.fri_config.num_query_rounds { - let mut x_index = fri_query_indices[query_round]; + for &(mut x_index) in &fri_query_indices { let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); let mut old_eval = fri_combine_initial( From ddac8026f25c7f81278cbb1628620f60a3c4b836 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 11 Oct 2021 17:24:06 +0200 Subject: [PATCH 05/10] Comments --- src/fri/proof.rs | 6 +++++- src/fri/verifier.rs | 4 ---- src/plonk/get_challenges.rs | 6 +++++- src/plonk/proof.rs | 13 ------------- src/util/serialization.rs | 2 -- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/fri/proof.rs b/src/fri/proof.rs index 264e2e9e..03239629 100644 --- a/src/fri/proof.rs +++ b/src/fri/proof.rs @@ -169,6 +169,7 @@ impl, const D: usize> FriProof { index >>= reduction_arity_bits[i]; steps_indices[i].push(index); let mut evals = query_step.evals; + // Remove the element that can be inferred. evals.remove(index_within_coset); steps_evals[i].push(evals); steps_proofs[i].push(query_step.merkle_proof); @@ -252,7 +253,7 @@ impl, const D: usize> CompressedFriProof { let mut fri_query_inferred_elements = if let Some(v) = fri_query_inferred_elements { v.iter().copied() } else { - panic!() + panic!("Proof challenges must be computed with `CompressedProofWithPublicInputs::get_challenges()`.") }; let cap_height = common_data.config.cap_height; let reduction_arity_bits = &common_data.fri_params.reduction_arity_bits; @@ -281,6 +282,7 @@ impl, const D: usize> CompressedFriProof { }) .collect::>(); + // Holds the `evals` vectors that have already been reconstructed at each reduction depth. let mut evals_by_depth = vec![ HashMap::>::new(); common_data.fri_params.reduction_arity_bits.len() @@ -303,8 +305,10 @@ impl, const D: usize> CompressedFriProof { } = query_round_proofs.steps[i][&index].clone(); steps_indices[i].push(index); if let Some(v) = evals_by_depth[i].get(&index) { + // If this index has already been seen, get `evals` from the `HashMap`. evals = v.to_vec(); } else { + // Otherwise insert the next inferred element. evals.insert( index_within_coset, fri_query_inferred_elements.next().unwrap(), diff --git a/src/fri/verifier.rs b/src/fri/verifier.rs index dce20c38..add03a9d 100644 --- a/src/fri/verifier.rs +++ b/src/fri/verifier.rs @@ -157,10 +157,6 @@ pub(crate) fn fri_combine_initial, const D: usize>( let config = &common_data.config; assert!(D > 1, "Not implemented for D=1."); let degree_log = common_data.degree_bits; - // debug_assert_eq!( - // degree_log, - // common_data.config.cap_height + proof.evals_proofs[0].1.siblings.len() - config.rate_bits - // ); let subgroup_x = F::Extension::from_basefield(subgroup_x); let mut alpha = ReducingFactor::new(alpha); let mut sum = F::Extension::ZERO; diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index c579aa46..0f6888b3 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -152,12 +152,15 @@ impl, const D: usize> CompressedProofWithPublicInpu .map(|_| challenger.get_challenge().to_canonical_u64() as usize % lde_size) .collect::>(); + let mut fri_query_inferred_elements = Vec::new(); + // Holds the indices that have already been seen at each reduction depth. let mut seen_indices_by_depth = vec![HashSet::new(); common_data.fri_params.reduction_arity_bits.len()]; let precomputed_reduced_evals = PrecomputedReducedEvals::from_os_and_alpha(&self.proof.openings, fri_alpha); - let mut fri_query_inferred_elements = Vec::new(); let log_n = common_data.degree_bits + common_data.config.rate_bits; + // Simulate the proof verification and add collect the inferred elements. + // The content of the loop is basically the same as the ` fri_verifier_query_round` function. for &(mut x_index) in &fri_query_indices { let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); @@ -180,6 +183,7 @@ impl, const D: usize> CompressedProofWithPublicInpu .enumerate() { if !seen_indices_by_depth[i].insert(x_index >> arity_bits) { + // If this index has already been seen, we can skip the rest of the reductions. break; } fri_query_inferred_elements.push(old_eval); diff --git a/src/plonk/proof.rs b/src/plonk/proof.rs index ecc4e3a4..5a0abfd7 100644 --- a/src/plonk/proof.rs +++ b/src/plonk/proof.rs @@ -168,7 +168,6 @@ impl, const D: usize> CompressedProofWithPublicInpu common_data: &CommonCircuitData, ) -> anyhow::Result<()> { let challenges = self.get_challenges(common_data)?; - dbg!(&challenges.fri_query_inferred_elements); let compressed_proof = self.proof.decompress(&challenges, common_data); verify_with_challenges( ProofWithPublicInputs { @@ -329,18 +328,6 @@ mod tests { // Verify that `decompress ∘ compress = identity`. let compressed_proof = proof.clone().compress(&data.common)?; let decompressed_compressed_proof = compressed_proof.clone().decompress(&data.common)?; - for i in 0..proof.proof.opening_proof.query_round_proofs.len() { - let qrp = proof.proof.opening_proof.query_round_proofs[i].clone(); - let dqrp = decompressed_compressed_proof - .proof - .opening_proof - .query_round_proofs[i] - .clone(); - for j in 0..qrp.steps.len() { - dbg!(&qrp.steps[j].evals); - dbg!(&dqrp.steps[j].evals); - } - } assert_eq!(proof, decompressed_compressed_proof); verify(proof, &data.verifier_only, &data.common)?; diff --git a/src/util/serialization.rs b/src/util/serialization.rs index e9164687..172b4d67 100644 --- a/src/util/serialization.rs +++ b/src/util/serialization.rs @@ -242,7 +242,6 @@ impl Buffer { &mut self, fqs: &FriQueryStep, ) -> Result<()> { - dbg!(self.0.position()); self.write_field_ext_vec::(&fqs.evals)?; self.write_merkle_proof(&fqs.merkle_proof) } @@ -251,7 +250,6 @@ impl Buffer { arity: usize, compressed: bool, ) -> Result> { - dbg!(self.0.position()); let evals = self.read_field_ext_vec::(arity - if compressed { 1 } else { 0 })?; let merkle_proof = self.read_merkle_proof()?; Ok(FriQueryStep { From 288a8e1155e4fcaae0fc28e0c2de94f3800c80e6 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 11 Oct 2021 18:44:17 +0200 Subject: [PATCH 06/10] Minor comments --- src/plonk/proof.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plonk/proof.rs b/src/plonk/proof.rs index 5a0abfd7..29cac3cc 100644 --- a/src/plonk/proof.rs +++ b/src/plonk/proof.rs @@ -221,8 +221,11 @@ pub(crate) struct ProofChallenges, const D: usize> pub fri_pow_response: F, + // Indices at which the oracle is queried in FRI. pub fri_query_indices: Vec, + // Coset element that can be inferred in the FRI reduction step. + // Is typically set to None iff the challenges are computed from a non-compressed proof. pub fri_query_inferred_elements: Option>, } From 62f3b558ad6917a6f1c8bb79ea7e76a485f0d03c Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 11 Oct 2021 18:45:55 +0200 Subject: [PATCH 07/10] Typos --- src/plonk/get_challenges.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index 0f6888b3..8981e263 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -159,8 +159,8 @@ impl, const D: usize> CompressedProofWithPublicInpu let precomputed_reduced_evals = PrecomputedReducedEvals::from_os_and_alpha(&self.proof.openings, fri_alpha); let log_n = common_data.degree_bits + common_data.config.rate_bits; - // Simulate the proof verification and add collect the inferred elements. - // The content of the loop is basically the same as the ` fri_verifier_query_round` function. + // Simulate the proof verification and collect the inferred elements. + // The content of the loop is basically the same as the `fri_verifier_query_round` function. for &(mut x_index) in &fri_query_indices { let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); From cdb289296936cc4b3e2412fa306dbc1f6f80eb72 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 12 Oct 2021 08:38:43 +0200 Subject: [PATCH 08/10] Move inferred elements to a new struct --- src/fri/proof.rs | 15 +++-------- src/plonk/get_challenges.rs | 51 ++++++++++++++++++++++--------------- src/plonk/proof.rs | 26 ++++++++++++++----- 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/fri/proof.rs b/src/fri/proof.rs index 03239629..f6875fcc 100644 --- a/src/fri/proof.rs +++ b/src/fri/proof.rs @@ -14,7 +14,7 @@ use crate::hash::path_compression::{compress_merkle_proofs, decompress_merkle_pr use crate::iop::target::Target; use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::plonk_common::PolynomialsIndexBlinding; -use crate::plonk::proof::ProofChallenges; +use crate::plonk::proof::{FriInferredElements, ProofChallenges}; use crate::polynomial::polynomial::PolynomialCoeffs; /// Evaluations and Merkle proof produced by the prover in a FRI query step. @@ -236,6 +236,7 @@ impl, const D: usize> CompressedFriProof { pub(crate) fn decompress( self, challenges: &ProofChallenges, + fri_inferred_elements: FriInferredElements, common_data: &CommonCircuitData, ) -> FriProof { let CompressedFriProof { @@ -247,14 +248,9 @@ impl, const D: usize> CompressedFriProof { } = self; let ProofChallenges { fri_query_indices: indices, - fri_query_inferred_elements, .. } = challenges; - let mut fri_query_inferred_elements = if let Some(v) = fri_query_inferred_elements { - v.iter().copied() - } else { - panic!("Proof challenges must be computed with `CompressedProofWithPublicInputs::get_challenges()`.") - }; + let mut fri_inferred_elements = fri_inferred_elements.0.into_iter(); let cap_height = common_data.config.cap_height; let reduction_arity_bits = &common_data.fri_params.reduction_arity_bits; let num_reductions = reduction_arity_bits.len(); @@ -309,10 +305,7 @@ impl, const D: usize> CompressedFriProof { evals = v.to_vec(); } else { // Otherwise insert the next inferred element. - evals.insert( - index_within_coset, - fri_query_inferred_elements.next().unwrap(), - ); + evals.insert(index_within_coset, fri_inferred_elements.next().unwrap()); evals_by_depth[i].insert(index, evals.clone()); } steps_evals[i].push(flatten(&evals)); diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index 8981e263..63802689 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -7,7 +7,7 @@ use crate::hash::hashing::hash_n_to_1; use crate::iop::challenger::Challenger; use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::proof::{ - CompressedProofWithPublicInputs, ProofChallenges, ProofWithPublicInputs, + CompressedProofWithPublicInputs, FriInferredElements, ProofChallenges, ProofWithPublicInputs, }; use crate::util::reverse_bits; @@ -87,7 +87,6 @@ impl, const D: usize> ProofWithPublicInputs { fri_betas, fri_pow_response, fri_query_indices, - fri_query_inferred_elements: None, }) } } @@ -152,16 +151,39 @@ impl, const D: usize> CompressedProofWithPublicInpu .map(|_| challenger.get_challenge().to_canonical_u64() as usize % lde_size) .collect::>(); - let mut fri_query_inferred_elements = Vec::new(); + Ok(ProofChallenges { + plonk_betas, + plonk_gammas, + plonk_alphas, + plonk_zeta, + fri_alpha, + fri_betas, + fri_pow_response, + fri_query_indices, + }) + } + pub(crate) fn get_inferred_elements( + &self, + challenges: &ProofChallenges, + common_data: &CommonCircuitData, + ) -> FriInferredElements { + let ProofChallenges { + plonk_zeta, + fri_alpha, + fri_betas, + fri_query_indices, + .. + } = challenges; + let mut fri_inferred_elements = Vec::new(); // Holds the indices that have already been seen at each reduction depth. let mut seen_indices_by_depth = vec![HashSet::new(); common_data.fri_params.reduction_arity_bits.len()]; let precomputed_reduced_evals = - PrecomputedReducedEvals::from_os_and_alpha(&self.proof.openings, fri_alpha); + PrecomputedReducedEvals::from_os_and_alpha(&self.proof.openings, *fri_alpha); let log_n = common_data.degree_bits + common_data.config.rate_bits; // Simulate the proof verification and collect the inferred elements. // The content of the loop is basically the same as the `fri_verifier_query_round` function. - for &(mut x_index) in &fri_query_indices { + for &(mut x_index) in fri_query_indices { let mut subgroup_x = F::MULTIPLICATIVE_GROUP_GENERATOR * F::primitive_root_of_unity(log_n).exp_u64(reverse_bits(x_index, log_n) as u64); let mut old_eval = fri_combine_initial( @@ -170,8 +192,8 @@ impl, const D: usize> CompressedProofWithPublicInpu .opening_proof .query_round_proofs .initial_trees_proofs[&x_index], - fri_alpha, - plonk_zeta, + *fri_alpha, + *plonk_zeta, subgroup_x, precomputed_reduced_evals, common_data, @@ -186,7 +208,7 @@ impl, const D: usize> CompressedProofWithPublicInpu // If this index has already been seen, we can skip the rest of the reductions. break; } - fri_query_inferred_elements.push(old_eval); + fri_inferred_elements.push(old_eval); let arity = 1 << arity_bits; let mut evals = self.proof.opening_proof.query_round_proofs.steps[i] [&(x_index >> arity_bits)] @@ -205,17 +227,6 @@ impl, const D: usize> CompressedProofWithPublicInpu x_index >>= arity_bits; } } - - Ok(ProofChallenges { - plonk_betas, - plonk_gammas, - plonk_alphas, - plonk_zeta, - fri_alpha, - fri_betas, - fri_pow_response, - fri_query_indices, - fri_query_inferred_elements: Some(fri_query_inferred_elements), - }) + FriInferredElements(fri_inferred_elements) } } diff --git a/src/plonk/proof.rs b/src/plonk/proof.rs index 29cac3cc..4dfa26bd 100644 --- a/src/plonk/proof.rs +++ b/src/plonk/proof.rs @@ -122,6 +122,7 @@ impl, const D: usize> CompressedProof { pub(crate) fn decompress( self, challenges: &ProofChallenges, + fri_inferred_elements: FriInferredElements, common_data: &CommonCircuitData, ) -> Proof { let CompressedProof { @@ -137,7 +138,11 @@ impl, const D: usize> CompressedProof { plonk_zs_partial_products_cap, quotient_polys_cap, openings, - opening_proof: opening_proof.decompress(challenges, common_data), + opening_proof: opening_proof.decompress( + &challenges, + fri_inferred_elements, + common_data, + ), } } } @@ -155,7 +160,10 @@ impl, const D: usize> CompressedProofWithPublicInpu common_data: &CommonCircuitData, ) -> anyhow::Result> { let challenges = self.get_challenges(common_data)?; - let compressed_proof = self.proof.decompress(&challenges, common_data); + let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); + let compressed_proof = + self.proof + .decompress(&challenges, fri_inferred_elements, common_data); Ok(ProofWithPublicInputs { public_inputs: self.public_inputs, proof: compressed_proof, @@ -168,7 +176,10 @@ impl, const D: usize> CompressedProofWithPublicInpu common_data: &CommonCircuitData, ) -> anyhow::Result<()> { let challenges = self.get_challenges(common_data)?; - let compressed_proof = self.proof.decompress(&challenges, common_data); + let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); + let compressed_proof = + self.proof + .decompress(&challenges, fri_inferred_elements, common_data); verify_with_challenges( ProofWithPublicInputs { public_inputs: self.public_inputs, @@ -223,12 +234,13 @@ pub(crate) struct ProofChallenges, const D: usize> // Indices at which the oracle is queried in FRI. pub fri_query_indices: Vec, - - // Coset element that can be inferred in the FRI reduction step. - // Is typically set to None iff the challenges are computed from a non-compressed proof. - pub fri_query_inferred_elements: Option>, } +/// Coset element that can be inferred in the FRI reduction step. +pub(crate) struct FriInferredElements, const D: usize>( + pub Vec, +); + pub struct ProofWithPublicInputsTarget { pub proof: ProofTarget, pub public_inputs: Vec, From 1ced853f33faea27f48b3484f8bfff895d0afceb Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 12 Oct 2021 08:40:56 +0200 Subject: [PATCH 09/10] Add coset_index var --- src/plonk/get_challenges.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index 63802689..6a92c819 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -210,8 +210,8 @@ impl, const D: usize> CompressedProofWithPublicInpu } fri_inferred_elements.push(old_eval); let arity = 1 << arity_bits; - let mut evals = self.proof.opening_proof.query_round_proofs.steps[i] - [&(x_index >> arity_bits)] + let coset_index = x_index >> arity_bits; + let mut evals = self.proof.opening_proof.query_round_proofs.steps[i][&coset_index] .evals .clone(); let x_index_within_coset = x_index & (arity - 1); From 839110b794f4b40182ce2cbe893eae42fe7a6c60 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 12 Oct 2021 20:21:29 +0200 Subject: [PATCH 10/10] `coset_index` in other places --- src/plonk/get_challenges.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plonk/get_challenges.rs b/src/plonk/get_challenges.rs index 6a92c819..44249f7b 100644 --- a/src/plonk/get_challenges.rs +++ b/src/plonk/get_challenges.rs @@ -204,13 +204,13 @@ impl, const D: usize> CompressedProofWithPublicInpu .iter() .enumerate() { - if !seen_indices_by_depth[i].insert(x_index >> arity_bits) { + let coset_index = x_index >> arity_bits; + if !seen_indices_by_depth[i].insert(coset_index) { // If this index has already been seen, we can skip the rest of the reductions. break; } fri_inferred_elements.push(old_eval); let arity = 1 << arity_bits; - let coset_index = x_index >> arity_bits; let mut evals = self.proof.opening_proof.query_round_proofs.steps[i][&coset_index] .evals .clone(); @@ -224,7 +224,7 @@ impl, const D: usize> CompressedProofWithPublicInpu fri_betas[i], ); subgroup_x = subgroup_x.exp_power_of_2(arity_bits); - x_index >>= arity_bits; + x_index = coset_index; } } FriInferredElements(fri_inferred_elements)