Skip to content

Commit

Permalink
Reduce degree of R to |H|. Update num_blinding_gates and computed_h
Browse files Browse the repository at this point in the history
  • Loading branch information
LindaGuiga committed Oct 10, 2024
1 parent 6aa4ca6 commit 0080b86
Show file tree
Hide file tree
Showing 16 changed files with 77 additions and 206 deletions.
24 changes: 6 additions & 18 deletions plonky2/src/batch_fri/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,24 +176,12 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>

// If we are in the zk case, we still have to add `R(X)` to the batch.
if is_zk && idx == 0 {
let degree = 1 << degree_bits[i];
let mut composition_poly = PolynomialCoeffs::empty();
polynomials[last_poly..]
.iter()
.enumerate()
.for_each(|(i, fri_poly)| {
let mut cur_coeffs = oracles[fri_poly.oracle_index].polynomials
[fri_poly.polynomial_index]
.coeffs
.clone();
cur_coeffs.reverse();
cur_coeffs.extend(vec![F::ZERO; degree * i]);
cur_coeffs.reverse();
cur_coeffs.extend(vec![F::ZERO; 2 * degree - cur_coeffs.len()]);
composition_poly += PolynomialCoeffs { coeffs: cur_coeffs };
});

final_poly += composition_poly.to_extension();
// There should be only one R polynomial left.
polynomials[last_poly..].iter().for_each(|fri_poly| {
final_poly += oracles[fri_poly.oracle_index].polynomials
[fri_poly.polynomial_index]
.to_extension();
});
}
}

Expand Down
8 changes: 1 addition & 7 deletions plonky2/src/batch_fri/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn batch_fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
fri_params: &FriParams,
timing: &mut TimingTree,
) -> FriProof<F, C::Hasher, D> {
let mut n = lde_polynomial_coeffs.len();
let n = lde_polynomial_coeffs.len();
assert_eq!(lde_polynomial_values[0].len(), lde_polynomial_coeffs.len());
// The polynomial vectors should be sorted by degree, from largest to smallest, with no duplicate degrees.
assert!(lde_polynomial_values
Expand All @@ -49,12 +49,6 @@ pub fn batch_fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
}
assert_eq!(cur_poly_index, lde_polynomial_values.len());

// In the zk case, the final polynomial polynomial to be reduced has degree double that
// of the original batch FRI polynomial.
if fri_params.hiding {
n /= 2;
}

// Commit phase
let (trees, final_coeffs) = timed!(
timing,
Expand Down
36 changes: 9 additions & 27 deletions plonky2/src/batch_fri/recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use alloc::{format, vec::Vec};

use itertools::Itertools;
use plonky2_field::types::Field;

use crate::field::extension::Extendable;
use crate::fri::proof::{
Expand Down Expand Up @@ -200,26 +199,14 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {

// If we are in the zk case, we still have to add `R(X)` to the batch.
if is_zk && idx == 0 {
polynomials[last_poly..]
.iter()
.enumerate()
.for_each(|(i, p)| {
let poly_blinding = instance[index].oracles[p.oracle_index].blinding;
let salted = params.hiding && poly_blinding;
let eval = proof.unsalted_eval(p.oracle_index, p.polynomial_index, salted);
let val = self
.constant_extension(F::Extension::from_canonical_u32((i == 0) as u32));
let power =
self.exp_power_of_2_extension(subgroup_x, i * params.degree_bits);
let pi =
self.constant_extension(F::Extension::from_canonical_u32(i as u32));
let power = self.mul_extension(power, pi);
let shift_val = self.add_extension(val, power);
polynomials[last_poly..].iter().for_each(|p| {
let poly_blinding = instance[index].oracles[p.oracle_index].blinding;
let salted = params.hiding && poly_blinding;
let eval = proof.unsalted_eval(p.oracle_index, p.polynomial_index, salted);

let eval_extension = eval.to_ext_target(self.zero());
let tmp = self.mul_extension(eval_extension, shift_val);
sum = self.add_extension(sum, tmp);
});
let eval_extension = eval.to_ext_target(self.zero());
sum = self.add_extension(sum, eval_extension);
});
}
}

Expand Down Expand Up @@ -247,7 +234,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
Self::assert_noncanonical_indices_ok(&params.config);
let mut x_index_bits = self.low_bits(x_index, n, F::BITS);

let initial_cap_index =
let cap_index =
self.le_sum(x_index_bits[x_index_bits.len() - params.config.cap_height..].iter());
with_context!(
self,
Expand All @@ -258,7 +245,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
&x_index_bits,
&round_proof.initial_trees_proof,
initial_merkle_caps,
initial_cap_index
cap_index
)
);

Expand Down Expand Up @@ -289,11 +276,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
);
batch_index += 1;

// In case of zk, the finaly polynomial's degree bits is increased by 1.
let cap_index = self.le_sum(
x_index_bits[x_index_bits.len() + params.hiding as usize - params.config.cap_height..]
.iter(),
);
for (i, &arity_bits) in params.reduction_arity_bits.iter().enumerate() {
let evals = &round_proof.steps[i].evals;

Expand Down
19 changes: 7 additions & 12 deletions plonky2/src/batch_fri/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,13 @@ fn batch_fri_combine_initial<

// If we are in the zk case, we still have to add `R(X)` to the batch.
if is_zk && idx == 0 {
polynomials[last_poly..]
.iter()
.enumerate()
.for_each(|(i, p)| {
let poly_blinding = instances[index].oracles[p.oracle_index].blinding;
let salted = params.hiding && poly_blinding;
let eval = proof.unsalted_eval(p.oracle_index, p.polynomial_index, salted);
let shift_val = F::Extension::from_canonical_usize((i == 0) as usize)
+ subgroup_x.exp_power_of_2(i * params.degree_bits)
* F::Extension::from_canonical_usize(i);
sum += F::Extension::from_basefield(eval) * shift_val;
});
polynomials[last_poly..].iter().for_each(|p| {
let poly_blinding = instances[index].oracles[p.oracle_index].blinding;
let salted = params.hiding && poly_blinding;
let eval = proof.unsalted_eval(p.oracle_index, p.polynomial_index, salted);

sum += F::Extension::from_basefield(eval);
});
}
}

Expand Down
3 changes: 1 addition & 2 deletions plonky2/src/fri/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ impl FriConfig {
self.rate_bits,
self.cap_height,
self.num_query_rounds,
hiding,
);
FriParams {
config: self.clone(),
Expand Down Expand Up @@ -104,7 +103,7 @@ impl FriParams {
}

pub fn final_poly_bits(&self) -> usize {
self.degree_bits + self.hiding as usize - self.total_arities()
self.degree_bits - self.total_arities()
}

pub fn final_poly_len(&self) -> usize {
Expand Down
23 changes: 5 additions & 18 deletions plonky2/src/fri/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,24 +225,11 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>

// If we are in the zk case, we still have to add `R(X)` to the batch.
if is_zk && idx == 0 {
let degree = 1 << oracles[0].degree_log;
let mut composition_poly = PolynomialCoeffs::empty();
polynomials[last_poly..]
.iter()
.enumerate()
.for_each(|(i, fri_poly)| {
let mut cur_coeffs = oracles[fri_poly.oracle_index].polynomials
[fri_poly.polynomial_index]
.coeffs
.clone();
cur_coeffs.reverse();
cur_coeffs.extend(vec![F::ZERO; degree * i]);
cur_coeffs.reverse();
cur_coeffs.extend(vec![F::ZERO; 2 * degree - cur_coeffs.len()]);
composition_poly += PolynomialCoeffs { coeffs: cur_coeffs };
});

final_poly += composition_poly.to_extension();
polynomials[last_poly..].iter().for_each(|fri_poly| {
final_poly += oracles[fri_poly.oracle_index].polynomials
[fri_poly.polynomial_index]
.to_extension();
});
}
}

Expand Down
22 changes: 10 additions & 12 deletions plonky2/src/fri/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> FriProof<F, H,
} = self;
let cap_height = params.config.cap_height;

let num_reductions = params.reduction_arity_bits.len();
let reduction_arity_bits = &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();

// "Transpose" the query round proofs, so that information for each Merkle tree is collected together.
Expand All @@ -169,8 +170,8 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> FriProof<F, H,
initial_trees_proofs[i].push(proof);
}
for (i, query_step) in steps.into_iter().enumerate() {
let index_within_coset = index & ((1 << params.reduction_arity_bits[i]) - 1);
index >>= params.reduction_arity_bits[i];
let index_within_coset = index & ((1 << reduction_arity_bits[i]) - 1);
index >>= reduction_arity_bits[i];
steps_indices[i].push(index);
let mut evals = query_step.evals;
// Remove the element that can be inferred.
Expand Down Expand Up @@ -257,7 +258,8 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> CompressedFriPr
let mut fri_inferred_elements = fri_inferred_elements.0.into_iter();
let cap_height = params.config.cap_height;

let num_reductions = params.reduction_arity_bits.len();
let reduction_arity_bits = &params.reduction_arity_bits;
let num_reductions = reduction_arity_bits.len();
let num_initial_trees = query_round_proofs
.initial_trees_proofs
.values()
Expand All @@ -284,8 +286,7 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> CompressedFriPr
.collect::<Vec<_>>();

// Holds the `evals` vectors that have already been reconstructed at each reduction depth.
let mut evals_by_depth =
vec![HashMap::<usize, Vec<_>>::new(); params.reduction_arity_bits.len()];
let mut evals_by_depth = vec![HashMap::<usize, Vec<_>>::new(); reduction_arity_bits.len()];
for &(mut index) in indices {
let initial_trees_proof = query_round_proofs.initial_trees_proofs[&index].clone();
for (i, (leaves_data, proof)) in
Expand All @@ -296,8 +297,8 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> CompressedFriPr
initial_trees_proofs[i].push(proof);
}
for i in 0..num_reductions {
let index_within_coset = index & ((1 << params.reduction_arity_bits[i]) - 1);
index >>= params.reduction_arity_bits[i];
let index_within_coset = index & ((1 << reduction_arity_bits[i]) - 1);
index >>= reduction_arity_bits[i];
let FriQueryStep {
mut evals,
merkle_proof,
Expand Down Expand Up @@ -325,10 +326,7 @@ impl<F: RichField + Extendable<D>, H: Hasher<F>, const D: usize> CompressedFriPr
.map(|(ls, is, ps)| decompress_merkle_proofs(ls, is, &ps, height, cap_height))
.collect::<Vec<_>>();
let steps_proofs = izip!(&steps_evals, &steps_indices, steps_proofs, heights)
.map(|(ls, is, ps, h)| {
let cur_h = if params.hiding { h + 1 } else { h };
decompress_merkle_proofs(ls, is, &ps, cur_h, cap_height)
})
.map(|(ls, is, ps, h)| decompress_merkle_proofs(ls, is, &ps, h, cap_height))
.collect::<Vec<_>>();

let mut decompressed_query_proofs = Vec::with_capacity(num_reductions);
Expand Down
6 changes: 1 addition & 5 deletions plonky2/src/fri/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
timing: &mut TimingTree,
) -> FriProof<F, C::Hasher, D> {
// In the zk case, the polynomial to be reduced has degree double that of the original batch FRI polynomial.
let n = if fri_params.hiding {
lde_polynomial_values.len() / 2
} else {
lde_polynomial_values.len()
};
let n = lde_polynomial_values.len();
assert_eq!(lde_polynomial_coeffs.len(), lde_polynomial_values.len());

// Commit phase
Expand Down
47 changes: 12 additions & 35 deletions plonky2/src/fri/recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use alloc::{format, vec::Vec};

use itertools::Itertools;
use plonky2_field::types::Field;

use crate::field::extension::Extendable;
use crate::fri::proof::{
Expand All @@ -24,10 +23,6 @@ use crate::util::reducing::ReducingFactorTarget;
use crate::util::{log2_strict, reverse_index_bits_in_place};
use crate::with_context;

// Length by which the Merkle proof is increased in the case of zk.
// This corresponds to the extra degree bit of the final computed polynomial.
const ZK_EXTRA_MERKLE_LENGTH: usize = 1;

impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
/// 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.
Expand Down Expand Up @@ -266,26 +261,15 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {

// If we are in the zk case, we still have to add `R(X)` to the batch.
if is_zk && idx == 0 {
polynomials[last_poly..]
.iter()
.enumerate()
.for_each(|(i, p)| {
let poly_blinding = instance.oracles[p.oracle_index].blinding;
let salted = params.hiding && poly_blinding;
let eval = proof.unsalted_eval(p.oracle_index, p.polynomial_index, salted);
let val = self
.constant_extension(F::Extension::from_canonical_u32((i == 0) as u32));
let power =
self.exp_power_of_2_extension(subgroup_x, i * params.degree_bits);
let pi =
self.constant_extension(F::Extension::from_canonical_u32(i as u32));
let power = self.mul_extension(power, pi);
let shift_val = self.add_extension(val, power);

let eval_extension = eval.to_ext_target(self.zero());
let tmp = self.mul_extension(eval_extension, shift_val);
sum = self.add_extension(sum, tmp);
});
polynomials[last_poly..].iter().for_each(|p| {
let poly_blinding = instance.oracles[p.oracle_index].blinding;
let salted = params.hiding && poly_blinding;
let eval_extension = proof
.unsalted_eval(p.oracle_index, p.polynomial_index, salted)
.to_ext_target(self.zero());

sum = self.add_extension(sum, eval_extension);
});
}
}

Expand Down Expand Up @@ -313,7 +297,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
Self::assert_noncanonical_indices_ok(&params.config);
let mut x_index_bits = self.low_bits(x_index, n_log, F::BITS);

let initial_cap_index =
let cap_index =
self.le_sum(x_index_bits[x_index_bits.len() - params.config.cap_height..].iter());
with_context!(
self,
Expand All @@ -322,7 +306,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
&x_index_bits,
&round_proof.initial_trees_proof,
initial_merkle_caps,
initial_cap_index
cap_index
)
);

Expand Down Expand Up @@ -350,11 +334,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
)
);

// In case of zk, the finaly polynomial's degree bits is increased by 1.
let cap_index = self.le_sum(
x_index_bits[x_index_bits.len() + params.hiding as usize - params.config.cap_height..]
.iter(),
);
for (i, &arity_bits) in params.reduction_arity_bits.iter().enumerate() {
let evals = &round_proof.steps[i].evals;

Expand Down Expand Up @@ -469,8 +448,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {

let mut steps = Vec::with_capacity(params.reduction_arity_bits.len());

// In case of zk, the finaly polynomial's degree bits is increased by `ZK_EXTRA_MERKLE_LENGTH`.
merkle_proof_len += ZK_EXTRA_MERKLE_LENGTH * params.hiding as usize;
for &arity_bits in &params.reduction_arity_bits {
assert!(merkle_proof_len >= arity_bits);
merkle_proof_len -= arity_bits;
Expand Down Expand Up @@ -529,7 +506,7 @@ impl<const D: usize> PrecomputedReducedOpeningsTarget<D> {
// the lower and higher coefficients of the random `R` polynomial.
// Those `R` polynomials should not be taken into account when
// computing the reduced openings.
let nb_r_polys = is_zk as usize * 2;
let nb_r_polys = is_zk as usize;
let reduced_openings_at_point = openings
.batches
.iter()
Expand Down
Loading

0 comments on commit 0080b86

Please sign in to comment.