Separate some circuit logic from FRI code (#414)

My goal is to make the FRI code independent of circuit objects like `CommonCircuitData`, so that it can be reused by STARK code which won't involve those objects.

A few changes here:

- Move `rate_bits` and `cap_height` into `FriConfig`.
- Move `degree_bits` into `FriParameters` (since it's instance size specific).
- Make `FriParams` contain `FriConfig`, so FRI methods can take just the former and access fields in both.
- Replace `CommonCircuitConfig` with `FriParams` in FRI prover methods.

The FRI verifier methods still involve circuit objects, as they have PLONK logic in `fri_combine_initial`. Will think about how to deal with that after this.
This commit is contained in:
Daniel Lubarov 2022-01-02 11:26:26 -08:00 committed by GitHub
parent a452da523b
commit 23f0e49c87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 116 additions and 83 deletions

View File

@ -26,11 +26,11 @@ fn bench_prove<C: GenericConfig<D>, const D: usize>() -> Result<()> {
constant_gate_size: 6,
use_base_arithmetic_gate: false,
security_bits: 128,
rate_bits: 3,
num_challenges: 3,
zero_knowledge: false,
cap_height: 1,
fri_config: FriConfig {
rate_bits: 3,
cap_height: 1,
proof_of_work_bits: 15,
reduction_strategy: FriReductionStrategy::ConstantArityBits(3, 5),
num_query_rounds: 35,

View File

@ -208,14 +208,14 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
alpha.shift_poly(&mut final_poly);
final_poly += zs_quotient;
let lde_final_poly = final_poly.lde(config.rate_bits);
let lde_final_poly = final_poly.lde(config.fri_config.rate_bits);
let lde_final_values = timed!(
timing,
&format!("perform final FFT {}", lde_final_poly.len()),
lde_final_poly.coset_fft(F::coset_shift().into())
);
let fri_proof = fri_proof(
let fri_proof = fri_proof::<F, C, D>(
&commitments
.par_iter()
.map(|c| &c.merkle_tree)
@ -223,7 +223,7 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
lde_final_poly,
lde_final_values,
challenger,
common_data,
&common_data.fri_params,
timing,
);

View File

@ -9,6 +9,12 @@ pub mod verifier;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct FriConfig {
/// `rate = 2^{-rate_bits}`.
pub rate_bits: usize,
/// Height of Merkle tree caps.
pub cap_height: usize,
pub proof_of_work_bits: u32,
pub reduction_strategy: FriReductionStrategy,
@ -17,10 +23,16 @@ pub struct FriConfig {
pub num_query_rounds: usize,
}
/// Parameters which are generated during preprocessing, in contrast to `FriConfig` which is
/// user-specified.
/// FRI parameters, including generated parameters which are specific to an instance size, in
/// contrast to `FriConfig` which is user-specified and independent of instance size.
#[derive(Debug)]
pub(crate) struct FriParams {
pub struct FriParams {
/// User-specified FRI configuration.
pub config: FriConfig,
/// The degree of the purported codeword, measured in bits.
pub degree_bits: usize,
/// The arity of each FRI reduction step, expressed as the log2 of the actual arity.
/// For example, `[3, 2, 1]` would describe a FRI reduction tree with 8-to-1 reduction, then
/// a 4-to-1 reduction, then a 2-to-1 reduction. After these reductions, the reduced polynomial
@ -36,4 +48,20 @@ impl FriParams {
pub(crate) fn max_arity_bits(&self) -> Option<usize> {
self.reduction_arity_bits.iter().copied().max()
}
pub fn lde_bits(&self) -> usize {
self.degree_bits + self.config.rate_bits
}
pub fn lde_size(&self) -> usize {
1 << self.lde_bits()
}
pub fn final_poly_bits(&self) -> usize {
self.degree_bits - self.total_arities()
}
pub fn final_poly_len(&self) -> usize {
1 << self.final_poly_bits()
}
}

View File

@ -140,7 +140,7 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> FriProof<F, H,
pow_witness,
..
} = self;
let cap_height = common_data.config.cap_height;
let cap_height = common_data.config.fri_config.cap_height;
let reduction_arity_bits = &common_data.fri_params.reduction_arity_bits;
let num_reductions = reduction_arity_bits.len();
let num_initial_trees = query_round_proofs[0].initial_trees_proof.evals_proofs.len();
@ -252,7 +252,7 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> CompressedFriPr
..
} = challenges;
let mut fri_inferred_elements = fri_inferred_elements.0.into_iter();
let cap_height = common_data.config.cap_height;
let cap_height = common_data.config.fri_config.cap_height;
let reduction_arity_bits = &common_data.fri_params.reduction_arity_bits;
let num_reductions = reduction_arity_bits.len();
let num_initial_trees = query_round_proofs
@ -270,7 +270,7 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> CompressedFriPr
let mut steps_indices = vec![vec![]; num_reductions];
let mut steps_evals = vec![vec![]; num_reductions];
let mut steps_proofs = vec![vec![]; num_reductions];
let height = common_data.degree_bits + common_data.config.rate_bits;
let height = common_data.degree_bits + common_data.config.fri_config.rate_bits;
let heights = reduction_arity_bits
.iter()
.scan(height, |acc, &bits| {

View File

@ -4,11 +4,10 @@ use plonky2_util::reverse_index_bits_in_place;
use rayon::prelude::*;
use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep};
use crate::fri::FriConfig;
use crate::fri::{FriConfig, FriParams};
use crate::hash::hash_types::{HashOut, RichField};
use crate::hash::merkle_tree::MerkleTree;
use crate::iop::challenger::Challenger;
use crate::plonk::circuit_data::CommonCircuitData;
use crate::plonk::config::{GenericConfig, Hasher};
use crate::plonk::plonk_common::reduce_with_powers;
use crate::timed;
@ -22,7 +21,7 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
// Evaluation of the polynomial on the large domain.
lde_polynomial_values: PolynomialValues<F::Extension>,
challenger: &mut Challenger<F, C::Hasher>,
common_data: &CommonCircuitData<F, C, D>,
fri_params: &FriParams,
timing: &mut TimingTree,
) -> FriProof<F, C::Hasher, D> {
let n = lde_polynomial_values.values.len();
@ -32,11 +31,11 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
let (trees, final_coeffs) = timed!(
timing,
"fold codewords in the commitment phase",
fri_committed_trees(
fri_committed_trees::<F, C, D>(
lde_polynomial_coeffs,
lde_polynomial_values,
challenger,
common_data,
fri_params,
)
);
@ -45,12 +44,12 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
let pow_witness = timed!(
timing,
"find proof-of-work witness",
fri_proof_of_work::<F, C, D>(current_hash, &common_data.config.fri_config)
fri_proof_of_work::<F, C, D>(current_hash, &fri_params.config)
);
// Query phase
let query_round_proofs =
fri_prover_query_rounds(initial_merkle_trees, &trees, challenger, n, common_data);
fri_prover_query_rounds::<F, C, D>(initial_merkle_trees, &trees, challenger, n, fri_params);
FriProof {
commit_phase_merkle_caps: trees.iter().map(|t| t.cap.clone()).collect(),
@ -64,18 +63,17 @@ fn fri_committed_trees<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
mut coeffs: PolynomialCoeffs<F::Extension>,
mut values: PolynomialValues<F::Extension>,
challenger: &mut Challenger<F, C::Hasher>,
common_data: &CommonCircuitData<F, C, D>,
fri_params: &FriParams,
) -> (
Vec<MerkleTree<F, C::Hasher>>,
PolynomialCoeffs<F::Extension>,
) {
let config = &common_data.config;
let mut trees = Vec::new();
let mut shift = F::MULTIPLICATIVE_GROUP_GENERATOR;
let num_reductions = common_data.fri_params.reduction_arity_bits.len();
let num_reductions = fri_params.reduction_arity_bits.len();
for i in 0..num_reductions {
let arity = 1 << common_data.fri_params.reduction_arity_bits[i];
let arity = 1 << fri_params.reduction_arity_bits[i];
reverse_index_bits_in_place(&mut values.values);
let chunked_values = values
@ -83,7 +81,7 @@ fn fri_committed_trees<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
.par_chunks(arity)
.map(|chunk: &[F::Extension]| flatten(chunk))
.collect();
let tree = MerkleTree::<F, C::Hasher>::new(chunked_values, config.cap_height);
let tree = MerkleTree::<F, C::Hasher>::new(chunked_values, fri_params.config.cap_height);
challenger.observe_cap(&tree.cap);
trees.push(tree);
@ -102,7 +100,9 @@ fn fri_committed_trees<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
}
// The coefficients being removed here should always be zero.
coeffs.coeffs.truncate(coeffs.len() >> config.rate_bits);
coeffs
.coeffs
.truncate(coeffs.len() >> fri_params.config.rate_bits);
challenger.observe_extension_elements(&coeffs.coeffs);
(trees, coeffs)
@ -142,10 +142,18 @@ fn fri_prover_query_rounds<
trees: &[MerkleTree<F, C::Hasher>],
challenger: &mut Challenger<F, C::Hasher>,
n: usize,
common_data: &CommonCircuitData<F, C, D>,
fri_params: &FriParams,
) -> Vec<FriQueryRound<F, C::Hasher, D>> {
(0..common_data.config.fri_config.num_query_rounds)
.map(|_| fri_prover_query_round(initial_merkle_trees, trees, challenger, n, common_data))
(0..fri_params.config.num_query_rounds)
.map(|_| {
fri_prover_query_round::<F, C, D>(
initial_merkle_trees,
trees,
challenger,
n,
fri_params,
)
})
.collect()
}
@ -158,7 +166,7 @@ fn fri_prover_query_round<
trees: &[MerkleTree<F, C::Hasher>],
challenger: &mut Challenger<F, C::Hasher>,
n: usize,
common_data: &CommonCircuitData<F, C, D>,
fri_params: &FriParams,
) -> FriQueryRound<F, C::Hasher, D> {
let mut query_steps = Vec::new();
let x = challenger.get_challenge();
@ -168,7 +176,7 @@ fn fri_prover_query_round<
.map(|t| (t.get(x_index).to_vec(), t.prove(x_index)))
.collect::<Vec<_>>();
for (i, tree) in trees.iter().enumerate() {
let arity_bits = common_data.fri_params.reduction_arity_bits[i];
let arity_bits = fri_params.reduction_arity_bits[i];
let evals = unflatten(tree.get(x_index >> arity_bits));
let merkle_proof = tree.prove(x_index >> arity_bits);

View File

@ -78,7 +78,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
) {
let random_access = RandomAccessGate::<F, D>::new_from_config(
&self.config,
max_fri_arity_bits.max(self.config.cap_height),
max_fri_arity_bits.max(self.config.fri_config.cap_height),
);
let (interpolation_wires, interpolation_routed_wires) =
if 1 << max_fri_arity_bits > common_data.quotient_degree_factor {
@ -143,7 +143,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
debug_assert_eq!(
common_data.final_poly_len(),
common_data.fri_params.final_poly_len(),
proof.final_poly.len(),
"Final polynomial has wrong degree."
);
@ -267,8 +267,8 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
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
common_data.config.fri_config.cap_height + proof.evals_proofs[0].1.siblings.len()
- config.fri_config.rate_bits
);
let subgroup_x = self.convert_to_ext(subgroup_x);
let mut alpha = ReducingFactorTarget::new(alpha);
@ -343,8 +343,9 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let x_index = challenger.get_challenge(self);
let mut x_index_bits = self.low_bits(x_index, n_log, F::BITS);
let cap_index =
self.le_sum(x_index_bits[x_index_bits.len() - common_data.config.cap_height..].iter());
let cap_index = self.le_sum(
x_index_bits[x_index_bits.len() - common_data.config.fri_config.cap_height..].iter(),
);
with_context!(
self,
"check FRI initial proof",

View File

@ -72,7 +72,7 @@ pub(crate) fn verify_fri_proof<
) -> Result<()> {
let config = &common_data.config;
ensure!(
common_data.final_poly_len() == proof.final_poly.len(),
common_data.fri_params.final_poly_len() == proof.final_poly.len(),
"Final polynomial has wrong degree."
);

View File

@ -111,9 +111,9 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
fn check_config(&self) {
let &CircuitConfig {
security_bits,
rate_bits,
fri_config:
FriConfig {
rate_bits,
proof_of_work_bits,
num_query_rounds,
..
@ -368,14 +368,16 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
})
}
fn fri_params(&self, degree_bits_estimate: usize) -> FriParams {
fn fri_params(&self, degree_bits: usize) -> FriParams {
let fri_config = &self.config.fri_config;
let reduction_arity_bits = fri_config.reduction_strategy.reduction_arity_bits(
degree_bits_estimate,
self.config.rate_bits,
degree_bits,
self.config.fri_config.rate_bits,
fri_config.num_query_rounds,
);
FriParams {
config: fri_config.clone(),
degree_bits,
reduction_arity_bits,
}
}
@ -620,8 +622,8 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let (gate_tree, max_filtered_constraint_degree, num_constants) = Tree::from_gates(gates);
// `quotient_degree_factor` has to be between `max_filtered_constraint_degree-1` and `1<<rate_bits`.
// We find the value that minimizes `num_partial_product + quotient_degree_factor`.
let quotient_degree_factor = (max_filtered_constraint_degree - 1
..=1 << self.config.rate_bits)
let rate_bits = self.config.fri_config.rate_bits;
let quotient_degree_factor = (max_filtered_constraint_degree - 1..=1 << rate_bits)
.min_by_key(|&q| num_partial_products(self.config.num_routed_wires, q).0 + q)
.unwrap();
debug!("Quotient degree factor set to: {}.", quotient_degree_factor);
@ -635,16 +637,15 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let (sigma_vecs, forest) = self.sigma_vecs(&k_is, &subgroup);
// Precompute FFT roots.
let max_fft_points =
1 << (degree_bits + max(self.config.rate_bits, log2_ceil(quotient_degree_factor)));
let max_fft_points = 1 << (degree_bits + max(rate_bits, log2_ceil(quotient_degree_factor)));
let fft_root_table = fft_root_table(max_fft_points);
let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat();
let constants_sigmas_commitment = PolynomialBatchCommitment::from_values(
constants_sigmas_vecs,
self.config.rate_bits,
rate_bits,
self.config.zero_knowledge & PlonkPolynomials::CONSTANTS_SIGMAS.blinding,
self.config.cap_height,
self.config.fri_config.cap_height,
&mut timing,
Some(&fft_root_table),
);

View File

@ -30,14 +30,11 @@ pub struct CircuitConfig {
/// for both base field and extension field arithmetic.
pub use_base_arithmetic_gate: bool,
pub security_bits: usize,
pub rate_bits: usize,
/// The number of challenge points to generate, for IOPs that have soundness errors of (roughly)
/// `degree / |F|`.
pub num_challenges: usize,
pub zero_knowledge: bool,
pub cap_height: usize,
// TODO: Find a better place for this.
pub fri_config: FriConfig,
}
@ -49,7 +46,7 @@ impl Default for CircuitConfig {
impl CircuitConfig {
pub fn rate(&self) -> f64 {
1.0 / ((1 << self.rate_bits) as f64)
1.0 / ((1 << self.fri_config.rate_bits) as f64)
}
pub fn num_advice_wires(&self) -> usize {
@ -64,11 +61,11 @@ impl CircuitConfig {
constant_gate_size: 5,
use_base_arithmetic_gate: true,
security_bits: 100,
rate_bits: 3,
num_challenges: 2,
zero_knowledge: false,
cap_height: 4,
fri_config: FriConfig {
rate_bits: 3,
cap_height: 4,
proof_of_work_bits: 16,
reduction_strategy: FriReductionStrategy::ConstantArityBits(4, 5),
num_query_rounds: 28,
@ -251,11 +248,11 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
}
pub fn lde_size(&self) -> usize {
1 << (self.degree_bits + self.config.rate_bits)
1 << (self.degree_bits + self.config.fri_config.rate_bits)
}
pub fn lde_generator(&self) -> F {
F::primitive_root_of_unity(self.degree_bits + self.config.rate_bits)
F::primitive_root_of_unity(self.degree_bits + self.config.fri_config.rate_bits)
}
pub fn constraint_degree(&self) -> usize {
@ -289,10 +286,6 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
pub fn partial_products_range(&self) -> RangeFrom<usize> {
self.config.num_challenges..
}
pub fn final_poly_len(&self) -> usize {
1 << (self.degree_bits - self.fri_params.total_arities())
}
}
/// The `Target` version of `VerifierCircuitData`, for use inside recursive circuits. Note that this

View File

@ -189,7 +189,7 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
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 log_n = common_data.degree_bits + common_data.config.rate_bits;
let log_n = common_data.degree_bits + common_data.config.fri_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 {

View File

@ -71,9 +71,9 @@ pub(crate) fn prove<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, co
"compute wires commitment",
PolynomialBatchCommitment::from_values(
wires_values,
config.rate_bits,
config.fri_config.rate_bits,
config.zero_knowledge & PlonkPolynomials::WIRES.blinding,
config.cap_height,
config.fri_config.cap_height,
timing,
prover_data.fft_root_table.as_ref(),
)
@ -111,9 +111,9 @@ pub(crate) fn prove<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, co
"commit to partial products and Z's",
PolynomialBatchCommitment::from_values(
zs_partial_products,
config.rate_bits,
config.fri_config.rate_bits,
config.zero_knowledge & PlonkPolynomials::ZS_PARTIAL_PRODUCTS.blinding,
config.cap_height,
config.fri_config.cap_height,
timing,
prover_data.fft_root_table.as_ref(),
)
@ -160,9 +160,9 @@ pub(crate) fn prove<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, co
"commit to quotient polys",
PolynomialBatchCommitment::from_coeffs(
all_quotient_poly_chunks,
config.rate_bits,
config.fri_config.rate_bits,
config.zero_knowledge & PlonkPolynomials::QUOTIENT.blinding,
config.cap_height,
config.fri_config.cap_height,
timing,
prover_data.fft_root_table.as_ref(),
)
@ -309,14 +309,14 @@ fn compute_quotient_polys<
let num_challenges = common_data.config.num_challenges;
let max_degree_bits = log2_ceil(common_data.quotient_degree_factor);
assert!(
max_degree_bits <= common_data.config.rate_bits,
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."
);
// We reuse the LDE computed in `ListPolynomialCommitment` and extract every `step` points to get
// an LDE matching `max_filtered_constraint_degree`.
let step = 1 << (common_data.config.rate_bits - max_degree_bits);
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`
// steps away since we work on an LDE of degree `max_filtered_constraint_degree`.
let next_step = 1 << max_degree_bits;

View File

@ -454,8 +454,8 @@ mod tests {
// A high-rate recursive proof, designed to be verifiable with fewer routed wires.
let high_rate_config = CircuitConfig {
rate_bits: 7,
fri_config: FriConfig {
rate_bits: 7,
proof_of_work_bits: 16,
num_query_rounds: 12,
..standard_config.fri_config.clone()
@ -476,10 +476,10 @@ mod tests {
// A final proof, optimized for size.
let final_config = CircuitConfig {
cap_height: 0,
rate_bits: 8,
num_routed_wires: 37,
fri_config: FriConfig {
rate_bits: 8,
cap_height: 0,
proof_of_work_bits: 20,
reduction_strategy: FriReductionStrategy::MinSize(None),
num_query_rounds: 10,
@ -582,7 +582,7 @@ mod tests {
set_proof_target(&inner_proof, &pt, &mut pw);
let inner_data = VerifierCircuitTarget {
constants_sigmas_cap: builder.add_virtual_cap(inner_config.cap_height),
constants_sigmas_cap: builder.add_virtual_cap(inner_config.fri_config.cap_height),
};
pw.set_cap_target(
&inner_data.constants_sigmas_cap,

View File

@ -347,11 +347,12 @@ impl Buffer {
) -> Result<FriProof<F, C::Hasher, D>> {
let config = &common_data.config;
let commit_phase_merkle_caps = (0..common_data.fri_params.reduction_arity_bits.len())
.map(|_| self.read_merkle_cap(config.cap_height))
.map(|_| self.read_merkle_cap(config.fri_config.cap_height))
.collect::<Result<Vec<_>>>()?;
let query_round_proofs = self.read_fri_query_rounds(common_data)?;
let final_poly =
PolynomialCoeffs::new(self.read_field_ext_vec::<F, D>(common_data.final_poly_len())?);
let final_poly = PolynomialCoeffs::new(
self.read_field_ext_vec::<F, D>(common_data.fri_params.final_poly_len())?,
);
let pow_witness = self.read_field()?;
Ok(FriProof {
commit_phase_merkle_caps,
@ -376,9 +377,9 @@ impl Buffer {
common_data: &CommonCircuitData<F, C, D>,
) -> Result<Proof<F, C, D>> {
let config = &common_data.config;
let wires_cap = self.read_merkle_cap(config.cap_height)?;
let plonk_zs_partial_products_cap = self.read_merkle_cap(config.cap_height)?;
let quotient_polys_cap = self.read_merkle_cap(config.cap_height)?;
let wires_cap = self.read_merkle_cap(config.fri_config.cap_height)?;
let plonk_zs_partial_products_cap = self.read_merkle_cap(config.fri_config.cap_height)?;
let quotient_polys_cap = self.read_merkle_cap(config.fri_config.cap_height)?;
let openings = self.read_opening_set(common_data)?;
let opening_proof = self.read_fri_proof(common_data)?;
@ -522,11 +523,12 @@ impl Buffer {
) -> Result<CompressedFriProof<F, C::Hasher, D>> {
let config = &common_data.config;
let commit_phase_merkle_caps = (0..common_data.fri_params.reduction_arity_bits.len())
.map(|_| self.read_merkle_cap(config.cap_height))
.map(|_| self.read_merkle_cap(config.fri_config.cap_height))
.collect::<Result<Vec<_>>>()?;
let query_round_proofs = self.read_compressed_fri_query_rounds(common_data)?;
let final_poly =
PolynomialCoeffs::new(self.read_field_ext_vec::<F, D>(common_data.final_poly_len())?);
let final_poly = PolynomialCoeffs::new(
self.read_field_ext_vec::<F, D>(common_data.fri_params.final_poly_len())?,
);
let pow_witness = self.read_field()?;
Ok(CompressedFriProof {
commit_phase_merkle_caps,
@ -559,9 +561,9 @@ impl Buffer {
common_data: &CommonCircuitData<F, C, D>,
) -> Result<CompressedProof<F, C, D>> {
let config = &common_data.config;
let wires_cap = self.read_merkle_cap(config.cap_height)?;
let plonk_zs_partial_products_cap = self.read_merkle_cap(config.cap_height)?;
let quotient_polys_cap = self.read_merkle_cap(config.cap_height)?;
let wires_cap = self.read_merkle_cap(config.fri_config.cap_height)?;
let plonk_zs_partial_products_cap = self.read_merkle_cap(config.fri_config.cap_height)?;
let quotient_polys_cap = self.read_merkle_cap(config.fri_config.cap_height)?;
let openings = self.read_opening_set(common_data)?;
let opening_proof = self.read_compressed_fri_proof(common_data)?;