mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 23:03:08 +00:00
Merge main
This commit is contained in:
commit
b44a01c975
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
@ -0,0 +1,2 @@
|
||||
unstable_features = true
|
||||
group_imports = "StdExternalCrate"
|
||||
@ -1,10 +1,9 @@
|
||||
use std::time::Instant;
|
||||
|
||||
use rayon::prelude::*;
|
||||
|
||||
use plonky2::field::crandall_field::CrandallField;
|
||||
use plonky2::field::field::Field;
|
||||
use plonky2::polynomial::polynomial::PolynomialValues;
|
||||
use rayon::prelude::*;
|
||||
|
||||
type F = CrandallField;
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use env_logger::Env;
|
||||
|
||||
use plonky2::circuit_builder::CircuitBuilder;
|
||||
use plonky2::circuit_data::CircuitConfig;
|
||||
use plonky2::field::crandall_field::CrandallField;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use std::fmt;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::{Product, Sum};
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
|
||||
use num::Integer;
|
||||
@ -8,8 +10,6 @@ use crate::field::extension_field::quadratic::QuadraticCrandallField;
|
||||
use crate::field::extension_field::quartic::QuarticCrandallField;
|
||||
use crate::field::extension_field::{Extendable, Frobenius};
|
||||
use crate::field::field::Field;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::{Product, Sum};
|
||||
|
||||
/// EPSILON = 9 * 2**28 - 1
|
||||
const EPSILON: u64 = 2415919103;
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use crate::field::extension_field::OEF;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::iter::{Product, Sum};
|
||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
|
||||
use crate::field::extension_field::OEF;
|
||||
|
||||
/// Let `F_D` be the optimal extension field `F[X]/(X^D-W)`. Then `ExtensionAlgebra<F_D>` is the quotient `F_D[X]/(X^D-W)`.
|
||||
/// It's a `D`-dimensional algebra over `F_D` useful to lift the multiplication over `F_D` to a multiplication over `(F_D)^D`.
|
||||
#[derive(Copy, Clone)]
|
||||
@ -154,11 +155,12 @@ impl<F: OEF<D>, const D: usize> PolynomialCoeffsAlgebra<F, D> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::algebra::ExtensionAlgebra;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field::Field;
|
||||
use itertools::Itertools;
|
||||
|
||||
/// Tests that the multiplication on the extension algebra lifts that of the field extension.
|
||||
fn test_extension_algebra<F: Extendable<D>, const D: usize>() {
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::{FieldExtension, Frobenius, OEF};
|
||||
use crate::field::field::Field;
|
||||
use rand::Rng;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::hash::Hash;
|
||||
use std::iter::{Product, Sum};
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::field::extension_field::{FieldExtension, Frobenius, OEF};
|
||||
use crate::field::field::Field;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct QuadraticCrandallField([CrandallField; 2]);
|
||||
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::circuit_builder::CircuitBuilder;
|
||||
use crate::field::extension_field::algebra::ExtensionAlgebra;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension, OEF};
|
||||
use crate::field::field::Field;
|
||||
use crate::gates::mul_extension::MulExtensionGate;
|
||||
use crate::target::Target;
|
||||
use num::traits::real::Real;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::ops::Range;
|
||||
|
||||
/// `Target`s representing an element of an extension field.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
||||
@ -142,9 +142,10 @@ pub fn run_binaryop_test_cases<F, BinaryOp, ExpectedOp>(
|
||||
macro_rules! test_arithmetic {
|
||||
($field:ty) => {
|
||||
mod arithmetic {
|
||||
use crate::field::field::Field;
|
||||
use std::ops::{Add, Mul, Neg, Sub};
|
||||
|
||||
use crate::field::field::Field;
|
||||
|
||||
// Can be 32 or 64; doesn't have to be computer's actual word
|
||||
// bits. Choosing 32 gives more tests...
|
||||
const WORD_BITS: usize = 32;
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use anyhow::{ensure, Result};
|
||||
use itertools::izip;
|
||||
|
||||
use crate::field::extension_field::{flatten, Extendable, FieldExtension, Frobenius};
|
||||
use crate::field::field::Field;
|
||||
@ -155,31 +154,29 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
let mut sum = F::Extension::ZERO;
|
||||
|
||||
// We will add three terms to `sum`:
|
||||
// - one for polynomials opened at `x` only
|
||||
// - one for polynomials opened at `x` and `g x`
|
||||
// - one for polynomials opened at `x` and its conjugate
|
||||
// - one for various polynomials which are opened at a single point `x`
|
||||
// - one for Zs, which are opened at `x` and `g x`
|
||||
// - one for wire polynomials, which are opened at `x` and its conjugate
|
||||
|
||||
let evals = [0, 1, 4]
|
||||
let single_evals = [0, 1, 4]
|
||||
.iter()
|
||||
.flat_map(|&i| proof.unsalted_evals(i, config))
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
let openings = os
|
||||
let single_openings = os
|
||||
.constants
|
||||
.iter()
|
||||
.chain(&os.plonk_s_sigmas)
|
||||
.chain(&os.quotient_polys);
|
||||
let numerator = izip!(evals, openings, &mut alpha_powers)
|
||||
.map(|(e, &o, a)| a * (e - o))
|
||||
.sum::<F::Extension>();
|
||||
let denominator = subgroup_x - zeta;
|
||||
sum += numerator / denominator;
|
||||
let single_diffs = single_evals.zip(single_openings).map(|(e, &o)| e - o);
|
||||
let single_numerator = reduce_with_iter(single_diffs, &mut alpha_powers);
|
||||
let single_denominator = subgroup_x - zeta;
|
||||
sum += single_numerator / single_denominator;
|
||||
|
||||
let ev: F::Extension = proof
|
||||
let zs_evals = proof
|
||||
.unsalted_evals(3, config)
|
||||
.iter()
|
||||
.zip(alpha_powers.clone())
|
||||
.map(|(&e, a)| a * e.into())
|
||||
.sum();
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
let zs_composition_eval = reduce_with_iter(zs_evals, alpha_powers.clone());
|
||||
let zeta_right = F::Extension::primitive_root_of_unity(degree_log) * zeta;
|
||||
let zs_interpol = interpolant(&[
|
||||
(zeta, reduce_with_iter(&os.plonk_zs, alpha_powers.clone())),
|
||||
@ -188,22 +185,21 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
|
||||
reduce_with_iter(&os.plonk_zs_right, &mut alpha_powers),
|
||||
),
|
||||
]);
|
||||
let numerator = ev - zs_interpol.eval(subgroup_x);
|
||||
let denominator = (subgroup_x - zeta) * (subgroup_x - zeta_right);
|
||||
sum += numerator / denominator;
|
||||
let zs_numerator = zs_composition_eval - zs_interpol.eval(subgroup_x);
|
||||
let zs_denominator = (subgroup_x - zeta) * (subgroup_x - zeta_right);
|
||||
sum += zs_numerator / zs_denominator;
|
||||
|
||||
let ev: F::Extension = proof
|
||||
let wire_evals = proof
|
||||
.unsalted_evals(2, config)
|
||||
.iter()
|
||||
.zip(alpha_powers.clone())
|
||||
.map(|(&e, a)| a * e.into())
|
||||
.sum();
|
||||
.map(|&e| F::Extension::from_basefield(e));
|
||||
let wire_composition_eval = reduce_with_iter(wire_evals, alpha_powers.clone());
|
||||
let zeta_frob = zeta.frobenius();
|
||||
let wire_eval = reduce_with_iter(&os.wires, alpha_powers.clone());
|
||||
let alpha_powers_frob = alpha_powers.repeated_frobenius(D - 1);
|
||||
let wire_eval_frob = reduce_with_iter(&os.wires, alpha_powers_frob).frobenius();
|
||||
let wires_interpol = interpolant(&[(zeta, wire_eval), (zeta_frob, wire_eval_frob)]);
|
||||
let numerator = ev - wires_interpol.eval(subgroup_x);
|
||||
let numerator = wire_composition_eval - wires_interpol.eval(subgroup_x);
|
||||
let denominator = (subgroup_x - zeta) * (subgroup_x - zeta_frob);
|
||||
sum += numerator / denominator;
|
||||
|
||||
|
||||
@ -209,11 +209,9 @@ impl<F: Extendable<D>, const D: usize> SimpleGenerator<F> for InterpolationGener
|
||||
|
||||
let mut deps = Vec::new();
|
||||
deps.extend(local_targets(self.gate.wires_evaluation_point()));
|
||||
deps.extend(local_targets(self.gate.wires_evaluation_value()));
|
||||
for i in 0..self.gate.num_points {
|
||||
deps.push(local_target(self.gate.wire_point(i)));
|
||||
deps.extend(local_targets(self.gate.wires_value(i)));
|
||||
deps.extend(local_targets(self.gate.wires_coeff(i)));
|
||||
}
|
||||
deps
|
||||
}
|
||||
|
||||
@ -84,11 +84,10 @@ impl<F: Field> MerkleTree<F> {
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
|
||||
use super::*;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
use crate::merkle_proofs::verify_merkle_proof;
|
||||
|
||||
use super::*;
|
||||
|
||||
fn random_data<F: Field>(n: usize, k: usize) -> Vec<Vec<F>> {
|
||||
(0..n).map(|_| F::rand_vec(k)).collect()
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
use std::borrow::Borrow;
|
||||
|
||||
use crate::circuit_builder::CircuitBuilder;
|
||||
use crate::circuit_data::CommonCircuitData;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field::Field;
|
||||
use crate::gates::gate::GateRef;
|
||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||
use crate::target::Target;
|
||||
use crate::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase};
|
||||
|
||||
@ -214,13 +217,26 @@ pub(crate) fn reduce_with_powers_recursive<F: Extendable<D>, const D: usize>(
|
||||
sum
|
||||
}
|
||||
|
||||
pub(crate) fn reduce_with_iter<F: Field, I>(terms: &[F], coeffs: I) -> F
|
||||
where
|
||||
I: IntoIterator<Item = F>,
|
||||
{
|
||||
let mut sum = F::ZERO;
|
||||
for (&term, coeff) in terms.iter().zip(coeffs) {
|
||||
sum += coeff * term;
|
||||
}
|
||||
sum
|
||||
/// Reduce a sequence of field elements by the given coefficients.
|
||||
pub(crate) fn reduce_with_iter<F: Field>(
|
||||
terms: impl IntoIterator<Item = impl Borrow<F>>,
|
||||
coeffs: impl IntoIterator<Item = impl Borrow<F>>,
|
||||
) -> F {
|
||||
terms
|
||||
.into_iter()
|
||||
.zip(coeffs)
|
||||
.map(|(t, c)| *t.borrow() * *c.borrow())
|
||||
.sum()
|
||||
}
|
||||
|
||||
/// Reduce a sequence of polynomials by the given coefficients.
|
||||
pub(crate) fn reduce_polys_with_iter<F: Field>(
|
||||
polys: impl IntoIterator<Item = impl Borrow<PolynomialCoeffs<F>>>,
|
||||
coeffs: impl IntoIterator<Item = impl Borrow<F>>,
|
||||
) -> PolynomialCoeffs<F> {
|
||||
polys
|
||||
.into_iter()
|
||||
.zip(coeffs)
|
||||
.map(|(p, c)| p.borrow() * *c.borrow())
|
||||
.sum()
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::field::lagrange::interpolant;
|
||||
use crate::fri::{prover::fri_proof, verifier::verify_fri_proof, FriConfig};
|
||||
use crate::merkle_tree::MerkleTree;
|
||||
use crate::plonk_challenger::Challenger;
|
||||
use crate::plonk_common::reduce_with_powers;
|
||||
use crate::plonk_common::{reduce_polys_with_iter, reduce_with_iter};
|
||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||
use crate::proof::{FriProof, FriProofTarget, Hash, OpeningSet};
|
||||
use crate::timed;
|
||||
@ -90,7 +90,7 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
assert!(D > 1, "Not implemented for D=1.");
|
||||
let degree_log = log2_strict(commitments[0].degree);
|
||||
let g = F::Extension::primitive_root_of_unity(degree_log);
|
||||
for &p in &[zeta, g * zeta] {
|
||||
for p in &[zeta, g * zeta] {
|
||||
assert_ne!(
|
||||
p.exp(1 << degree_log as u64),
|
||||
F::Extension::ONE,
|
||||
@ -110,45 +110,34 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
challenger.observe_opening_set(&os);
|
||||
|
||||
let alpha = challenger.get_extension_challenge();
|
||||
let mut cur_alpha = F::Extension::ONE;
|
||||
let mut alpha_powers = alpha.powers();
|
||||
|
||||
// Final low-degree polynomial that goes into FRI.
|
||||
let mut final_poly = PolynomialCoeffs::empty();
|
||||
// Count the total number of polynomials accumulated into `final_poly`.
|
||||
let mut poly_count = 0;
|
||||
|
||||
// Polynomials opened at a single point.
|
||||
let composition_poly = [0, 1, 4]
|
||||
let single_polys = [0, 1, 4]
|
||||
.iter()
|
||||
.flat_map(|&i| &commitments[i].polynomials)
|
||||
.rev()
|
||||
.fold(PolynomialCoeffs::empty(), |acc, p| {
|
||||
poly_count += 1;
|
||||
&(&acc * alpha) + &p.to_extension()
|
||||
});
|
||||
let composition_eval = [&os.constants, &os.plonk_s_sigmas, &os.quotient_polys]
|
||||
.iter()
|
||||
.flat_map(|v| v.iter())
|
||||
.rev()
|
||||
.fold(F::Extension::ZERO, |acc, &e| acc * alpha + e);
|
||||
.map(|p| p.to_extension());
|
||||
let single_os = [&os.constants, &os.plonk_s_sigmas, &os.quotient_polys];
|
||||
let single_evals = single_os.iter().flat_map(|v| v.iter());
|
||||
let single_composition_poly = reduce_polys_with_iter(single_polys, alpha_powers.clone());
|
||||
let single_composition_eval = reduce_with_iter(single_evals, &mut alpha_powers);
|
||||
|
||||
let quotient = Self::compute_quotient(&[zeta], &[composition_eval], &composition_poly);
|
||||
final_poly = &final_poly + &("ient * cur_alpha);
|
||||
cur_alpha = alpha.exp(poly_count);
|
||||
let single_quotient = Self::compute_quotient(
|
||||
&[zeta],
|
||||
&[single_composition_eval],
|
||||
&single_composition_poly,
|
||||
);
|
||||
final_poly = &final_poly + &single_quotient;
|
||||
|
||||
// Zs polynomials are opened at `zeta` and `g*zeta`.
|
||||
let zs_composition_poly =
|
||||
commitments[3]
|
||||
.polynomials
|
||||
.iter()
|
||||
.rev()
|
||||
.fold(PolynomialCoeffs::empty(), |acc, p| {
|
||||
poly_count += 1;
|
||||
&(&acc * alpha) + &p.to_extension()
|
||||
});
|
||||
let zs_polys = commitments[3].polynomials.iter().map(|p| p.to_extension());
|
||||
let zs_composition_poly = reduce_polys_with_iter(zs_polys, alpha_powers.clone());
|
||||
let zs_composition_evals = [
|
||||
reduce_with_powers(&os.plonk_zs, alpha),
|
||||
reduce_with_powers(&os.plonk_zs_right, alpha),
|
||||
reduce_with_iter(&os.plonk_zs, alpha_powers.clone()),
|
||||
reduce_with_iter(&os.plonk_zs_right, &mut alpha_powers),
|
||||
];
|
||||
|
||||
let zs_quotient = Self::compute_quotient(
|
||||
@ -156,33 +145,25 @@ impl<F: Field> ListPolynomialCommitment<F> {
|
||||
&zs_composition_evals,
|
||||
&zs_composition_poly,
|
||||
);
|
||||
final_poly = &final_poly + &(&zs_quotient * cur_alpha);
|
||||
cur_alpha = alpha.exp(poly_count);
|
||||
final_poly = &final_poly + &zs_quotient;
|
||||
|
||||
// When working in an extension field, need to check that wires are in the base field.
|
||||
// Check this by opening the wires polynomials at `zeta` and `zeta.frobenius()` and using the fact that
|
||||
// a polynomial `f` is over the base field iff `f(z).frobenius()=f(z.frobenius())` with high probability.
|
||||
let wires_composition_poly =
|
||||
commitments[2]
|
||||
.polynomials
|
||||
.iter()
|
||||
.rev()
|
||||
.fold(PolynomialCoeffs::empty(), |acc, p| {
|
||||
poly_count += 1;
|
||||
&(&acc * alpha) + &p.to_extension()
|
||||
});
|
||||
let wire_polys = commitments[2].polynomials.iter().map(|p| p.to_extension());
|
||||
let wire_composition_poly = reduce_polys_with_iter(wire_polys, alpha_powers.clone());
|
||||
let wire_evals_frob = os.wires.iter().map(|e| e.frobenius()).collect::<Vec<_>>();
|
||||
let wires_composition_evals = [
|
||||
reduce_with_powers(&os.wires, alpha),
|
||||
reduce_with_powers(&wire_evals_frob, alpha),
|
||||
let wire_composition_evals = [
|
||||
reduce_with_iter(&os.wires, alpha_powers.clone()),
|
||||
reduce_with_iter(&wire_evals_frob, alpha_powers),
|
||||
];
|
||||
|
||||
let wires_quotient = Self::compute_quotient(
|
||||
&[zeta, zeta.frobenius()],
|
||||
&wires_composition_evals,
|
||||
&wires_composition_poly,
|
||||
&wire_composition_evals,
|
||||
&wire_composition_poly,
|
||||
);
|
||||
final_poly = &final_poly + &(&wires_quotient * cur_alpha);
|
||||
final_poly = &final_poly + &wires_quotient;
|
||||
|
||||
let lde_final_poly = final_poly.lde(config.rate_bits);
|
||||
let lde_final_values = lde_final_poly
|
||||
@ -279,9 +260,9 @@ pub struct OpeningProofTarget<const D: usize> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
use rand::Rng;
|
||||
|
||||
use super::*;
|
||||
use rand::Rng;
|
||||
|
||||
fn gen_random_test_case<F: Field + Extendable<D>, const D: usize>(
|
||||
k: usize,
|
||||
@ -365,6 +346,7 @@ mod tests {
|
||||
mod quadratic {
|
||||
use super::*;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
|
||||
#[test]
|
||||
fn test_batch_polynomial_commitment() -> Result<()> {
|
||||
check_batch_polynomial_commitment::<CrandallField, 2>()
|
||||
@ -374,6 +356,7 @@ mod tests {
|
||||
mod quartic {
|
||||
use super::*;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
|
||||
#[test]
|
||||
fn test_batch_polynomial_commitment() -> Result<()> {
|
||||
check_batch_polynomial_commitment::<CrandallField, 4>()
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use std::cmp::max;
|
||||
use std::iter::Sum;
|
||||
use std::ops::{Add, Mul, Sub};
|
||||
|
||||
use crate::field::extension_field::Extendable;
|
||||
@ -222,6 +223,12 @@ impl<F: Field> Add for &PolynomialCoeffs<F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Sum for PolynomialCoeffs<F> {
|
||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||
iter.fold(Self::empty(), |acc, p| &acc + &p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Sub for &PolynomialCoeffs<F> {
|
||||
type Output = PolynomialCoeffs<F>;
|
||||
|
||||
@ -272,9 +279,8 @@ mod tests {
|
||||
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
|
||||
use super::*;
|
||||
use crate::field::crandall_field::CrandallField;
|
||||
|
||||
#[test]
|
||||
fn test_trimmed() {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::Extendable;
|
||||
use crate::field::field::Field;
|
||||
@ -7,7 +9,6 @@ use crate::merkle_proofs::{MerkleProof, MerkleProofTarget};
|
||||
use crate::polynomial::commitment::{ListPolynomialCommitment, OpeningProof, OpeningProofTarget};
|
||||
use crate::polynomial::polynomial::PolynomialCoeffs;
|
||||
use crate::target::Target;
|
||||
use std::convert::TryInto;
|
||||
|
||||
/// Represents a ~256 bit hash output.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user