mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 01:33:07 +00:00
Partial products of quotient
This commit is contained in:
parent
b5b2ef9f3e
commit
50cafca705
@ -439,8 +439,10 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.max()
|
||||
.expect("No gates?");
|
||||
|
||||
let num_partial_products =
|
||||
num_partial_products(self.config.num_routed_wires, max_filtered_constraint_degree);
|
||||
let num_partial_products = num_partial_products(
|
||||
self.config.num_routed_wires,
|
||||
max_filtered_constraint_degree - 1,
|
||||
);
|
||||
|
||||
// TODO: This should also include an encoding of gate constraints.
|
||||
let circuit_digest_parts = [
|
||||
|
||||
@ -73,7 +73,7 @@ pub(crate) fn eval_vanishing_poly<F: Extendable<D>, const D: usize>(
|
||||
gammas: &[F],
|
||||
alphas: &[F],
|
||||
) -> Vec<F::Extension> {
|
||||
let max_degree = common_data.max_filtered_constraint_degree;
|
||||
let max_degree = common_data.max_filtered_constraint_degree - 1;
|
||||
let (num_prods, final_num_prod) = common_data.num_partial_products;
|
||||
|
||||
let constraint_terms =
|
||||
@ -106,38 +106,29 @@ pub(crate) fn eval_vanishing_poly<F: Extendable<D>, const D: usize>(
|
||||
wire_value + s_sigma * betas[i].into() + gammas[i].into()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let quotient_values = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| numerator_values[j] / denominator_values[j])
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// The partial products considered for this iteration of `i`.
|
||||
let current_partial_products =
|
||||
&partial_products[2 * i * num_prods..(2 * i + 2) * num_prods];
|
||||
// The partial products for the numerator are in the first `num_prods` elements.
|
||||
let numerator_partial_products = ¤t_partial_products[..num_prods];
|
||||
// The partial products for the denominator are in the last `num_prods` elements.
|
||||
let denominator_partial_products = ¤t_partial_products[num_prods..];
|
||||
let current_partial_products = &partial_products[i * num_prods..(i + 1) * num_prods];
|
||||
// Check the numerator partial products.
|
||||
vanishing_partial_products_terms.extend(check_partial_products(
|
||||
&numerator_values,
|
||||
numerator_partial_products,
|
||||
max_degree,
|
||||
));
|
||||
// Check the denominator partial products.
|
||||
vanishing_partial_products_terms.extend(check_partial_products(
|
||||
&denominator_values,
|
||||
denominator_partial_products,
|
||||
max_degree,
|
||||
));
|
||||
let mut partial_product_check =
|
||||
check_partial_products("ient_values, current_partial_products, max_degree);
|
||||
denominator_values
|
||||
.chunks(max_degree - 1)
|
||||
.zip(partial_product_check.iter_mut())
|
||||
.for_each(|(d, q)| {
|
||||
*q *= d.iter().copied().product();
|
||||
});
|
||||
vanishing_partial_products_terms.extend(partial_product_check);
|
||||
|
||||
// The numerator final product is the product of the last `final_num_prod` elements.
|
||||
let f_prime: F::Extension = numerator_partial_products[num_prods - final_num_prod..]
|
||||
let quotient: F::Extension = current_partial_products[num_prods - final_num_prod..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
// The denominator final product is the product of the last `final_num_prod` elements.
|
||||
let g_prime: F::Extension = denominator_partial_products[num_prods - final_num_prod..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
vanishing_v_shift_terms.push(f_prime * z_x - g_prime * z_gz);
|
||||
vanishing_v_shift_terms.push(quotient * z_x - z_gz);
|
||||
}
|
||||
|
||||
let vanishing_terms = [
|
||||
@ -167,7 +158,7 @@ pub(crate) fn eval_vanishing_poly_base<F: Extendable<D>, const D: usize>(
|
||||
alphas: &[F],
|
||||
z_h_on_coset: &ZeroPolyOnCoset<F>,
|
||||
) -> Vec<F> {
|
||||
let max_degree = common_data.max_filtered_constraint_degree;
|
||||
let max_degree = common_data.max_filtered_constraint_degree - 1;
|
||||
let (num_prods, final_num_prod) = common_data.num_partial_products;
|
||||
|
||||
let constraint_terms =
|
||||
@ -200,44 +191,39 @@ pub(crate) fn eval_vanishing_poly_base<F: Extendable<D>, const D: usize>(
|
||||
wire_value + betas[i] * s_sigma + gammas[i]
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let quotient_values = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| numerator_values[j] / denominator_values[j])
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// The partial products considered for this iteration of `i`.
|
||||
let current_partial_products =
|
||||
&partial_products[2 * i * num_prods..(2 * i + 2) * num_prods];
|
||||
// The partial products for the numerator are in the first `num_prods` elements.
|
||||
let numerator_partial_products = ¤t_partial_products[..num_prods];
|
||||
// The partial products for the denominator are in the last `num_prods` elements.
|
||||
let denominator_partial_products = ¤t_partial_products[num_prods..];
|
||||
let current_partial_products = &partial_products[i * num_prods..(i + 1) * num_prods];
|
||||
// Check the numerator partial products.
|
||||
vanishing_partial_products_terms.extend(check_partial_products(
|
||||
&numerator_values,
|
||||
numerator_partial_products,
|
||||
max_degree,
|
||||
));
|
||||
// Check the denominator partial products.
|
||||
vanishing_partial_products_terms.extend(check_partial_products(
|
||||
&denominator_values,
|
||||
denominator_partial_products,
|
||||
max_degree,
|
||||
));
|
||||
let mut partial_product_check =
|
||||
check_partial_products("ient_values, current_partial_products, max_degree);
|
||||
denominator_values
|
||||
.chunks(max_degree)
|
||||
.zip(partial_product_check.iter_mut())
|
||||
.for_each(|(d, q)| {
|
||||
*q *= d.iter().copied().product();
|
||||
});
|
||||
dbg!(
|
||||
quotient_values[27],
|
||||
current_partial_products.last().unwrap()
|
||||
);
|
||||
partial_product_check.pop();
|
||||
vanishing_partial_products_terms.extend(partial_product_check);
|
||||
|
||||
// The numerator final product is the product of the last `final_num_prod` elements.
|
||||
let f_prime: F = numerator_partial_products[num_prods - final_num_prod..]
|
||||
let quotient: F = current_partial_products[num_prods - final_num_prod..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
// The denominator final product is the product of the last `final_num_prod` elements.
|
||||
let g_prime: F = denominator_partial_products[num_prods - final_num_prod..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
vanishing_v_shift_terms.push(f_prime * z_x - g_prime * z_gz);
|
||||
vanishing_v_shift_terms.push(quotient * z_x - z_gz);
|
||||
}
|
||||
|
||||
let vanishing_terms = [
|
||||
vanishing_z_1_terms,
|
||||
vanishing_partial_products_terms,
|
||||
vanishing_v_shift_terms,
|
||||
// vanishing_v_shift_terms,
|
||||
constraint_terms,
|
||||
]
|
||||
.concat();
|
||||
|
||||
@ -93,7 +93,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
// The first two polynomials in `partial_products` represent the final products used in the
|
||||
// computation of `Z`. They aren't needed anymore so we discard them.
|
||||
partial_products.iter_mut().for_each(|part| {
|
||||
part.drain(0..2);
|
||||
part.remove(0);
|
||||
});
|
||||
|
||||
let zs_partial_products = [plonk_z_vecs, partial_products.concat()].concat();
|
||||
@ -204,8 +204,8 @@ fn all_wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
}
|
||||
|
||||
/// Compute the partial products used in the `Z` polynomial.
|
||||
/// Returns the polynomials interpolating `partial_products(f) + partial_products(g)`
|
||||
/// where `f, g` are the products in the definition of `Z`: `Z(g^i) = n / d`.
|
||||
/// Returns the polynomials interpolating `partial_products(f / g)`
|
||||
/// where `f, g` are the products in the definition of `Z`: `Z(g^i) = f / g`.
|
||||
fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
witness: &Witness<F>,
|
||||
beta: F,
|
||||
@ -213,7 +213,7 @@ fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> Vec<PolynomialValues<F>> {
|
||||
let degree = common_data.max_filtered_constraint_degree;
|
||||
let degree = common_data.max_filtered_constraint_degree - 1;
|
||||
let subgroup = &prover_data.subgroup;
|
||||
let k_is = &common_data.k_is;
|
||||
let values = subgroup
|
||||
@ -221,47 +221,29 @@ fn wires_permutation_partial_products<F: Extendable<D>, const D: usize>(
|
||||
.enumerate()
|
||||
.map(|(i, &x)| {
|
||||
let s_sigmas = &prover_data.sigmas[i];
|
||||
let numerator_values = (0..common_data.config.num_routed_wires)
|
||||
let quotient_values = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| {
|
||||
let wire_value = witness.get_wire(i, j);
|
||||
let k_i = k_is[j];
|
||||
let s_id = k_i * x;
|
||||
wire_value + beta * s_id + gamma
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let denominator_values = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| {
|
||||
let wire_value = witness.get_wire(i, j);
|
||||
let s_sigma = s_sigmas[j];
|
||||
wire_value + beta * s_sigma + gamma
|
||||
let numerator = wire_value + beta * s_id + gamma;
|
||||
let denominator = wire_value + beta * s_sigma + gamma;
|
||||
numerator / denominator
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let numerator_partials = partial_products(&numerator_values, degree);
|
||||
let denominator_partials = partial_products(&denominator_values, degree);
|
||||
let quotient_partials = partial_products("ient_values, degree);
|
||||
|
||||
// This is the final product for the numerator.
|
||||
let numerator = numerator_partials
|
||||
[common_data.num_partial_products.0 - common_data.num_partial_products.1..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
// This is the final product for the denominator.
|
||||
let denominator = denominator_partials
|
||||
// This is the final product for the quotient.
|
||||
let quotient = quotient_partials
|
||||
[common_data.num_partial_products.0 - common_data.num_partial_products.1..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
|
||||
// We add the numerator and denominator at the beginning of the vector to reuse them
|
||||
// later in the computation of `Z`.
|
||||
[
|
||||
vec![numerator],
|
||||
vec![denominator],
|
||||
numerator_partials,
|
||||
denominator_partials,
|
||||
]
|
||||
.concat()
|
||||
// We add the quotient at the beginning of the vector to reuse them later in the computation of `Z`.
|
||||
[vec![quotient], quotient_partials].concat()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -287,10 +269,9 @@ fn compute_z<F: Extendable<D>, const D: usize>(
|
||||
) -> PolynomialValues<F> {
|
||||
let mut plonk_z_points = vec![F::ONE];
|
||||
for i in 1..common_data.degree() {
|
||||
let numerator = partial_products[0].values[i - 1];
|
||||
let denominator = partial_products[1].values[i - 1];
|
||||
let quotient = partial_products[0].values[i - 1];
|
||||
let last = *plonk_z_points.last().unwrap();
|
||||
plonk_z_points.push(last * numerator / denominator);
|
||||
plonk_z_points.push(last * quotient);
|
||||
}
|
||||
plonk_z_points.into()
|
||||
}
|
||||
@ -332,7 +313,8 @@ fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
|
||||
ZeroPolyOnCoset::new(common_data.degree_bits, max_filtered_constraint_degree_bits);
|
||||
|
||||
let quotient_values: Vec<Vec<F>> = points
|
||||
.into_par_iter()
|
||||
// .into_par_iter()
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, x)| {
|
||||
let shifted_x = F::coset_shift() * x;
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::util::ceil_div_usize;
|
||||
pub fn partial_products<T: Product + Copy>(v: &[T], max_degree: usize) -> Vec<T> {
|
||||
let mut res = Vec::new();
|
||||
let mut remainder = v.to_vec();
|
||||
while remainder.len() >= max_degree {
|
||||
while remainder.len() > max_degree {
|
||||
let new_partials = remainder
|
||||
.chunks(max_degree)
|
||||
// No need to compute the product if the chunk has size 1.
|
||||
@ -25,7 +25,10 @@ pub fn partial_products<T: Product + Copy>(v: &[T], max_degree: usize) -> Vec<T>
|
||||
};
|
||||
remainder = new_partials;
|
||||
// If there were a chunk of size 1, add it back to the remainder.
|
||||
remainder.extend(addendum);
|
||||
remainder.extend_from_slice(&addendum);
|
||||
if remainder.len() <= max_degree {
|
||||
res.extend(addendum);
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
@ -36,11 +39,14 @@ pub fn partial_products<T: Product + Copy>(v: &[T], max_degree: usize) -> Vec<T>
|
||||
pub fn num_partial_products(n: usize, max_degree: usize) -> (usize, usize) {
|
||||
let mut res = 0;
|
||||
let mut remainder = n;
|
||||
while remainder >= max_degree {
|
||||
while remainder > max_degree {
|
||||
let new_partials_len = ceil_div_usize(remainder, max_degree);
|
||||
let addendum = if remainder % max_degree == 1 { 1 } else { 0 };
|
||||
res += new_partials_len - addendum;
|
||||
remainder = new_partials_len;
|
||||
if remainder <= max_degree {
|
||||
res += addendum;
|
||||
}
|
||||
}
|
||||
|
||||
(res, remainder)
|
||||
@ -56,7 +62,7 @@ pub fn check_partial_products<T: Product + Copy + Sub<Output = T>>(
|
||||
let mut res = Vec::new();
|
||||
let mut remainder = v.to_vec();
|
||||
let mut partials = partials.to_vec();
|
||||
while remainder.len() >= max_degree {
|
||||
while remainder.len() > max_degree {
|
||||
let products = remainder
|
||||
.chunks(max_degree)
|
||||
.filter(|chunk| chunk.len() != 1)
|
||||
@ -69,7 +75,10 @@ pub fn check_partial_products<T: Product + Copy + Sub<Output = T>>(
|
||||
vec![]
|
||||
};
|
||||
remainder = partials.drain(..products.len()).collect();
|
||||
remainder.extend(addendum)
|
||||
remainder.extend_from_slice(&addendum);
|
||||
if remainder.len() <= max_degree {
|
||||
res.extend(addendum.into_iter().map(|a| a - *partials.last().unwrap()));
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
@ -85,7 +94,7 @@ mod tests {
|
||||
fn test_partial_products() {
|
||||
let v = vec![1, 2, 3, 4, 5, 6];
|
||||
let p = partial_products(&v, 2);
|
||||
assert_eq!(p, vec![2, 12, 30, 24, 720]);
|
||||
assert_eq!(p, vec![2, 12, 30, 24, 30]);
|
||||
let nums = num_partial_products(v.len(), 2);
|
||||
assert_eq!(p.len(), nums.0);
|
||||
assert!(check_partial_products(&v, &p, 2)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user