mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 06:13:07 +00:00
refactor: remove usage of unstable generic_const_exprs in starky (#1300)
This commit is contained in:
parent
8af189b927
commit
8326db604c
67
starky/src/evaluation_frame.rs
Normal file
67
starky/src/evaluation_frame.rs
Normal file
@ -0,0 +1,67 @@
|
||||
/// A trait for viewing an evaluation frame of a STARK table.
|
||||
///
|
||||
/// It allows to access the current and next rows at a given step
|
||||
/// and can be used to implement constraint evaluation both natively
|
||||
/// and recursively.
|
||||
pub trait StarkEvaluationFrame<T: Copy + Clone + Default, U: Copy + Clone + Default>:
|
||||
Sized
|
||||
{
|
||||
/// The number of columns for the STARK table this evaluation frame views.
|
||||
const COLUMNS: usize;
|
||||
const PUBLIC_INPUTS: usize;
|
||||
|
||||
/// Returns the local values (i.e. current row) for this evaluation frame.
|
||||
fn get_local_values(&self) -> &[T];
|
||||
/// Returns the next values (i.e. next row) for this evaluation frame.
|
||||
fn get_next_values(&self) -> &[T];
|
||||
|
||||
fn get_public_inputs(&self) -> &[U];
|
||||
|
||||
/// Outputs a new evaluation frame from the provided local and next values.
|
||||
///
|
||||
/// **NOTE**: Concrete implementations of this method SHOULD ensure that
|
||||
/// the provided slices lengths match the `Self::COLUMNS` value.
|
||||
fn from_values(lv: &[T], nv: &[T], pis: &[U]) -> Self;
|
||||
}
|
||||
|
||||
pub struct StarkFrame<
|
||||
T: Copy + Clone + Default,
|
||||
U: Copy + Clone + Default,
|
||||
const N: usize,
|
||||
const N2: usize,
|
||||
> {
|
||||
local_values: [T; N],
|
||||
next_values: [T; N],
|
||||
public_inputs: [U; N2],
|
||||
}
|
||||
|
||||
impl<T: Copy + Clone + Default, U: Copy + Clone + Default, const N: usize, const N2: usize>
|
||||
StarkEvaluationFrame<T, U> for StarkFrame<T, U, N, N2>
|
||||
{
|
||||
const COLUMNS: usize = N;
|
||||
const PUBLIC_INPUTS: usize = N2;
|
||||
|
||||
fn get_local_values(&self) -> &[T] {
|
||||
&self.local_values
|
||||
}
|
||||
|
||||
fn get_next_values(&self) -> &[T] {
|
||||
&self.next_values
|
||||
}
|
||||
|
||||
fn get_public_inputs(&self) -> &[U] {
|
||||
&self.public_inputs
|
||||
}
|
||||
|
||||
fn from_values(lv: &[T], nv: &[T], pis: &[U]) -> Self {
|
||||
assert_eq!(lv.len(), Self::COLUMNS);
|
||||
assert_eq!(nv.len(), Self::COLUMNS);
|
||||
assert_eq!(pis.len(), Self::PUBLIC_INPUTS);
|
||||
|
||||
Self {
|
||||
local_values: lv.try_into().unwrap(),
|
||||
next_values: nv.try_into().unwrap(),
|
||||
public_inputs: pis.try_into().unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,13 +6,14 @@ use plonky2::field::extension::{Extendable, FieldExtension};
|
||||
use plonky2::field::packed::PackedField;
|
||||
use plonky2::field::polynomial::PolynomialValues;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::ext_target::ExtensionTarget;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::evaluation_frame::{StarkEvaluationFrame, StarkFrame};
|
||||
use crate::permutation::PermutationPair;
|
||||
use crate::stark::Stark;
|
||||
use crate::util::trace_rows_to_poly_values;
|
||||
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
|
||||
|
||||
/// Toy STARK system used for testing.
|
||||
/// Computes a Fibonacci sequence with state `[x0, x1, i, j]` using the state transition
|
||||
@ -57,57 +58,67 @@ impl<F: RichField + Extendable<D>, const D: usize> FibonacciStark<F, D> {
|
||||
}
|
||||
}
|
||||
|
||||
const COLUMNS: usize = 4;
|
||||
const PUBLIC_INPUTS: usize = 3;
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for FibonacciStark<F, D> {
|
||||
const COLUMNS: usize = 4;
|
||||
const PUBLIC_INPUTS: usize = 3;
|
||||
type EvaluationFrame<FE, P, const D2: usize> = StarkFrame<P, P::Scalar, COLUMNS, PUBLIC_INPUTS>
|
||||
where
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
P: PackedField<Scalar = FE>;
|
||||
|
||||
type EvaluationFrameTarget =
|
||||
StarkFrame<ExtensionTarget<D>, ExtensionTarget<D>, COLUMNS, PUBLIC_INPUTS>;
|
||||
|
||||
fn eval_packed_generic<FE, P, const D2: usize>(
|
||||
&self,
|
||||
vars: StarkEvaluationVars<FE, P, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
|
||||
vars: &Self::EvaluationFrame<FE, P, D2>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) where
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
P: PackedField<Scalar = FE>,
|
||||
{
|
||||
let local_values = vars.get_local_values();
|
||||
let next_values = vars.get_next_values();
|
||||
let public_inputs = vars.get_public_inputs();
|
||||
|
||||
// Check public inputs.
|
||||
yield_constr
|
||||
.constraint_first_row(vars.local_values[0] - vars.public_inputs[Self::PI_INDEX_X0]);
|
||||
yield_constr
|
||||
.constraint_first_row(vars.local_values[1] - vars.public_inputs[Self::PI_INDEX_X1]);
|
||||
yield_constr
|
||||
.constraint_last_row(vars.local_values[1] - vars.public_inputs[Self::PI_INDEX_RES]);
|
||||
yield_constr.constraint_first_row(local_values[0] - public_inputs[Self::PI_INDEX_X0]);
|
||||
yield_constr.constraint_first_row(local_values[1] - public_inputs[Self::PI_INDEX_X1]);
|
||||
yield_constr.constraint_last_row(local_values[1] - public_inputs[Self::PI_INDEX_RES]);
|
||||
|
||||
// x0' <- x1
|
||||
yield_constr.constraint_transition(vars.next_values[0] - vars.local_values[1]);
|
||||
yield_constr.constraint_transition(next_values[0] - local_values[1]);
|
||||
// x1' <- x0 + x1
|
||||
yield_constr.constraint_transition(
|
||||
vars.next_values[1] - vars.local_values[0] - vars.local_values[1],
|
||||
);
|
||||
yield_constr.constraint_transition(next_values[1] - local_values[0] - local_values[1]);
|
||||
}
|
||||
|
||||
fn eval_ext_circuit(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
vars: StarkEvaluationTargets<D, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
|
||||
vars: &Self::EvaluationFrameTarget,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) {
|
||||
let local_values = vars.get_local_values();
|
||||
let next_values = vars.get_next_values();
|
||||
let public_inputs = vars.get_public_inputs();
|
||||
// Check public inputs.
|
||||
let pis_constraints = [
|
||||
builder.sub_extension(vars.local_values[0], vars.public_inputs[Self::PI_INDEX_X0]),
|
||||
builder.sub_extension(vars.local_values[1], vars.public_inputs[Self::PI_INDEX_X1]),
|
||||
builder.sub_extension(vars.local_values[1], vars.public_inputs[Self::PI_INDEX_RES]),
|
||||
builder.sub_extension(local_values[0], public_inputs[Self::PI_INDEX_X0]),
|
||||
builder.sub_extension(local_values[1], public_inputs[Self::PI_INDEX_X1]),
|
||||
builder.sub_extension(local_values[1], public_inputs[Self::PI_INDEX_RES]),
|
||||
];
|
||||
yield_constr.constraint_first_row(builder, pis_constraints[0]);
|
||||
yield_constr.constraint_first_row(builder, pis_constraints[1]);
|
||||
yield_constr.constraint_last_row(builder, pis_constraints[2]);
|
||||
|
||||
// x0' <- x1
|
||||
let first_col_constraint = builder.sub_extension(vars.next_values[0], vars.local_values[1]);
|
||||
let first_col_constraint = builder.sub_extension(next_values[0], local_values[1]);
|
||||
yield_constr.constraint_transition(builder, first_col_constraint);
|
||||
// x1' <- x0 + x1
|
||||
let second_col_constraint = {
|
||||
let tmp = builder.sub_extension(vars.next_values[1], vars.local_values[0]);
|
||||
builder.sub_extension(tmp, vars.local_values[1])
|
||||
let tmp = builder.sub_extension(next_values[1], local_values[0]);
|
||||
builder.sub_extension(tmp, local_values[1])
|
||||
};
|
||||
yield_constr.constraint_transition(builder, second_col_constraint);
|
||||
}
|
||||
@ -165,7 +176,7 @@ mod tests {
|
||||
stark,
|
||||
&config,
|
||||
trace,
|
||||
public_inputs,
|
||||
&public_inputs,
|
||||
&mut TimingTree::default(),
|
||||
)?;
|
||||
|
||||
@ -213,7 +224,7 @@ mod tests {
|
||||
stark,
|
||||
&config,
|
||||
trace,
|
||||
public_inputs,
|
||||
&public_inputs,
|
||||
&mut TimingTree::default(),
|
||||
)?;
|
||||
verify_stark_proof(stark, proof.clone(), &config)?;
|
||||
@ -235,8 +246,6 @@ mod tests {
|
||||
) -> Result<()>
|
||||
where
|
||||
InnerC::Hasher: AlgebraicHasher<F>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let circuit_config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(circuit_config);
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
#![feature(generic_const_exprs)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
extern crate alloc;
|
||||
@ -10,6 +8,7 @@ mod get_challenges;
|
||||
|
||||
pub mod config;
|
||||
pub mod constraint_consumer;
|
||||
pub mod evaluation_frame;
|
||||
pub mod permutation;
|
||||
pub mod proof;
|
||||
pub mod prover;
|
||||
@ -18,7 +17,6 @@ pub mod stark;
|
||||
pub mod stark_testing;
|
||||
pub mod util;
|
||||
pub mod vanishing_poly;
|
||||
pub mod vars;
|
||||
pub mod verifier;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -20,8 +20,8 @@ use plonky2_maybe_rayon::*;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::evaluation_frame::StarkEvaluationFrame;
|
||||
use crate::stark::Stark;
|
||||
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
|
||||
|
||||
/// A pair of lists of columns, `lhs` and `rhs`, that should be permutations of one another.
|
||||
/// In particular, there should exist some permutation `pi` such that for any `i`,
|
||||
@ -262,7 +262,7 @@ where
|
||||
pub(crate) fn eval_permutation_checks<F, FE, P, S, const D: usize, const D2: usize>(
|
||||
stark: &S,
|
||||
config: &StarkConfig,
|
||||
vars: StarkEvaluationVars<FE, P, { S::COLUMNS }, { S::PUBLIC_INPUTS }>,
|
||||
vars: &S::EvaluationFrame<FE, P, D2>,
|
||||
permutation_data: PermutationCheckVars<F, FE, P, D2>,
|
||||
consumer: &mut ConstraintConsumer<P>,
|
||||
) where
|
||||
@ -270,9 +270,9 @@ pub(crate) fn eval_permutation_checks<F, FE, P, S, const D: usize, const D2: usi
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
P: PackedField<Scalar = FE>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let local_values = vars.get_local_values();
|
||||
|
||||
let PermutationCheckVars {
|
||||
local_zs,
|
||||
next_zs,
|
||||
@ -306,7 +306,7 @@ pub(crate) fn eval_permutation_checks<F, FE, P, S, const D: usize, const D2: usi
|
||||
let mut factor = ReducingFactor::new(*beta);
|
||||
let (lhs, rhs): (Vec<_>, Vec<_>) = column_pairs
|
||||
.iter()
|
||||
.map(|&(i, j)| (vars.local_values[i], vars.local_values[j]))
|
||||
.map(|&(i, j)| (local_values[i], local_values[j]))
|
||||
.unzip();
|
||||
(
|
||||
factor.reduce_ext(lhs.into_iter()) + FE::from_basefield(*gamma),
|
||||
@ -330,15 +330,15 @@ pub(crate) fn eval_permutation_checks_circuit<F, S, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
stark: &S,
|
||||
config: &StarkConfig,
|
||||
vars: StarkEvaluationTargets<D, { S::COLUMNS }, { S::PUBLIC_INPUTS }>,
|
||||
vars: &S::EvaluationFrameTarget,
|
||||
permutation_data: PermutationCheckDataTarget<D>,
|
||||
consumer: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) where
|
||||
F: RichField + Extendable<D>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let local_values = vars.get_local_values();
|
||||
|
||||
let PermutationCheckDataTarget {
|
||||
local_zs,
|
||||
next_zs,
|
||||
@ -376,7 +376,7 @@ pub(crate) fn eval_permutation_checks_circuit<F, S, const D: usize>(
|
||||
let mut factor = ReducingFactorTarget::new(beta_ext);
|
||||
let (lhs, rhs): (Vec<_>, Vec<_>) = column_pairs
|
||||
.iter()
|
||||
.map(|&(i, j)| (vars.local_values[i], vars.local_values[j]))
|
||||
.map(|&(i, j)| (local_values[i], local_values[j]))
|
||||
.unzip();
|
||||
let reduced_lhs = factor.reduce(&lhs, builder);
|
||||
let reduced_rhs = factor.reduce(&rhs, builder);
|
||||
|
||||
@ -20,6 +20,7 @@ use plonky2_maybe_rayon::*;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::constraint_consumer::ConstraintConsumer;
|
||||
use crate::evaluation_frame::StarkEvaluationFrame;
|
||||
use crate::permutation::{
|
||||
compute_permutation_z_polys, get_n_permutation_challenge_sets, PermutationChallengeSet,
|
||||
PermutationCheckVars,
|
||||
@ -27,21 +28,18 @@ use crate::permutation::{
|
||||
use crate::proof::{StarkOpeningSet, StarkProof, StarkProofWithPublicInputs};
|
||||
use crate::stark::Stark;
|
||||
use crate::vanishing_poly::eval_vanishing_poly;
|
||||
use crate::vars::StarkEvaluationVars;
|
||||
|
||||
pub fn prove<F, C, S, const D: usize>(
|
||||
stark: S,
|
||||
config: &StarkConfig,
|
||||
trace_poly_values: Vec<PolynomialValues<F>>,
|
||||
public_inputs: [F; S::PUBLIC_INPUTS],
|
||||
public_inputs: &[F],
|
||||
timing: &mut TimingTree,
|
||||
) -> Result<StarkProofWithPublicInputs<F, C, D>>
|
||||
where
|
||||
F: RichField + Extendable<D>,
|
||||
C: GenericConfig<D, F = F>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let degree = trace_poly_values[0].len();
|
||||
let degree_bits = log2_strict(degree);
|
||||
@ -202,7 +200,7 @@ fn compute_quotient_polys<'a, F, P, C, S, const D: usize>(
|
||||
PolynomialBatch<F, C, D>,
|
||||
Vec<PermutationChallengeSet<F>>,
|
||||
)>,
|
||||
public_inputs: [F; S::PUBLIC_INPUTS],
|
||||
public_inputs: &[F],
|
||||
alphas: Vec<F>,
|
||||
degree_bits: usize,
|
||||
config: &StarkConfig,
|
||||
@ -212,8 +210,6 @@ where
|
||||
P: PackedField<Scalar = F>,
|
||||
C: GenericConfig<D, F = F>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
let degree = 1 << degree_bits;
|
||||
let rate_bits = config.fri_config.rate_bits;
|
||||
@ -236,12 +232,8 @@ where
|
||||
let z_h_on_coset = ZeroPolyOnCoset::<F>::new(degree_bits, quotient_degree_bits);
|
||||
|
||||
// Retrieve the LDE values at index `i`.
|
||||
let get_trace_values_packed = |i_start| -> [P; S::COLUMNS] {
|
||||
trace_commitment
|
||||
.get_lde_values_packed(i_start, step)
|
||||
.try_into()
|
||||
.unwrap()
|
||||
};
|
||||
let get_trace_values_packed =
|
||||
|i_start| -> Vec<P> { trace_commitment.get_lde_values_packed(i_start, step) };
|
||||
|
||||
// Last element of the subgroup.
|
||||
let last = F::primitive_root_of_unity(degree_bits).inverse();
|
||||
@ -272,11 +264,11 @@ where
|
||||
lagrange_basis_first,
|
||||
lagrange_basis_last,
|
||||
);
|
||||
let vars = StarkEvaluationVars {
|
||||
local_values: &get_trace_values_packed(i_start),
|
||||
next_values: &get_trace_values_packed(i_next_start),
|
||||
public_inputs: &public_inputs,
|
||||
};
|
||||
let vars = S::EvaluationFrame::from_values(
|
||||
&get_trace_values_packed(i_start),
|
||||
&get_trace_values_packed(i_next_start),
|
||||
public_inputs,
|
||||
);
|
||||
let permutation_check_data = permutation_zs_commitment_challenges.as_ref().map(
|
||||
|(permutation_zs_commitment, permutation_challenge_sets)| PermutationCheckVars {
|
||||
local_zs: permutation_zs_commitment.get_lde_values_packed(i_start, step),
|
||||
@ -287,7 +279,7 @@ where
|
||||
eval_vanishing_poly::<F, F, P, S, D, 1>(
|
||||
stark,
|
||||
config,
|
||||
vars,
|
||||
&vars,
|
||||
permutation_check_data,
|
||||
&mut consumer,
|
||||
);
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::iter::once;
|
||||
|
||||
use anyhow::{ensure, Result};
|
||||
@ -16,6 +15,7 @@ use plonky2::with_context;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::constraint_consumer::RecursiveConstraintConsumer;
|
||||
use crate::evaluation_frame::StarkEvaluationFrame;
|
||||
use crate::permutation::PermutationCheckDataTarget;
|
||||
use crate::proof::{
|
||||
StarkOpeningSetTarget, StarkProof, StarkProofChallengesTarget, StarkProofTarget,
|
||||
@ -23,7 +23,6 @@ use crate::proof::{
|
||||
};
|
||||
use crate::stark::Stark;
|
||||
use crate::vanishing_poly::eval_vanishing_poly_circuit;
|
||||
use crate::vars::StarkEvaluationTargets;
|
||||
|
||||
pub fn verify_stark_proof_circuit<
|
||||
F: RichField + Extendable<D>,
|
||||
@ -37,8 +36,6 @@ pub fn verify_stark_proof_circuit<
|
||||
inner_config: &StarkConfig,
|
||||
) where
|
||||
C::Hasher: AlgebraicHasher<F>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
assert_eq!(proof_with_pis.public_inputs.len(), S::PUBLIC_INPUTS);
|
||||
let degree_bits = proof_with_pis.proof.recover_degree_bits(inner_config);
|
||||
@ -73,8 +70,6 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
degree_bits: usize,
|
||||
) where
|
||||
C::Hasher: AlgebraicHasher<F>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
check_permutation_options(&stark, &proof_with_pis, &challenges).unwrap();
|
||||
let one = builder.one_extension();
|
||||
@ -90,16 +85,15 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
permutation_zs_next,
|
||||
quotient_polys,
|
||||
} = &proof.openings;
|
||||
let vars = StarkEvaluationTargets {
|
||||
local_values: &local_values.to_vec().try_into().unwrap(),
|
||||
next_values: &next_values.to_vec().try_into().unwrap(),
|
||||
public_inputs: &public_inputs
|
||||
|
||||
let vars = S::EvaluationFrameTarget::from_values(
|
||||
local_values,
|
||||
next_values,
|
||||
&public_inputs
|
||||
.into_iter()
|
||||
.map(|t| builder.convert_to_ext(t))
|
||||
.collect::<Vec<_>>()
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
};
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let zeta_pow_deg = builder.exp_power_of_2_extension(challenges.stark_zeta, degree_bits);
|
||||
let z_h_zeta = builder.sub_extension(zeta_pow_deg, one);
|
||||
@ -132,7 +126,7 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
builder,
|
||||
&stark,
|
||||
inner_config,
|
||||
vars,
|
||||
&vars,
|
||||
permutation_data,
|
||||
&mut consumer,
|
||||
)
|
||||
|
||||
@ -14,15 +14,23 @@ use plonky2::util::ceil_div_usize;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::evaluation_frame::StarkEvaluationFrame;
|
||||
use crate::permutation::PermutationPair;
|
||||
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
|
||||
|
||||
/// Represents a STARK system.
|
||||
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.
|
||||
const PUBLIC_INPUTS: usize;
|
||||
const COLUMNS: usize = Self::EvaluationFrameTarget::COLUMNS;
|
||||
const PUBLIC_INPUTS: usize = Self::EvaluationFrameTarget::PUBLIC_INPUTS;
|
||||
|
||||
/// This is used to evaluate constraints natively.
|
||||
type EvaluationFrame<FE, P, const D2: usize>: StarkEvaluationFrame<P, FE>
|
||||
where
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
P: PackedField<Scalar = FE>;
|
||||
|
||||
/// The `Target` version of `Self::EvaluationFrame`, used to evaluate constraints recursively.
|
||||
type EvaluationFrameTarget: StarkEvaluationFrame<ExtensionTarget<D>, ExtensionTarget<D>>;
|
||||
|
||||
/// Evaluate constraints at a vector of points.
|
||||
///
|
||||
@ -32,7 +40,7 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
|
||||
/// constraints over `F`.
|
||||
fn eval_packed_generic<FE, P, const D2: usize>(
|
||||
&self,
|
||||
vars: StarkEvaluationVars<FE, P, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
|
||||
vars: &Self::EvaluationFrame<FE, P, D2>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) where
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
@ -41,7 +49,7 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
|
||||
/// Evaluate constraints at a vector of points from the base field `F`.
|
||||
fn eval_packed_base<P: PackedField<Scalar = F>>(
|
||||
&self,
|
||||
vars: StarkEvaluationVars<F, P, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
|
||||
vars: &Self::EvaluationFrame<F, P, 1>,
|
||||
yield_constr: &mut ConstraintConsumer<P>,
|
||||
) {
|
||||
self.eval_packed_generic(vars, yield_constr)
|
||||
@ -50,12 +58,7 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
|
||||
/// Evaluate constraints at a single point from the degree `D` extension field.
|
||||
fn eval_ext(
|
||||
&self,
|
||||
vars: StarkEvaluationVars<
|
||||
F::Extension,
|
||||
F::Extension,
|
||||
{ Self::COLUMNS },
|
||||
{ Self::PUBLIC_INPUTS },
|
||||
>,
|
||||
vars: &Self::EvaluationFrame<F::Extension, F::Extension, D>,
|
||||
yield_constr: &mut ConstraintConsumer<F::Extension>,
|
||||
) {
|
||||
self.eval_packed_generic(vars, yield_constr)
|
||||
@ -68,7 +71,7 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
|
||||
fn eval_ext_circuit(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
vars: StarkEvaluationTargets<D, { Self::COLUMNS }, { Self::PUBLIC_INPUTS }>,
|
||||
vars: &Self::EvaluationFrameTarget,
|
||||
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
|
||||
);
|
||||
|
||||
|
||||
@ -13,8 +13,8 @@ use plonky2::plonk::config::GenericConfig;
|
||||
use plonky2::util::{log2_ceil, log2_strict, transpose};
|
||||
|
||||
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
|
||||
use crate::evaluation_frame::StarkEvaluationFrame;
|
||||
use crate::stark::Stark;
|
||||
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
|
||||
|
||||
const WITNESS_SIZE: usize = 1 << 5;
|
||||
|
||||
@ -22,16 +22,12 @@ const WITNESS_SIZE: usize = 1 << 5;
|
||||
/// low-degree witness polynomials.
|
||||
pub fn test_stark_low_degree<F: RichField + Extendable<D>, S: Stark<F, D>, const D: usize>(
|
||||
stark: S,
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
) -> Result<()> {
|
||||
let rate_bits = log2_ceil(stark.constraint_degree() + 1);
|
||||
|
||||
let trace_ldes = random_low_degree_matrix::<F>(S::COLUMNS, rate_bits);
|
||||
let size = trace_ldes.len();
|
||||
let public_inputs = F::rand_array::<{ S::PUBLIC_INPUTS }>();
|
||||
let public_inputs = F::rand_vec(S::PUBLIC_INPUTS);
|
||||
|
||||
let lagrange_first = PolynomialValues::selector(WITNESS_SIZE, 0).lde(rate_bits);
|
||||
let lagrange_last = PolynomialValues::selector(WITNESS_SIZE, WITNESS_SIZE - 1).lde(rate_bits);
|
||||
@ -42,14 +38,11 @@ where
|
||||
let alpha = F::rand();
|
||||
let constraint_evals = (0..size)
|
||||
.map(|i| {
|
||||
let vars = StarkEvaluationVars {
|
||||
local_values: &trace_ldes[i].clone().try_into().unwrap(),
|
||||
next_values: &trace_ldes[(i + (1 << rate_bits)) % size]
|
||||
.clone()
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
public_inputs: &public_inputs,
|
||||
};
|
||||
let vars = S::EvaluationFrame::from_values(
|
||||
&trace_ldes[i],
|
||||
&trace_ldes[(i + (1 << rate_bits)) % size],
|
||||
&public_inputs,
|
||||
);
|
||||
|
||||
let mut consumer = ConstraintConsumer::<F>::new(
|
||||
vec![alpha],
|
||||
@ -57,7 +50,7 @@ where
|
||||
lagrange_first.values[i],
|
||||
lagrange_last.values[i],
|
||||
);
|
||||
stark.eval_packed_base(vars, &mut consumer);
|
||||
stark.eval_packed_base(&vars, &mut consumer);
|
||||
consumer.accumulators()[0]
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@ -85,17 +78,13 @@ pub fn test_stark_circuit_constraints<
|
||||
const D: usize,
|
||||
>(
|
||||
stark: S,
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
) -> Result<()> {
|
||||
// Compute native constraint evaluation on random values.
|
||||
let vars = StarkEvaluationVars {
|
||||
local_values: &F::Extension::rand_array::<{ S::COLUMNS }>(),
|
||||
next_values: &F::Extension::rand_array::<{ S::COLUMNS }>(),
|
||||
public_inputs: &F::Extension::rand_array::<{ S::PUBLIC_INPUTS }>(),
|
||||
};
|
||||
let vars = S::EvaluationFrame::from_values(
|
||||
&F::Extension::rand_vec(S::COLUMNS),
|
||||
&F::Extension::rand_vec(S::COLUMNS),
|
||||
&F::Extension::rand_vec(S::PUBLIC_INPUTS),
|
||||
);
|
||||
let alphas = F::rand_vec(1);
|
||||
let z_last = F::Extension::rand();
|
||||
let lagrange_first = F::Extension::rand();
|
||||
@ -110,20 +99,19 @@ where
|
||||
lagrange_first,
|
||||
lagrange_last,
|
||||
);
|
||||
stark.eval_ext(vars, &mut consumer);
|
||||
stark.eval_ext(&vars, &mut consumer);
|
||||
let native_eval = consumer.accumulators()[0];
|
||||
|
||||
// Compute circuit constraint evaluation on same random values.
|
||||
let circuit_config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(circuit_config);
|
||||
let mut pw = PartialWitness::<F>::new();
|
||||
|
||||
let locals_t = builder.add_virtual_extension_targets(S::COLUMNS);
|
||||
pw.set_extension_targets(&locals_t, vars.local_values);
|
||||
pw.set_extension_targets(&locals_t, vars.get_local_values());
|
||||
let nexts_t = builder.add_virtual_extension_targets(S::COLUMNS);
|
||||
pw.set_extension_targets(&nexts_t, vars.next_values);
|
||||
pw.set_extension_targets(&nexts_t, vars.get_next_values());
|
||||
let pis_t = builder.add_virtual_extension_targets(S::PUBLIC_INPUTS);
|
||||
pw.set_extension_targets(&pis_t, vars.public_inputs);
|
||||
pw.set_extension_targets(&pis_t, vars.get_public_inputs());
|
||||
let alphas_t = builder.add_virtual_targets(1);
|
||||
pw.set_target(alphas_t[0], alphas[0]);
|
||||
let z_last_t = builder.add_virtual_extension_target();
|
||||
@ -133,11 +121,7 @@ where
|
||||
let lagrange_last_t = builder.add_virtual_extension_target();
|
||||
pw.set_extension_target(lagrange_last_t, lagrange_last);
|
||||
|
||||
let vars = StarkEvaluationTargets::<D, { S::COLUMNS }, { S::PUBLIC_INPUTS }> {
|
||||
local_values: &locals_t.try_into().unwrap(),
|
||||
next_values: &nexts_t.try_into().unwrap(),
|
||||
public_inputs: &pis_t.try_into().unwrap(),
|
||||
};
|
||||
let vars = S::EvaluationFrameTarget::from_values(&locals_t, &nexts_t, &pis_t);
|
||||
let mut consumer = RecursiveConstraintConsumer::<F, D>::new(
|
||||
builder.zero_extension(),
|
||||
alphas_t,
|
||||
@ -145,7 +129,7 @@ where
|
||||
lagrange_first_t,
|
||||
lagrange_last_t,
|
||||
);
|
||||
stark.eval_ext_circuit(&mut builder, vars, &mut consumer);
|
||||
stark.eval_ext_circuit(&mut builder, &vars, &mut consumer);
|
||||
let circuit_eval = consumer.accumulators()[0];
|
||||
let native_eval_t = builder.constant_extension(native_eval);
|
||||
builder.connect_extension(circuit_eval, native_eval_t);
|
||||
|
||||
@ -10,12 +10,11 @@ use crate::permutation::{
|
||||
PermutationCheckVars,
|
||||
};
|
||||
use crate::stark::Stark;
|
||||
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
|
||||
|
||||
pub(crate) fn eval_vanishing_poly<F, FE, P, S, const D: usize, const D2: usize>(
|
||||
stark: &S,
|
||||
config: &StarkConfig,
|
||||
vars: StarkEvaluationVars<FE, P, { S::COLUMNS }, { S::PUBLIC_INPUTS }>,
|
||||
vars: &S::EvaluationFrame<FE, P, D2>,
|
||||
permutation_data: Option<PermutationCheckVars<F, FE, P, D2>>,
|
||||
consumer: &mut ConstraintConsumer<P>,
|
||||
) where
|
||||
@ -23,8 +22,6 @@ pub(crate) fn eval_vanishing_poly<F, FE, P, S, const D: usize, const D2: usize>(
|
||||
FE: FieldExtension<D2, BaseField = F>,
|
||||
P: PackedField<Scalar = FE>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
stark.eval_packed_generic(vars, consumer);
|
||||
if let Some(permutation_data) = permutation_data {
|
||||
@ -42,14 +39,12 @@ pub(crate) fn eval_vanishing_poly_circuit<F, S, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
stark: &S,
|
||||
config: &StarkConfig,
|
||||
vars: StarkEvaluationTargets<D, { S::COLUMNS }, { S::PUBLIC_INPUTS }>,
|
||||
vars: &S::EvaluationFrameTarget,
|
||||
permutation_data: Option<PermutationCheckDataTarget<D>>,
|
||||
consumer: &mut RecursiveConstraintConsumer<F, D>,
|
||||
) where
|
||||
F: RichField + Extendable<D>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
stark.eval_ext_circuit(builder, vars, consumer);
|
||||
if let Some(permutation_data) = permutation_data {
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
use plonky2::field::packed::PackedField;
|
||||
use plonky2::field::types::Field;
|
||||
use plonky2::iop::ext_target::ExtensionTarget;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct StarkEvaluationVars<'a, F, P, const COLUMNS: usize, const PUBLIC_INPUTS: usize>
|
||||
where
|
||||
F: Field,
|
||||
P: PackedField<Scalar = F>,
|
||||
{
|
||||
pub local_values: &'a [P; COLUMNS],
|
||||
pub next_values: &'a [P; COLUMNS],
|
||||
pub public_inputs: &'a [P::Scalar; PUBLIC_INPUTS],
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct StarkEvaluationTargets<
|
||||
'a,
|
||||
const D: usize,
|
||||
const COLUMNS: usize,
|
||||
const PUBLIC_INPUTS: usize,
|
||||
> {
|
||||
pub local_values: &'a [ExtensionTarget<D>; COLUMNS],
|
||||
pub next_values: &'a [ExtensionTarget<D>; COLUMNS],
|
||||
pub public_inputs: &'a [ExtensionTarget<D>; PUBLIC_INPUTS],
|
||||
}
|
||||
@ -12,11 +12,11 @@ use plonky2::plonk::plonk_common::reduce_with_powers;
|
||||
|
||||
use crate::config::StarkConfig;
|
||||
use crate::constraint_consumer::ConstraintConsumer;
|
||||
use crate::evaluation_frame::StarkEvaluationFrame;
|
||||
use crate::permutation::PermutationCheckVars;
|
||||
use crate::proof::{StarkOpeningSet, StarkProof, StarkProofChallenges, StarkProofWithPublicInputs};
|
||||
use crate::stark::Stark;
|
||||
use crate::vanishing_poly::eval_vanishing_poly;
|
||||
use crate::vars::StarkEvaluationVars;
|
||||
|
||||
pub fn verify_stark_proof<
|
||||
F: RichField + Extendable<D>,
|
||||
@ -27,11 +27,7 @@ pub fn verify_stark_proof<
|
||||
stark: S,
|
||||
proof_with_pis: StarkProofWithPublicInputs<F, C, D>,
|
||||
config: &StarkConfig,
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
) -> Result<()> {
|
||||
ensure!(proof_with_pis.public_inputs.len() == S::PUBLIC_INPUTS);
|
||||
let degree_bits = proof_with_pis.proof.recover_degree_bits(config);
|
||||
let challenges = proof_with_pis.get_challenges(&stark, config, degree_bits);
|
||||
@ -49,11 +45,7 @@ pub(crate) fn verify_stark_proof_with_challenges<
|
||||
challenges: StarkProofChallenges<F, D>,
|
||||
degree_bits: usize,
|
||||
config: &StarkConfig,
|
||||
) -> Result<()>
|
||||
where
|
||||
[(); S::COLUMNS]:,
|
||||
[(); S::PUBLIC_INPUTS]:,
|
||||
{
|
||||
) -> Result<()> {
|
||||
validate_proof_shape(&stark, &proof_with_pis, config)?;
|
||||
check_permutation_options(&stark, &proof_with_pis, &challenges)?;
|
||||
let StarkProofWithPublicInputs {
|
||||
@ -67,17 +59,15 @@ where
|
||||
permutation_zs_next,
|
||||
quotient_polys,
|
||||
} = &proof.openings;
|
||||
let vars = StarkEvaluationVars {
|
||||
local_values: &local_values.to_vec().try_into().unwrap(),
|
||||
next_values: &next_values.to_vec().try_into().unwrap(),
|
||||
public_inputs: &public_inputs
|
||||
.into_iter()
|
||||
let vars = S::EvaluationFrame::from_values(
|
||||
local_values,
|
||||
next_values,
|
||||
&public_inputs
|
||||
.iter()
|
||||
.copied()
|
||||
.map(F::Extension::from_basefield)
|
||||
.collect::<Vec<_>>()
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let (l_0, l_last) = eval_l_0_and_l_last(degree_bits, challenges.stark_zeta);
|
||||
let last = F::primitive_root_of_unity(degree_bits).inverse();
|
||||
let z_last = challenges.stark_zeta - last.into();
|
||||
@ -99,7 +89,7 @@ where
|
||||
eval_vanishing_poly::<F, F::Extension, F::Extension, S, D, D>(
|
||||
&stark,
|
||||
config,
|
||||
vars,
|
||||
&vars,
|
||||
permutation_data,
|
||||
&mut consumer,
|
||||
);
|
||||
@ -153,7 +143,6 @@ where
|
||||
F: RichField + Extendable<D>,
|
||||
C: GenericConfig<D, F = F>,
|
||||
S: Stark<F, D>,
|
||||
[(); S::COLUMNS]:,
|
||||
{
|
||||
let StarkProofWithPublicInputs {
|
||||
proof,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user