mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-09 09:13:09 +00:00
Working
This commit is contained in:
parent
4e361726d0
commit
bd1672cbf2
@ -777,7 +777,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.expect("No gates?");
|
||||
|
||||
let num_partial_products =
|
||||
num_partial_products(self.config.num_routed_wires, quotient_degree_factor);
|
||||
num_partial_products(self.config.num_routed_wires, quotient_degree_factor - 1);
|
||||
|
||||
// TODO: This should also include an encoding of gate constraints.
|
||||
let circuit_digest_parts = [
|
||||
|
||||
@ -17,7 +17,7 @@ use crate::plonk::vanishing_poly::eval_vanishing_poly_base_batch;
|
||||
use crate::plonk::vars::EvaluationVarsBase;
|
||||
use crate::polynomial::polynomial::{PolynomialCoeffs, PolynomialValues};
|
||||
use crate::timed;
|
||||
use crate::util::partial_products::partial_products;
|
||||
use crate::util::partial_products::{check_partial_products, partial_products};
|
||||
use crate::util::timing::TimingTree;
|
||||
use crate::util::{log2_ceil, transpose};
|
||||
|
||||
@ -63,6 +63,7 @@ pub(crate) fn prove<F: RichField + Extendable<D>, const D: usize>(
|
||||
.map(|column| PolynomialValues::new(column.clone()))
|
||||
.collect()
|
||||
);
|
||||
let wires = wires_values.iter().map(|v| v.values[0]).collect::<Vec<_>>();
|
||||
|
||||
let wires_commitment = timed!(
|
||||
timing,
|
||||
@ -108,6 +109,33 @@ pub(crate) fn prove<F: RichField + Extendable<D>, const D: usize>(
|
||||
partial_products.iter_mut().for_each(|part| {
|
||||
part.remove(0);
|
||||
});
|
||||
// let part = partial_products[0].clone();
|
||||
// let v = part.iter().map(|v| v.values[0]).collect::<Vec<_>>();
|
||||
// dbg!();
|
||||
// let numerator_values = (0..common_data.config.num_routed_wires)
|
||||
// .map(|j| {
|
||||
// let wire_value = wires[j];
|
||||
// let k_i = common_data.k_is[j];
|
||||
// let s_id = k_i;
|
||||
// wire_value + s_id * betas[0] + gammas[0]
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
// let denominator_values = (0..common_data.config.num_routed_wires)
|
||||
// .map(|j| {
|
||||
// let wire_value = wires[j];
|
||||
// let s_sigma = s_sigmas[j];
|
||||
// wire_value + s_sigma * betas[0] + gammas[0]
|
||||
// })
|
||||
// .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[i * num_prods..(i + 1) * num_prods];
|
||||
// // Check the quotient partial products.
|
||||
// let mut partial_product_check = check_partial_products("ient_values, &v, quotient_degree);
|
||||
// dbg!(partial_product_check);
|
||||
|
||||
let zs_partial_products = [plonk_z_vecs, partial_products.concat()].concat();
|
||||
let zs_partial_products_commitment = timed!(
|
||||
@ -238,7 +266,7 @@ fn wires_permutation_partial_products<F: RichField + Extendable<D>, const D: usi
|
||||
prover_data: &ProverOnlyCircuitData<F, D>,
|
||||
common_data: &CommonCircuitData<F, D>,
|
||||
) -> Vec<PolynomialValues<F>> {
|
||||
let degree = common_data.quotient_degree_factor;
|
||||
let degree = common_data.quotient_degree_factor - 1;
|
||||
let subgroup = &prover_data.subgroup;
|
||||
let k_is = &common_data.k_is;
|
||||
let values = subgroup
|
||||
@ -266,12 +294,18 @@ fn wires_permutation_partial_products<F: RichField + Extendable<D>, const D: usi
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let quotient_partials = partial_products("ient_values, degree);
|
||||
dbg!(check_partial_products(
|
||||
"ient_values,
|
||||
"ient_partials,
|
||||
degree
|
||||
));
|
||||
|
||||
// This is the final product for the quotient.
|
||||
let quotient = quotient_partials[common_data.num_partial_products.1..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
let quotient = *quotient_partials.last().unwrap()
|
||||
* quotient_values[common_data.num_partial_products.1..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
|
||||
// We add the quotient at the beginning of the vector to reuse them later in the computation of `Z`.
|
||||
[vec![quotient], quotient_partials].concat()
|
||||
|
||||
@ -27,7 +27,7 @@ pub(crate) fn eval_vanishing_poly<F: RichField + Extendable<D>, const D: usize>(
|
||||
gammas: &[F],
|
||||
alphas: &[F],
|
||||
) -> Vec<F::Extension> {
|
||||
let max_degree = common_data.quotient_degree_factor;
|
||||
let max_degree = common_data.quotient_degree_factor - 1;
|
||||
let (num_prods, final_num_prod) = common_data.num_partial_products;
|
||||
|
||||
let constraint_terms =
|
||||
@ -73,20 +73,27 @@ pub(crate) fn eval_vanishing_poly<F: RichField + Extendable<D>, const D: usize>(
|
||||
check_partial_products("ient_values, current_partial_products, max_degree);
|
||||
// The first checks are of the form `q - n/d` which is a rational function not a polynomial.
|
||||
// We multiply them by `d` to get checks of the form `q*d - n` which low-degree polynomials.
|
||||
denominator_values
|
||||
.chunks(max_degree)
|
||||
.zip(partial_product_check.iter_mut())
|
||||
.for_each(|(d, q)| {
|
||||
*q *= d.iter().copied().product();
|
||||
});
|
||||
for (j, q) in partial_product_check.iter_mut().enumerate() {
|
||||
let range = j * (max_degree - 1)..(j + 1) * (max_degree - 1);
|
||||
*q *= denominator_values[range].iter().copied().product();
|
||||
}
|
||||
// denominator_values
|
||||
// .chunks(max_degree)
|
||||
// .zip(partial_product_check.iter_mut())
|
||||
// .for_each(|(d, q)| {
|
||||
// *q *= d.iter().copied().product();
|
||||
// });
|
||||
vanishing_partial_products_terms.extend(partial_product_check);
|
||||
|
||||
// The quotient final product is the product of the last `final_num_prod` elements.
|
||||
let quotient: F::Extension = current_partial_products[num_prods - final_num_prod..]
|
||||
let quotient: F::Extension = *current_partial_products.last().unwrap()
|
||||
* quotient_values[final_num_prod..].iter().copied().product();
|
||||
let mut wanted = quotient * z_x - z_gz;
|
||||
wanted *= denominator_values[final_num_prod..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
vanishing_v_shift_terms.push(quotient * z_x - z_gz);
|
||||
vanishing_v_shift_terms.push(wanted);
|
||||
}
|
||||
|
||||
let vanishing_terms = [
|
||||
@ -124,7 +131,7 @@ pub(crate) fn eval_vanishing_poly_base_batch<F: RichField + Extendable<D>, const
|
||||
assert_eq!(partial_products_batch.len(), n);
|
||||
assert_eq!(s_sigmas_batch.len(), n);
|
||||
|
||||
let max_degree = common_data.quotient_degree_factor;
|
||||
let max_degree = common_data.quotient_degree_factor - 1;
|
||||
let (num_prods, final_num_prod) = common_data.num_partial_products;
|
||||
|
||||
let num_gate_constraints = common_data.num_gate_constraints;
|
||||
@ -189,20 +196,31 @@ pub(crate) fn eval_vanishing_poly_base_batch<F: RichField + Extendable<D>, const
|
||||
check_partial_products("ient_values, current_partial_products, max_degree);
|
||||
// The first checks are of the form `q - n/d` which is a rational function not a polynomial.
|
||||
// We multiply them by `d` to get checks of the form `q*d - n` which low-degree polynomials.
|
||||
denominator_values
|
||||
.chunks(max_degree)
|
||||
.zip(partial_product_check.iter_mut())
|
||||
.for_each(|(d, q)| {
|
||||
*q *= d.iter().copied().product();
|
||||
});
|
||||
for (j, q) in partial_product_check.iter_mut().enumerate() {
|
||||
let range = j * (max_degree - 1)..(j + 1) * (max_degree - 1);
|
||||
*q *= denominator_values[range].iter().copied().product();
|
||||
}
|
||||
// denominator_values
|
||||
// .chunks(max_degree)
|
||||
// .zip(partial_product_check.iter_mut())
|
||||
// .for_each(|(d, q)| {
|
||||
// *q *= d.iter().copied().product();
|
||||
// });
|
||||
vanishing_partial_products_terms.extend(partial_product_check);
|
||||
|
||||
// The quotient final product is the product of the last `final_num_prod` elements.
|
||||
let quotient: F = current_partial_products[num_prods - final_num_prod..]
|
||||
let quotient: F = *current_partial_products.last().unwrap()
|
||||
* quotient_values[final_num_prod..].iter().copied().product();
|
||||
// let quotient: F = current_partial_products[num_prods - final_num_prod..]
|
||||
// .iter()
|
||||
// .copied()
|
||||
// .product();
|
||||
let mut wanted = quotient * z_x - z_gz;
|
||||
wanted *= denominator_values[final_num_prod..]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
vanishing_v_shift_terms.push(quotient * z_x - z_gz);
|
||||
vanishing_v_shift_terms.push(wanted);
|
||||
|
||||
numerator_values.clear();
|
||||
denominator_values.clear();
|
||||
|
||||
@ -3,20 +3,20 @@ use std::ops::{MulAssign, Sub};
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::field::field_types::{Field, RichField};
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::ceil_div_usize;
|
||||
|
||||
/// Compute partial products of the original vector `v` such that all products consist of `max_degree`
|
||||
/// or less elements. This is done until we've computed the product `P` of all elements in the vector.
|
||||
pub fn partial_products<T: MulAssign + Product + Copy>(v: &[T], max_degree: usize) -> Vec<T> {
|
||||
pub fn partial_products<F: Field>(v: &[F], max_degree: usize) -> Vec<F> {
|
||||
debug_assert!(max_degree > 1);
|
||||
let mut res = Vec::new();
|
||||
let mut acc = v[0];
|
||||
let mut acc = F::ONE;
|
||||
let chunk_size = max_degree - 1;
|
||||
let num_chunks = ceil_div_usize(v.len() - 1, chunk_size) - 1;
|
||||
let num_chunks = ceil_div_usize(v.len(), chunk_size) - 1;
|
||||
for i in 0..num_chunks {
|
||||
acc *= v[1 + i * chunk_size..1 + (i + 1) * chunk_size]
|
||||
acc *= v[i * chunk_size..(i + 1) * chunk_size]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
@ -31,30 +31,28 @@ pub fn partial_products<T: MulAssign + Product + Copy>(v: &[T], max_degree: usiz
|
||||
pub fn num_partial_products(n: usize, max_degree: usize) -> (usize, usize) {
|
||||
debug_assert!(max_degree > 1);
|
||||
let chunk_size = max_degree - 1;
|
||||
let num_chunks = ceil_div_usize(n - 1, chunk_size) - 1;
|
||||
let num_chunks = ceil_div_usize(n, chunk_size) - 1;
|
||||
|
||||
(num_chunks, 1 + num_chunks * chunk_size)
|
||||
(num_chunks, num_chunks * chunk_size)
|
||||
}
|
||||
|
||||
/// Checks that the partial products of `v` are coherent with those in `partials` by only computing
|
||||
/// products of size `max_degree` or less.
|
||||
pub fn check_partial_products<T: MulAssign + Product + Copy + Sub<Output = T>>(
|
||||
v: &[T],
|
||||
mut partials: &[T],
|
||||
max_degree: usize,
|
||||
) -> Vec<T> {
|
||||
pub fn check_partial_products<F: Field>(v: &[F], mut partials: &[F], max_degree: usize) -> Vec<F> {
|
||||
debug_assert!(max_degree > 1);
|
||||
let mut partials = partials.iter();
|
||||
let mut res = Vec::new();
|
||||
let mut acc = v[0];
|
||||
let mut acc = F::ONE;
|
||||
let chunk_size = max_degree - 1;
|
||||
let num_chunks = ceil_div_usize(v.len() - 1, chunk_size) - 1;
|
||||
let num_chunks = ceil_div_usize(v.len(), chunk_size) - 1;
|
||||
for i in 0..num_chunks {
|
||||
acc *= v[1 + i * chunk_size..1 + (i + 1) * chunk_size]
|
||||
acc *= v[i * chunk_size..(i + 1) * chunk_size]
|
||||
.iter()
|
||||
.copied()
|
||||
.product();
|
||||
res.push(acc - *partials.next().unwrap());
|
||||
let bacc = *partials.next().unwrap();
|
||||
res.push(acc - bacc);
|
||||
acc = bacc;
|
||||
}
|
||||
debug_assert!(partials.next().is_none());
|
||||
|
||||
@ -85,38 +83,38 @@ pub fn check_partial_products_recursively<F: RichField + Extendable<D>, const D:
|
||||
res
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use num::Zero;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_partial_products() {
|
||||
let v = vec![1, 2, 3, 4, 5, 6];
|
||||
let p = partial_products(&v, 2);
|
||||
assert_eq!(p, vec![2, 6, 24, 120]);
|
||||
let nums = num_partial_products(v.len(), 2);
|
||||
assert_eq!(p.len(), nums.0);
|
||||
assert!(check_partial_products(&v, &p, 2)
|
||||
.iter()
|
||||
.all(|x| x.is_zero()));
|
||||
assert_eq!(
|
||||
*p.last().unwrap() * v[nums.1..].iter().copied().product::<i32>(),
|
||||
v.into_iter().product::<i32>(),
|
||||
);
|
||||
|
||||
let v = vec![1, 2, 3, 4, 5, 6];
|
||||
let p = partial_products(&v, 3);
|
||||
assert_eq!(p, vec![6, 120]);
|
||||
let nums = num_partial_products(v.len(), 3);
|
||||
assert_eq!(p.len(), nums.0);
|
||||
assert!(check_partial_products(&v, &p, 3)
|
||||
.iter()
|
||||
.all(|x| x.is_zero()));
|
||||
assert_eq!(
|
||||
*p.last().unwrap() * v[nums.1..].iter().copied().product::<i32>(),
|
||||
v.into_iter().product::<i32>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use num::Zero;
|
||||
//
|
||||
// use super::*;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_partial_products() {
|
||||
// let v = vec![1, 2, 3, 4, 5, 6];
|
||||
// let p = partial_products(&v, 2);
|
||||
// assert_eq!(p, vec![2, 6, 24, 120]);
|
||||
// let nums = num_partial_products(v.len(), 2);
|
||||
// assert_eq!(p.len(), nums.0);
|
||||
// assert!(check_partial_products(&v, &p, 2)
|
||||
// .iter()
|
||||
// .all(|x| x.is_zero()));
|
||||
// assert_eq!(
|
||||
// *p.last().unwrap() * v[nums.1..].iter().copied().product::<i32>(),
|
||||
// v.into_iter().product::<i32>(),
|
||||
// );
|
||||
//
|
||||
// let v = vec![1, 2, 3, 4, 5, 6];
|
||||
// let p = partial_products(&v, 3);
|
||||
// assert_eq!(p, vec![6, 120]);
|
||||
// let nums = num_partial_products(v.len(), 3);
|
||||
// assert_eq!(p.len(), nums.0);
|
||||
// assert!(check_partial_products(&v, &p, 3)
|
||||
// .iter()
|
||||
// .all(|x| x.is_zero()));
|
||||
// assert_eq!(
|
||||
// *p.last().unwrap() * v[nums.1..].iter().copied().product::<i32>(),
|
||||
// v.into_iter().product::<i32>(),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user