refactor: remove usage of unstable generic_const_exprs in starky (#1300)

This commit is contained in:
bing 2023-10-24 08:20:00 +08:00 committed by GitHub
parent 8af189b927
commit 8326db604c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 182 additions and 177 deletions

View 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(),
}
}
}

View File

@ -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);

View File

@ -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)]

View File

@ -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);

View File

@ -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,
);

View File

@ -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,
)

View File

@ -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>,
);

View File

@ -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);

View File

@ -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 {

View File

@ -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],
}

View File

@ -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,