This commit is contained in:
wborgeaud 2022-05-24 16:24:52 +02:00
parent d9b237d998
commit d47b22d2b5
7 changed files with 228 additions and 131 deletions

View File

@ -1,5 +1,4 @@
use anyhow::{ensure, Result};
use env_logger::Target;
use plonky2::field::extension_field::{Extendable, FieldExtension};
use plonky2::field::field_types::Field;
use plonky2::field::packed_field::PackedField;
@ -7,17 +6,19 @@ use plonky2::field::polynomial::PolynomialValues;
use plonky2::hash::hash_types::RichField;
use plonky2::iop::challenger::Challenger;
use plonky2::iop::ext_target::ExtensionTarget;
use plonky2::iop::target::Target;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::config::GenericConfig;
use crate::all_stark::Table;
use crate::config::StarkConfig;
use crate::constraint_consumer::ConstraintConsumer;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::permutation::{
get_grand_product_challenge_set, GrandProductChallenge, GrandProductChallengeSet,
};
use crate::proof::{StarkProofWithPublicInputs, StarkProofWithPublicInputsTarget};
use crate::stark::Stark;
use crate::vars::StarkEvaluationVars;
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
#[derive(Clone)]
pub struct CrossTableLookup<F: Field> {
@ -290,6 +291,48 @@ impl<'a, const D: usize> CtlCheckVarsTarget<'a, D> {
}
}
pub(crate) fn eval_cross_table_lookup_checks_circuit<
S: Stark<F, D>,
F: RichField + Extendable<D>,
const D: usize,
>(
builder: &mut CircuitBuilder<F, D>,
vars: StarkEvaluationTargets<D, { S::COLUMNS }, { S::PUBLIC_INPUTS }>,
ctl_vars: &[CtlCheckVarsTarget<D>],
consumer: &mut RecursiveConstraintConsumer<F, D>,
) {
for lookup_vars in ctl_vars {
let CtlCheckVarsTarget {
local_z,
next_z,
challenges,
columns,
} = lookup_vars;
// Check value of `Z(1)`
let combined_local = challenges.combine_circuit(
builder,
&columns
.iter()
.map(|&i| vars.local_values[i])
.collect::<Vec<_>>(),
);
let first_row = builder.sub_extension(*local_z, combined_local);
consumer.constraint_first_row(builder, first_row);
// Check `Z(gw) = combination * Z(w)`
let combined_next = challenges.combine_circuit(
builder,
&columns
.iter()
.map(|&i| vars.next_values[i])
.collect::<Vec<_>>(),
);
let mut transition = builder.mul_extension(*local_z, combined_next);
transition = builder.sub_extension(*next_z, transition);
consumer.constraint_transition(builder, transition);
}
}
pub(crate) fn verify_cross_table_lookups<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
@ -333,3 +376,49 @@ pub(crate) fn verify_cross_table_lookups<
Ok(())
}
pub(crate) fn verify_cross_table_lookups_circuit<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
builder: &mut CircuitBuilder<F, D>,
cross_table_lookups: Vec<CrossTableLookup<F>>,
proofs: &[StarkProofWithPublicInputsTarget<D>],
challenges: GrandProductChallengeSet<Target>,
inner_config: &StarkConfig,
) {
let degrees_bits = proofs
.iter()
.map(|p| p.proof.recover_degree_bits(inner_config))
.collect::<Vec<_>>();
let mut ctl_zs_openings = proofs
.iter()
.map(|p| p.proof.openings.ctl_zs_last.iter())
.collect::<Vec<_>>();
for (
i,
CrossTableLookup {
looking_table,
looked_table,
default,
..
},
) in cross_table_lookups.into_iter().enumerate()
{
let looking_degree = 1 << degrees_bits[looking_table as usize];
let looked_degree = 1 << degrees_bits[looked_table as usize];
let looking_z = *ctl_zs_openings[looking_table as usize].next().unwrap();
let looked_z = *ctl_zs_openings[looked_table as usize].next().unwrap();
let challenge = challenges.challenges[i % inner_config.num_challenges];
let default = default
.into_iter()
.map(|x| builder.constant(x.into()))
.collect::<Vec<_>>();
let combined_default = challenge.combine_base_circuit(builder, &default);
let pad = builder.exp_u64(combined_default, looking_degree - looked_degree);
let padded_looked_z = builder.mul(looked_z, pad);
builder.connect(looking_z, padded_looked_z);
}
}

View File

@ -13,7 +13,6 @@ use crate::permutation::{
get_n_grand_product_challenge_sets, get_n_grand_product_challenge_sets_target,
};
use crate::proof::*;
use crate::stark::Stark;
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> AllProof<F, C, D> {
/// Computes all Fiat-Shamir challenges used in the STARK proof.
@ -47,11 +46,7 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> A
}
impl<const D: usize> AllProofTarget<D> {
pub(crate) fn get_challenges<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
>(
pub(crate) fn get_challenges<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>>(
&self,
builder: &mut CircuitBuilder<F, D>,
all_stark: &AllStark<F, D>,
@ -165,8 +160,6 @@ impl<const D: usize> StarkProofWithPublicInputsTarget<D> {
where
C::Hasher: AlgebraicHasher<F>,
{
let degree_bits = self.proof.recover_degree_bits(config);
let StarkProofTarget {
permutation_ctl_zs_cap,
quotient_polys_cap,

View File

@ -68,6 +68,32 @@ impl<F: Field> GrandProductChallenge<F> {
}
}
impl GrandProductChallenge<Target> {
pub(crate) fn combine_circuit<'a, F: RichField + Extendable<D>, const D: usize>(
&self,
builder: &mut CircuitBuilder<F, D>,
terms: &[ExtensionTarget<D>],
) -> ExtensionTarget<D> {
let zero = builder.zero();
let mut factor = ReducingFactorTarget::new(self.beta.to_ext_target(zero));
let reduced = factor.reduce(terms, builder);
builder.add_extension(reduced, self.gamma.to_ext_target(zero))
}
pub(crate) fn combine_base_circuit<'a, F: RichField + Extendable<D>, const D: usize>(
&self,
builder: &mut CircuitBuilder<F, D>,
terms: &[Target],
) -> Target {
let zero = builder.zero();
let combination = terms
.iter()
.rev()
.fold(zero, |acc, &t| builder.mul_add(self.beta, acc, t));
builder.add(combination, self.gamma)
}
}
/// Like `PermutationChallenge`, but with `num_challenges` copies to boost soundness.
#[derive(Clone)]
pub(crate) struct GrandProductChallengeSet<T: Copy> {

View File

@ -1,24 +1,27 @@
use std::iter::once;
use anyhow::{ensure, Result};
use itertools::Itertools;
use plonky2::field::extension_field::Extendable;
use plonky2::field::field_types::Field;
use plonky2::fri::witness_util::set_fri_proof_target;
use plonky2::hash::hash_types::RichField;
use plonky2::iop::ext_target::ExtensionTarget;
use plonky2::iop::target::Target;
use plonky2::iop::witness::Witness;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
use plonky2::util::reducing::ReducingFactorTarget;
use plonky2::with_context;
use crate::all_stark::AllStark;
use crate::all_stark::{AllStark, Table};
use crate::config::StarkConfig;
use crate::constraint_consumer::RecursiveConstraintConsumer;
use crate::cpu::cpu_stark::CpuStark;
use crate::cross_table_lookup::{verify_cross_table_lookups_circuit, CtlCheckVarsTarget};
use crate::keccak::keccak_stark::KeccakStark;
use crate::permutation::PermutationCheckDataTarget;
use crate::proof::{
AllProof, AllProofChallengesTarget, AllProofTarget, StarkOpeningSetTarget, StarkProof,
AllProofChallengesTarget, AllProofTarget, StarkOpeningSetTarget, StarkProof,
StarkProofChallengesTarget, StarkProofTarget, StarkProofWithPublicInputs,
StarkProofWithPublicInputsTarget,
};
@ -29,7 +32,6 @@ use crate::vars::StarkEvaluationTargets;
pub fn verify_proof_circuit<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
const D: usize,
>(
builder: &mut CircuitBuilder<F, D>,
@ -37,14 +39,16 @@ pub fn verify_proof_circuit<
all_proof: AllProofTarget<D>,
inner_config: &StarkConfig,
) where
[(); CpuStark::<F, D>::COLUMNS]:,
[(); CpuStark::<F, D>::PUBLIC_INPUTS]:,
[(); KeccakStark::<F, D>::COLUMNS]:,
[(); KeccakStark::<F, D>::PUBLIC_INPUTS]:,
C::Hasher: AlgebraicHasher<F>,
[(); S::COLUMNS]:,
[(); S::PUBLIC_INPUTS]:,
{
let AllProofChallengesTarget {
stark_challenges,
ctl_challenges,
} = all_proof.get_challenges(builder, &all_stark, inner_config);
} = all_proof.get_challenges::<F, C>(builder, &all_stark, inner_config);
let nums_permutation_zs = all_stark.nums_permutation_zs(inner_config);
@ -54,33 +58,36 @@ pub fn verify_proof_circuit<
cross_table_lookups,
} = all_stark;
let ctl_vars_per_table = CtlCheckVars::from_proofs(
let ctl_vars_per_table = CtlCheckVarsTarget::from_proofs(
&all_proof.stark_proofs,
&cross_table_lookups,
&ctl_challenges,
&nums_permutation_zs,
);
verify_stark_proof_with_challenges(
verify_stark_proof_with_challenges_circuit::<F, C, _, D>(
builder,
cpu_stark,
&all_proof.stark_proofs[Table::Cpu as usize],
&stark_challenges[Table::Cpu as usize],
&ctl_vars_per_table[Table::Cpu as usize],
config,
)?;
verify_stark_proof_with_challenges(
inner_config,
);
verify_stark_proof_with_challenges_circuit::<F, C, _, D>(
builder,
keccak_stark,
&all_proof.stark_proofs[Table::Keccak as usize],
&stark_challenges[Table::Keccak as usize],
&ctl_vars_per_table[Table::Keccak as usize],
config,
)?;
inner_config,
);
verify_cross_table_lookups(
verify_cross_table_lookups_circuit::<F, C, D>(
builder,
cross_table_lookups,
&all_proof.stark_proofs,
ctl_challenges,
config,
inner_config,
)
}
@ -93,40 +100,43 @@ fn verify_stark_proof_with_challenges_circuit<
>(
builder: &mut CircuitBuilder<F, D>,
stark: S,
proof_with_pis: StarkProofWithPublicInputsTarget<D>,
challenges: StarkProofChallengesTarget<D>,
proof_with_pis: &StarkProofWithPublicInputsTarget<D>,
challenges: &StarkProofChallengesTarget<D>,
ctl_vars: &[CtlCheckVarsTarget<D>],
inner_config: &StarkConfig,
degree_bits: usize,
) where
C::Hasher: AlgebraicHasher<F>,
[(); S::COLUMNS]:,
[(); S::PUBLIC_INPUTS]:,
{
check_permutation_options(&stark, &proof_with_pis, &challenges).unwrap();
let zero = builder.zero();
let one = builder.one_extension();
let StarkProofWithPublicInputsTarget {
proof,
public_inputs,
} = proof_with_pis;
assert_eq!(public_inputs.len(), S::PUBLIC_INPUTS);
let StarkOpeningSetTarget {
local_values,
next_values,
permutation_ctl_zs: permutation_zs,
permutation_ctl_zs_right: permutation_zs_right,
ctl_zs_last,
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
.into_iter()
.map(|t| builder.convert_to_ext(t))
.iter()
.map(|&t| builder.convert_to_ext(t))
.collect::<Vec<_>>()
.try_into()
.unwrap(),
};
let degree_bits = proof.recover_degree_bits(inner_config);
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);
let (l_1, l_last) =
@ -137,7 +147,7 @@ fn verify_stark_proof_with_challenges_circuit<
let mut consumer = RecursiveConstraintConsumer::<F, D>::new(
builder.zero_extension(),
challenges.stark_alphas,
challenges.stark_alphas.clone(),
z_last,
l_1,
l_last,
@ -146,9 +156,9 @@ fn verify_stark_proof_with_challenges_circuit<
let permutation_data = stark
.uses_permutation_args()
.then(|| PermutationCheckDataTarget {
local_zs: permutation_zs.as_ref().unwrap().clone(),
next_zs: permutation_zs_right.as_ref().unwrap().clone(),
permutation_challenge_sets: challenges.permutation_challenge_sets.unwrap(),
local_zs: permutation_zs.clone(),
next_zs: permutation_zs_right.clone(),
permutation_challenge_sets: challenges.permutation_challenge_sets.clone().unwrap(),
});
with_context!(
@ -160,6 +170,7 @@ fn verify_stark_proof_with_challenges_circuit<
inner_config,
vars,
permutation_data,
ctl_vars,
&mut consumer,
)
);
@ -176,20 +187,23 @@ fn verify_stark_proof_with_challenges_circuit<
builder.connect_extension(vanishing_polys_zeta[i], computed_vanishing_poly);
}
let merkle_caps = once(proof.trace_cap)
.chain(proof.permutation_ctl_zs_cap)
.chain(once(proof.quotient_polys_cap))
.collect_vec();
let merkle_caps = vec![
proof.trace_cap.clone(),
proof.permutation_ctl_zs_cap.clone(),
proof.quotient_polys_cap.clone(),
];
let fri_instance = stark.fri_instance_target(
builder,
challenges.stark_zeta,
F::primitive_root_of_unity(degree_bits),
degree_bits,
ctl_zs_last.len(),
inner_config,
);
builder.verify_fri_proof::<C>(
&fri_instance,
&proof.openings.to_fri_openings(),
&proof.openings.to_fri_openings(zero),
&challenges.fri_challenges,
&merkle_caps,
&proof.opening_proof,
@ -252,9 +266,7 @@ pub fn add_virtual_stark_proof<F: RichField + Extendable<D>, S: Stark<F, D>, con
.chain(once(stark.quotient_degree_factor() * config.num_challenges))
.collect_vec();
let permutation_zs_cap = stark
.uses_permutation_args()
.then(|| builder.add_virtual_cap(cap_height));
let permutation_zs_cap = builder.add_virtual_cap(cap_height);
StarkProofTarget {
trace_cap: builder.add_virtual_cap(cap_height),
@ -274,12 +286,11 @@ fn add_stark_opening_set<F: RichField + Extendable<D>, S: Stark<F, D>, const D:
StarkOpeningSetTarget {
local_values: builder.add_virtual_extension_targets(S::COLUMNS),
next_values: builder.add_virtual_extension_targets(S::COLUMNS),
permutation_ctl_zs: stark
.uses_permutation_args()
.then(|| builder.add_virtual_extension_targets(stark.num_permutation_batches(config))),
permutation_ctl_zs_right: stark
.uses_permutation_args()
.then(|| builder.add_virtual_extension_targets(stark.num_permutation_batches(config))),
permutation_ctl_zs: builder
.add_virtual_extension_targets(stark.num_permutation_batches(config)),
permutation_ctl_zs_right: builder
.add_virtual_extension_targets(stark.num_permutation_batches(config)),
ctl_zs_last: vec![],
quotient_polys: builder
.add_virtual_extension_targets(stark.quotient_degree_factor() * num_challenges),
}
@ -289,6 +300,7 @@ pub fn set_stark_proof_with_pis_target<F, C: GenericConfig<D, F = F>, W, const D
witness: &mut W,
stark_proof_with_pis_target: &StarkProofWithPublicInputsTarget<D>,
stark_proof_with_pis: &StarkProofWithPublicInputs<F, C, D>,
zero: Target,
) where
F: RichField + Extendable<D>,
C::Hasher: AlgebraicHasher<F>,
@ -308,13 +320,14 @@ pub fn set_stark_proof_with_pis_target<F, C: GenericConfig<D, F = F>, W, const D
witness.set_target(pi_t, pi);
}
set_stark_proof_target(witness, pt, proof);
set_stark_proof_target(witness, pt, proof, zero);
}
pub fn set_stark_proof_target<F, C: GenericConfig<D, F = F>, W, const D: usize>(
witness: &mut W,
proof_target: &StarkProofTarget<D>,
proof: &StarkProof<F, C, D>,
zero: Target,
) where
F: RichField + Extendable<D>,
C::Hasher: AlgebraicHasher<F>,
@ -324,39 +337,14 @@ pub fn set_stark_proof_target<F, C: GenericConfig<D, F = F>, W, const D: usize>(
witness.set_cap_target(&proof_target.quotient_polys_cap, &proof.quotient_polys_cap);
witness.set_fri_openings(
&proof_target.openings.to_fri_openings(),
&proof_target.openings.to_fri_openings(zero),
&proof.openings.to_fri_openings(),
);
if let Some(permutation_zs_cap_target) = &proof_target.permutation_ctl_zs_cap {
witness.set_cap_target(permutation_zs_cap_target, &proof.permutation_ctl_zs_cap);
}
witness.set_cap_target(
&proof_target.permutation_ctl_zs_cap,
&proof.permutation_ctl_zs_cap,
);
set_fri_proof_target(witness, &proof_target.opening_proof, &proof.opening_proof);
}
/// Utility function to check that all permutation data wrapped in `Option`s are `Some` iff
/// the Stark uses a permutation argument.
fn check_permutation_options<F: RichField + Extendable<D>, S: Stark<F, D>, const D: usize>(
stark: &S,
proof_with_pis: &StarkProofWithPublicInputsTarget<D>,
challenges: &StarkProofChallengesTarget<D>,
) -> Result<()> {
let options_is_some = [
proof_with_pis.proof.permutation_ctl_zs_cap.is_some(),
proof_with_pis.proof.openings.permutation_ctl_zs.is_some(),
proof_with_pis
.proof
.openings
.permutation_ctl_zs_right
.is_some(),
challenges.permutation_challenge_sets.is_some(),
];
ensure!(
options_is_some
.into_iter()
.all(|b| b == stark.uses_permutation_args()),
"Permutation data doesn't match with Stark configuration."
);
Ok(())
}

View File

@ -1,5 +1,3 @@
use std::iter::once;
use plonky2::field::extension_field::{Extendable, FieldExtension};
use plonky2::field::field_types::Field;
use plonky2::field::packed_field::PackedField;
@ -97,24 +95,16 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
FriPolynomialInfo::from_range(oracle_indices.next().unwrap(), 0..Self::COLUMNS);
let num_permutation_batches = self.num_permutation_batches(config);
let permutation_ctl_zs_info = (num_permutation_batches + num_ctl_zs > 0).then(|| {
let permutation_ctl_index = oracle_indices.next().unwrap();
FriPolynomialInfo::from_range(
permutation_ctl_index,
0..num_permutation_batches + num_ctl_zs,
)
});
let permutation_ctl_index = oracle_indices.next().unwrap();
let permutation_ctl_zs_info = FriPolynomialInfo::from_range(
permutation_ctl_index,
0..num_permutation_batches + num_ctl_zs,
);
let ctl_zs_info = (num_ctl_zs > 0).then(|| {
let index = permutation_ctl_zs_info
.as_ref()
.map(|info| info[0].oracle_index)
.unwrap_or_else(|| oracle_indices.next().unwrap());
FriPolynomialInfo::from_range(
index,
num_permutation_batches..num_permutation_batches + num_ctl_zs,
)
});
let ctl_zs_info = FriPolynomialInfo::from_range(
permutation_ctl_index,
num_permutation_batches..num_permutation_batches + num_ctl_zs,
);
let quotient_info = FriPolynomialInfo::from_range(
oracle_indices.next().unwrap(),
@ -123,29 +113,24 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
let zeta_batch = FriBatchInfo {
point: zeta,
polynomials: once(trace_info.clone())
.chain(permutation_ctl_zs_info.clone())
.chain(once(quotient_info))
.collect::<Vec<_>>()
.concat(),
polynomials: [
trace_info.clone(),
permutation_ctl_zs_info.clone(),
quotient_info,
]
.concat(),
};
let zeta_right_batch = FriBatchInfo {
point: zeta.scalar_mul(g),
polynomials: once(trace_info)
.chain(permutation_ctl_zs_info)
.collect::<Vec<_>>()
.concat(),
polynomials: [trace_info, permutation_ctl_zs_info].concat(),
};
let ctl_last_batch = ctl_zs_info.map(|info| FriBatchInfo {
let ctl_last_batch = FriBatchInfo {
point: F::Extension::primitive_root_of_unity(degree_bits).inverse(),
polynomials: info,
});
polynomials: ctl_zs_info,
};
FriInstanceInfo {
oracles: vec![no_blinding_oracle; oracle_indices.next().unwrap()],
batches: once(zeta_batch)
.chain(once(zeta_right_batch))
.chain(ctl_last_batch)
.collect::<Vec<_>>(),
batches: vec![zeta_batch, zeta_right_batch, ctl_last_batch],
}
}
@ -155,7 +140,9 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
builder: &mut CircuitBuilder<F, D>,
zeta: ExtensionTarget<D>,
g: F,
config: &StarkConfig,
degree_bits: usize,
num_ctl_zs: usize,
inner_config: &StarkConfig,
) -> FriInstanceInfoTarget<D> {
let no_blinding_oracle = FriOracleInfo { blinding: false };
let mut oracle_indices = 0..;
@ -163,25 +150,28 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
let trace_info =
FriPolynomialInfo::from_range(oracle_indices.next().unwrap(), 0..Self::COLUMNS);
let permutation_zs_info = if self.uses_permutation_args() {
FriPolynomialInfo::from_range(
oracle_indices.next().unwrap(),
0..self.num_permutation_batches(config),
)
} else {
vec![]
};
let num_permutation_batches = self.num_permutation_batches(inner_config);
let permutation_ctl_index = oracle_indices.next().unwrap();
let permutation_ctl_zs_info = FriPolynomialInfo::from_range(
permutation_ctl_index,
0..num_permutation_batches + num_ctl_zs,
);
let ctl_zs_info = FriPolynomialInfo::from_range(
permutation_ctl_index,
num_permutation_batches..num_permutation_batches + num_ctl_zs,
);
let quotient_info = FriPolynomialInfo::from_range(
oracle_indices.next().unwrap(),
0..self.quotient_degree_factor() * config.num_challenges,
0..self.quotient_degree_factor() * inner_config.num_challenges,
);
let zeta_batch = FriBatchInfoTarget {
point: zeta,
polynomials: [
trace_info.clone(),
permutation_zs_info.clone(),
permutation_ctl_zs_info.clone(),
quotient_info,
]
.concat(),
@ -189,11 +179,16 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
let zeta_right = builder.mul_const_extension(g, zeta);
let zeta_right_batch = FriBatchInfoTarget {
point: zeta_right,
polynomials: [trace_info, permutation_zs_info].concat(),
polynomials: [trace_info, permutation_ctl_zs_info].concat(),
};
let ctl_last_batch = FriBatchInfoTarget {
point: builder
.constant_extension(F::Extension::primitive_root_of_unity(degree_bits).inverse()),
polynomials: ctl_zs_info,
};
FriInstanceInfoTarget {
oracles: vec![no_blinding_oracle; oracle_indices.next().unwrap()],
batches: vec![zeta_batch, zeta_right_batch],
batches: vec![zeta_batch, zeta_right_batch, ctl_last_batch],
}
}

View File

@ -6,7 +6,10 @@ use plonky2::plonk::config::GenericConfig;
use crate::config::StarkConfig;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cross_table_lookup::{eval_cross_table_lookup_checks, CtlCheckVars};
use crate::cross_table_lookup::{
eval_cross_table_lookup_checks, eval_cross_table_lookup_checks_circuit, CtlCheckVars,
CtlCheckVarsTarget,
};
use crate::permutation::{
eval_permutation_checks, eval_permutation_checks_circuit, PermutationCheckDataTarget,
PermutationCheckVars,
@ -47,6 +50,7 @@ pub(crate) fn eval_vanishing_poly_circuit<F, C, S, const D: usize>(
config: &StarkConfig,
vars: StarkEvaluationTargets<D, { S::COLUMNS }, { S::PUBLIC_INPUTS }>,
permutation_data: Option<PermutationCheckDataTarget<D>>,
ctl_vars: &[CtlCheckVarsTarget<D>],
consumer: &mut RecursiveConstraintConsumer<F, D>,
) where
F: RichField + Extendable<D>,
@ -66,4 +70,5 @@ pub(crate) fn eval_vanishing_poly_circuit<F, C, S, const D: usize>(
consumer,
);
}
eval_cross_table_lookup_checks_circuit::<S, F, D>(builder, vars, ctl_vars, consumer);
}

View File

@ -29,6 +29,7 @@ where
[(); CpuStark::<F, D>::COLUMNS]:,
[(); CpuStark::<F, D>::PUBLIC_INPUTS]:,
[(); KeccakStark::<F, D>::COLUMNS]:,
[(); KeccakStark::<F, D>::PUBLIC_INPUTS]:,
[(); C::Hasher::HASH_SIZE]:,
{
let AllProofChallenges {