mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-05 15:23:06 +00:00
First try
This commit is contained in:
parent
c0ac79e2e1
commit
d54cc9a7c8
@ -24,6 +24,7 @@ pub mod packed_field;
|
||||
pub mod polynomial;
|
||||
pub mod secp256k1_base;
|
||||
pub mod secp256k1_scalar;
|
||||
pub mod zero_poly_coset;
|
||||
|
||||
#[cfg(test)]
|
||||
mod field_testing;
|
||||
|
||||
47
field/src/zero_poly_coset.rs
Normal file
47
field/src/zero_poly_coset.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use crate::field_types::Field;
|
||||
|
||||
/// Precomputations of the evaluation of `Z_H(X) = X^n - 1` on a coset `gK` with `H <= K`.
|
||||
pub struct ZeroPolyOnCoset<F: Field> {
|
||||
/// `n = |H|`.
|
||||
n: F,
|
||||
/// `rate = |K|/|H|`.
|
||||
rate: usize,
|
||||
/// Holds `g^n * (w^n)^i - 1 = g^n * v^i - 1` for `i in 0..rate`, with `w` a generator of `K` and `v` a
|
||||
/// `rate`-primitive root of unity.
|
||||
evals: Vec<F>,
|
||||
/// Holds the multiplicative inverses of `evals`.
|
||||
inverses: Vec<F>,
|
||||
}
|
||||
|
||||
impl<F: Field> ZeroPolyOnCoset<F> {
|
||||
pub fn new(n_log: usize, rate_bits: usize) -> Self {
|
||||
let g_pow_n = F::coset_shift().exp_power_of_2(n_log);
|
||||
let evals = F::two_adic_subgroup(rate_bits)
|
||||
.into_iter()
|
||||
.map(|x| g_pow_n * x - F::ONE)
|
||||
.collect::<Vec<_>>();
|
||||
let inverses = F::batch_multiplicative_inverse(&evals);
|
||||
Self {
|
||||
n: F::from_canonical_usize(1 << n_log),
|
||||
rate: 1 << rate_bits,
|
||||
evals,
|
||||
inverses,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Z_H(g * w^i)`.
|
||||
pub fn eval(&self, i: usize) -> F {
|
||||
self.evals[i % self.rate]
|
||||
}
|
||||
|
||||
/// Returns `1 / Z_H(g * w^i)`.
|
||||
pub fn eval_inverse(&self, i: usize) -> F {
|
||||
self.inverses[i % self.rate]
|
||||
}
|
||||
|
||||
/// Returns `L_1(x) = Z_H(x)/(n * (x - 1))` with `x = w^i`.
|
||||
pub fn eval_l1(&self, i: usize, x: F) -> F {
|
||||
// Could also precompute the inverses using Montgomery.
|
||||
self.eval(i) * (self.n * (x - F::ONE)).inverse()
|
||||
}
|
||||
}
|
||||
@ -63,52 +63,6 @@ pub(crate) fn eval_zero_poly<F: Field>(n: usize, x: F) -> F {
|
||||
x.exp_u64(n as u64) - F::ONE
|
||||
}
|
||||
|
||||
/// Precomputations of the evaluation of `Z_H(X) = X^n - 1` on a coset `gK` with `H <= K`.
|
||||
pub(crate) struct ZeroPolyOnCoset<F: Field> {
|
||||
/// `n = |H|`.
|
||||
n: F,
|
||||
/// `rate = |K|/|H|`.
|
||||
rate: usize,
|
||||
/// Holds `g^n * (w^n)^i - 1 = g^n * v^i - 1` for `i in 0..rate`, with `w` a generator of `K` and `v` a
|
||||
/// `rate`-primitive root of unity.
|
||||
evals: Vec<F>,
|
||||
/// Holds the multiplicative inverses of `evals`.
|
||||
inverses: Vec<F>,
|
||||
}
|
||||
|
||||
impl<F: Field> ZeroPolyOnCoset<F> {
|
||||
pub fn new(n_log: usize, rate_bits: usize) -> Self {
|
||||
let g_pow_n = F::coset_shift().exp_power_of_2(n_log);
|
||||
let evals = F::two_adic_subgroup(rate_bits)
|
||||
.into_iter()
|
||||
.map(|x| g_pow_n * x - F::ONE)
|
||||
.collect::<Vec<_>>();
|
||||
let inverses = F::batch_multiplicative_inverse(&evals);
|
||||
Self {
|
||||
n: F::from_canonical_usize(1 << n_log),
|
||||
rate: 1 << rate_bits,
|
||||
evals,
|
||||
inverses,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Z_H(g * w^i)`.
|
||||
pub fn eval(&self, i: usize) -> F {
|
||||
self.evals[i % self.rate]
|
||||
}
|
||||
|
||||
/// Returns `1 / Z_H(g * w^i)`.
|
||||
pub fn eval_inverse(&self, i: usize) -> F {
|
||||
self.inverses[i % self.rate]
|
||||
}
|
||||
|
||||
/// Returns `L_1(x) = Z_H(x)/(n * (x - 1))` with `x = w^i`.
|
||||
pub fn eval_l1(&self, i: usize, x: F) -> F {
|
||||
// Could also precompute the inverses using Montgomery.
|
||||
self.eval(i) * (self.n * (x - F::ONE)).inverse()
|
||||
}
|
||||
}
|
||||
|
||||
/// Evaluate the Lagrange basis `L_1` with `L_1(1) = 1`, and `L_1(x) = 0` for other members of an
|
||||
/// order `n` multiplicative subgroup.
|
||||
pub(crate) fn eval_l_1<F: Field>(n: usize, x: F) -> F {
|
||||
|
||||
@ -4,6 +4,7 @@ use anyhow::ensure;
|
||||
use anyhow::Result;
|
||||
use plonky2_field::extension_field::Extendable;
|
||||
use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues};
|
||||
use plonky2_field::zero_poly_coset::ZeroPolyOnCoset;
|
||||
use plonky2_util::log2_ceil;
|
||||
use rayon::prelude::*;
|
||||
|
||||
@ -15,7 +16,7 @@ use crate::iop::generator::generate_partial_witness;
|
||||
use crate::iop::witness::{MatrixWitness, PartialWitness, Witness};
|
||||
use crate::plonk::circuit_data::{CommonCircuitData, ProverOnlyCircuitData};
|
||||
use crate::plonk::config::{GenericConfig, Hasher};
|
||||
use crate::plonk::plonk_common::{PlonkOracle, ZeroPolyOnCoset};
|
||||
use crate::plonk::plonk_common::PlonkOracle;
|
||||
use crate::plonk::proof::OpeningSet;
|
||||
use crate::plonk::proof::{Proof, ProofWithPublicInputs};
|
||||
use crate::plonk::vanishing_poly::eval_vanishing_poly_base_batch;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use plonky2_field::batch_util::batch_add_inplace;
|
||||
use plonky2_field::extension_field::{Extendable, FieldExtension};
|
||||
use plonky2_field::field_types::Field;
|
||||
use plonky2_field::zero_poly_coset::ZeroPolyOnCoset;
|
||||
|
||||
use crate::gates::gate::PrefixedGate;
|
||||
use crate::hash::hash_types::RichField;
|
||||
@ -10,7 +11,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CommonCircuitData;
|
||||
use crate::plonk::config::GenericConfig;
|
||||
use crate::plonk::plonk_common;
|
||||
use crate::plonk::plonk_common::{eval_l_1_recursively, ZeroPolyOnCoset};
|
||||
use crate::plonk::plonk_common::eval_l_1_recursively;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch};
|
||||
use crate::util::partial_products::{check_partial_products, check_partial_products_recursively};
|
||||
use crate::util::reducing::ReducingFactorTarget;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use plonky2::field::extension_field::Extendable;
|
||||
use plonky2::field::field_types::Field;
|
||||
use plonky2::field::packed_field::PackedField;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::ext_target::ExtensionTarget;
|
||||
@ -24,6 +25,24 @@ pub struct ConstraintConsumer<P: PackedField> {
|
||||
}
|
||||
|
||||
impl<P: PackedField> ConstraintConsumer<P> {
|
||||
pub fn new(
|
||||
alpha: P::Scalar,
|
||||
lagrange_basis_first: P::Scalar,
|
||||
lagrange_basis_last: P::Scalar,
|
||||
) -> Self {
|
||||
Self {
|
||||
alpha,
|
||||
constraint_acc: P::ZEROS,
|
||||
lagrange_basis_first,
|
||||
lagrange_basis_last,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Do this correctly.
|
||||
pub fn accumulator(&self) -> P::Scalar {
|
||||
self.constraint_acc.as_slice()[0]
|
||||
}
|
||||
|
||||
/// Add one constraint.
|
||||
pub fn one(&mut self, constraint: P) {
|
||||
self.constraint_acc *= self.alpha;
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use itertools::Itertools;
|
||||
use plonky2::field::extension_field::Extendable;
|
||||
use plonky2::field::polynomial::PolynomialValues;
|
||||
use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues};
|
||||
use plonky2::field::zero_poly_coset::ZeroPolyOnCoset;
|
||||
use plonky2::fri::oracle::PolynomialBatch;
|
||||
use plonky2::fri::prover::fri_proof;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::challenger::Challenger;
|
||||
use plonky2::plonk::circuit_data::CommonCircuitData;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use plonky2::timed;
|
||||
use plonky2::util::timing::TimingTree;
|
||||
@ -13,8 +15,10 @@ use plonky2_util::log2_strict;
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::constraint_consumer::ConstraintConsumer;
|
||||
use crate::proof::StarkProof;
|
||||
use crate::stark::Stark;
|
||||
use crate::vars::StarkEvaluationVars;
|
||||
|
||||
pub fn prove<F, C, S, const D: usize>(
|
||||
stark: S,
|
||||
@ -27,6 +31,7 @@ where
|
||||
C: GenericConfig<D, F = F>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let degree_bits = log2_strict(trace.len());
|
||||
|
||||
@ -57,13 +62,23 @@ where
|
||||
)
|
||||
);
|
||||
|
||||
let trace_cap = trace_commitment.merkle_tree.cap;
|
||||
let trace_cap = trace_commitment.merkle_tree.cap.clone();
|
||||
let mut challenger = Challenger::new();
|
||||
challenger.observe_cap(&trace_cap);
|
||||
|
||||
let alphas = challenger.get_n_challenges(config.num_challenges);
|
||||
let quotient = compute_quotient_polys::<F, C, S, D>(
|
||||
&stark,
|
||||
&trace_commitment,
|
||||
&alphas,
|
||||
degree_bits,
|
||||
rate_bits,
|
||||
);
|
||||
let openings = todo!();
|
||||
|
||||
let initial_merkle_trees = todo!();
|
||||
let lde_polynomial_coeffs = todo!();
|
||||
let lde_polynomial_values = todo!();
|
||||
let mut challenger = Challenger::new();
|
||||
let fri_params = config.fri_params(degree_bits);
|
||||
|
||||
let opening_proof = fri_proof::<F, C, D>(
|
||||
@ -81,3 +96,69 @@ where
|
||||
opening_proof,
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_quotient_polys<F, C, S, const D: usize>(
|
||||
stark: &S,
|
||||
trace_commitment: &PolynomialBatch<F, C, D>,
|
||||
alphas: &[F],
|
||||
degree_bits: usize,
|
||||
rate_bits: usize,
|
||||
) -> Vec<PolynomialCoeffs<F>>
|
||||
where
|
||||
F: RichField + Extendable<D>,
|
||||
C: GenericConfig<D, F = F>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let degree = 1 << degree_bits;
|
||||
let points = F::two_adic_subgroup(degree_bits + rate_bits);
|
||||
|
||||
let lagrange_first = {
|
||||
let mut evals = PolynomialValues::new(vec![F::ZERO; degree]);
|
||||
evals.values[0] = F::ONE;
|
||||
evals.lde(rate_bits)
|
||||
};
|
||||
let lagrange_last = {
|
||||
let mut evals = PolynomialValues::new(vec![F::ZERO; degree]);
|
||||
evals.values[degree - 1] = F::ONE;
|
||||
evals.lde(rate_bits)
|
||||
};
|
||||
|
||||
let z_h_on_coset = ZeroPolyOnCoset::new(degree_bits, rate_bits);
|
||||
|
||||
alphas
|
||||
.iter()
|
||||
.map(|&alpha| {
|
||||
let quotient_evals = PolynomialValues::new(
|
||||
(0..degree << rate_bits)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let mut consumer = ConstraintConsumer::<F>::new(
|
||||
alpha,
|
||||
lagrange_first.values[i],
|
||||
lagrange_last.values[i],
|
||||
);
|
||||
let vars =
|
||||
StarkEvaluationVars::<F, F, { S::COLUMNS }, { S::PUBLIC_INPUTS }> {
|
||||
local_values: trace_commitment
|
||||
.get_lde_values(i)
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
next_values: trace_commitment
|
||||
.get_lde_values((i + 1) % (degree << rate_bits))
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
public_inputs: &[F::ZERO; S::PUBLIC_INPUTS],
|
||||
};
|
||||
stark.eval_packed_base(vars, &mut consumer);
|
||||
let constraints_eval = consumer.accumulator();
|
||||
let denominator_inv = z_h_on_coset.eval_inverse(i);
|
||||
constraints_eval * denominator_inv
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
quotient_evals.coset_ifft(F::coset_shift())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::vars::StarkEvaluationTargets;
|
||||
use crate::vars::StarkEvaluationVars;
|
||||
|
||||
/// Represents a STARK system.
|
||||
pub trait Stark<F: RichField + Extendable<D>, const D: usize> {
|
||||
pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
|
||||
/// The total number of columns in the trace.
|
||||
const COLUMNS: usize;
|
||||
/// The number of public inputs.
|
||||
|
||||
@ -11,6 +11,7 @@ use std::mem::size_of;
|
||||
use std::ptr::{swap, swap_nonoverlapping};
|
||||
|
||||
mod transpose_util;
|
||||
|
||||
use crate::transpose_util::transpose_in_place_square;
|
||||
|
||||
pub fn bits_u64(n: u64) -> usize {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user