Some renaming + cleaning

This commit is contained in:
wborgeaud 2022-05-13 11:20:29 +02:00
parent a38c19f952
commit 8cd2793937
8 changed files with 98 additions and 115 deletions

View File

@ -28,12 +28,14 @@ impl<F: RichField + Extendable<D>, const D: usize> AllStark<F, D> {
#[derive(Copy, Clone)]
pub struct CpuStark<F, const D: usize> {
#[allow(dead_code)]
num_rows: usize,
f: PhantomData<F>,
}
#[derive(Copy, Clone)]
pub struct KeccakStark<F, const D: usize> {
#[allow(dead_code)]
num_rows: usize,
f: PhantomData<F>,
}

View File

@ -46,12 +46,14 @@ impl CrossTableLookup {
/// Lookup data for one table.
#[derive(Clone)]
pub struct LookupData<F: Field> {
pub struct CtlData<F: Field> {
// Challenges used in the lookup argument.
pub(crate) challenges: GrandProductChallengeSet<F>,
// Vector of `(Z, columns)` where `Z` is a Z-polynomial for a lookup on columns `columns`.
pub zs_columns: Vec<(PolynomialValues<F>, Vec<usize>)>,
}
impl<F: Field> LookupData<F> {
impl<F: Field> CtlData<F> {
pub(crate) fn new(challenges: GrandProductChallengeSet<F>) -> Self {
Self {
challenges,
@ -72,15 +74,15 @@ impl<F: Field> LookupData<F> {
}
}
pub fn cross_table_lookup_zs<F: RichField, C: GenericConfig<D, F = F>, const D: usize>(
pub fn cross_table_lookup_data<F: RichField, C: GenericConfig<D, F = F>, const D: usize>(
config: &StarkConfig,
trace_poly_values: &[Vec<PolynomialValues<F>>],
cross_table_lookups: &[CrossTableLookup],
challenger: &mut Challenger<F, C::Hasher>,
) -> Vec<LookupData<F>> {
) -> Vec<CtlData<F>> {
let challenges = get_grand_product_challenge_set(challenger, config.num_challenges);
cross_table_lookups.iter().fold(
vec![LookupData::new(challenges.clone()); trace_poly_values.len()],
vec![CtlData::new(challenges.clone()); trace_poly_values.len()],
|mut acc, cross_table_lookup| {
let CrossTableLookup {
looking_table,
@ -159,11 +161,11 @@ impl<'a, F: RichField + Extendable<D>, const D: usize>
.iter()
.zip(num_permutation_zs)
.map(|(p, &num_permutation)| -> Box<dyn Iterator<Item = _>> {
if p.proof.openings.permutation_lookup_zs.is_some() {
if p.proof.openings.permutation_ctl_zs.is_some() {
Box::new(
p.proof
.openings
.permutation_lookup_zs
.permutation_ctl_zs
.as_ref()
.unwrap()
.iter()
@ -171,7 +173,7 @@ impl<'a, F: RichField + Extendable<D>, const D: usize>
.zip(
p.proof
.openings
.permutation_lookup_zs_right
.permutation_ctl_zs_right
.as_ref()
.unwrap()
.iter()
@ -219,7 +221,7 @@ impl<'a, F: RichField + Extendable<D>, const D: usize>
pub(crate) fn eval_cross_table_lookup_checks<F, FE, P, C, S, const D: usize, const D2: usize>(
vars: StarkEvaluationVars<FE, P>,
lookup_data: &[CTLCheckVars<F, FE, P, D2>],
ctl_vars: &[CTLCheckVars<F, FE, P, D2>],
consumer: &mut ConstraintConsumer<P>,
) where
F: RichField + Extendable<D>,
@ -228,13 +230,13 @@ pub(crate) fn eval_cross_table_lookup_checks<F, FE, P, C, S, const D: usize, con
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
{
for lookup_datum in lookup_data {
for lookup_vars in ctl_vars {
let CTLCheckVars {
local_z,
next_z,
challenges,
columns,
} = lookup_datum;
} = lookup_vars;
let mut factor = ReducingFactor::new(challenges.beta);
let mut combine = |v: &[P]| -> P {
factor.reduce_ext(columns.iter().map(|&i| v[i])) + FE::from_basefield(challenges.gamma)
@ -261,9 +263,9 @@ pub(crate) fn verify_cross_table_lookups<
.iter()
.map(|p| p.proof.recover_degree_bits(config))
.collect::<Vec<_>>();
let mut lookup_zs_openings = proofs
let mut ctl_zs_openings = proofs
.iter()
.map(|p| p.proof.openings.lookup_zs_last.iter())
.map(|p| p.proof.openings.ctl_zs_last.iter())
.collect::<Vec<_>>();
for (
i,
@ -276,8 +278,8 @@ pub(crate) fn verify_cross_table_lookups<
{
let looking_degree = 1 << degrees_bits[looking_table as usize];
let looked_degree = 1 << degrees_bits[looked_table as usize];
let looking_z = *lookup_zs_openings[looking_table as usize].next().unwrap();
let looked_z = *lookup_zs_openings[looked_table as usize].next().unwrap();
let looking_z = *ctl_zs_openings[looking_table as usize].next().unwrap();
let looked_z = *ctl_zs_openings[looked_table as usize].next().unwrap();
ensure!(
looking_z
== looked_z

View File

@ -261,7 +261,7 @@ pub(crate) fn eval_permutation_checks<F, FE, P, C, S, const D: usize, const D2:
stark: &S,
config: &StarkConfig,
vars: StarkEvaluationVars<FE, P>,
permutation_data: PermutationCheckVars<F, FE, P, D2>,
permutation_vars: PermutationCheckVars<F, FE, P, D2>,
consumer: &mut ConstraintConsumer<P>,
) where
F: RichField + Extendable<D>,
@ -274,7 +274,7 @@ pub(crate) fn eval_permutation_checks<F, FE, P, C, S, const D: usize, const D2:
local_zs,
next_zs,
permutation_challenge_sets,
} = permutation_data;
} = permutation_vars;
// Check that Z(1) = 1;
for &z in &local_zs {

View File

@ -144,9 +144,9 @@ pub(crate) struct StarkProofChallengesTarget<const D: usize> {
pub struct StarkOpeningSet<F: RichField + Extendable<D>, const D: usize> {
pub local_values: Vec<F::Extension>,
pub next_values: Vec<F::Extension>,
pub permutation_lookup_zs: Option<Vec<F::Extension>>,
pub permutation_lookup_zs_right: Option<Vec<F::Extension>>,
pub lookup_zs_last: Vec<F>,
pub permutation_ctl_zs: Option<Vec<F::Extension>>,
pub permutation_ctl_zs_right: Option<Vec<F::Extension>>,
pub ctl_zs_last: Vec<F>,
pub quotient_polys: Vec<F::Extension>,
}
@ -155,7 +155,7 @@ impl<F: RichField + Extendable<D>, const D: usize> StarkOpeningSet<F, D> {
zeta: F::Extension,
g: F,
trace_commitment: &PolynomialBatch<F, C, D>,
permutation_lookup_zs_commitment: Option<&PolynomialBatch<F, C, D>>,
permutation_ctl_zs_commitment: Option<&PolynomialBatch<F, C, D>>,
quotient_commitment: &PolynomialBatch<F, C, D>,
degree_bits: usize,
num_permutation_zs: usize,
@ -176,11 +176,10 @@ impl<F: RichField + Extendable<D>, const D: usize> StarkOpeningSet<F, D> {
Self {
local_values: eval_commitment(zeta, trace_commitment),
next_values: eval_commitment(zeta_right, trace_commitment),
permutation_lookup_zs: permutation_lookup_zs_commitment
.map(|c| eval_commitment(zeta, c)),
permutation_lookup_zs_right: permutation_lookup_zs_commitment
permutation_ctl_zs: permutation_ctl_zs_commitment.map(|c| eval_commitment(zeta, c)),
permutation_ctl_zs_right: permutation_ctl_zs_commitment
.map(|c| eval_commitment(zeta_right, c)),
lookup_zs_last: permutation_lookup_zs_commitment
ctl_zs_last: permutation_ctl_zs_commitment
.map(|c| {
eval_commitment_base(F::primitive_root_of_unity(degree_bits).inverse(), c)
[num_permutation_zs..]
@ -196,7 +195,7 @@ impl<F: RichField + Extendable<D>, const D: usize> StarkOpeningSet<F, D> {
values: self
.local_values
.iter()
.chain(self.permutation_lookup_zs.iter().flatten())
.chain(self.permutation_ctl_zs.iter().flatten())
.chain(&self.quotient_polys)
.copied()
.collect_vec(),
@ -205,16 +204,16 @@ impl<F: RichField + Extendable<D>, const D: usize> StarkOpeningSet<F, D> {
values: self
.next_values
.iter()
.chain(self.permutation_lookup_zs_right.iter().flatten())
.chain(self.permutation_ctl_zs_right.iter().flatten())
.copied()
.collect_vec(),
};
let mut batches = vec![zeta_batch, zeta_right_batch];
if !self.lookup_zs_last.is_empty() {
if !self.ctl_zs_last.is_empty() {
batches.push(FriOpeningBatch {
values: self
.lookup_zs_last
.ctl_zs_last
.iter()
.copied()
.map(F::Extension::from_basefield)

View File

@ -21,7 +21,7 @@ use rayon::prelude::*;
use crate::all_stark::{AllStark, Table};
use crate::config::StarkConfig;
use crate::constraint_consumer::ConstraintConsumer;
use crate::cross_table_lookup::{cross_table_lookup_zs, CTLCheckVars, LookupData};
use crate::cross_table_lookup::{cross_table_lookup_data, CTLCheckVars, CtlData};
use crate::permutation::PermutationCheckVars;
use crate::permutation::{
compute_permutation_z_polys, get_n_grand_product_challenge_sets, GrandProductChallengeSet,
@ -31,6 +31,7 @@ use crate::stark::Stark;
use crate::vanishing_poly::eval_vanishing_poly;
use crate::vars::StarkEvaluationVars;
/// Compute all STARK proofs.
pub fn prove<F, C, const D: usize>(
all_stark: &AllStark<F, D>,
config: &StarkConfig,
@ -80,7 +81,7 @@ where
challenger.observe_cap(cap);
}
let lookup_zs = cross_table_lookup_zs::<F, C, D>(
let ctl_data_per_table = cross_table_lookup_data::<F, C, D>(
config,
&trace_poly_values,
&all_stark.cross_table_lookups,
@ -92,7 +93,7 @@ where
config,
&trace_poly_values[Table::Cpu as usize],
&trace_commitments[Table::Cpu as usize],
&lookup_zs[Table::Cpu as usize],
&ctl_data_per_table[Table::Cpu as usize],
&public_inputs[Table::Cpu as usize],
&mut challenger,
timing,
@ -102,7 +103,7 @@ where
config,
&trace_poly_values[Table::Keccak as usize],
&trace_commitments[Table::Keccak as usize],
&lookup_zs[Table::Keccak as usize],
&ctl_data_per_table[Table::Keccak as usize],
&public_inputs[Table::Keccak as usize],
&mut challenger,
timing,
@ -114,12 +115,13 @@ where
})
}
/// Compute proof for a single STARK table.
fn prove_single_table<F, C, S, const D: usize>(
stark: &S,
config: &StarkConfig,
trace_poly_values: &[PolynomialValues<F>],
trace_commitment: &PolynomialBatch<F, C, D>,
lookup_data: &LookupData<F>,
ctl_data: &CtlData<F>,
public_inputs: &[F],
challenger: &mut Challenger<F, C::Hasher>,
timing: &mut TimingTree,
@ -157,9 +159,9 @@ where
let num_permutation_zs = permutation_zs.as_ref().map(|v| v.len()).unwrap_or(0);
let z_polys = match permutation_zs {
None => lookup_data.z_polys(),
None => ctl_data.z_polys(),
Some(mut permutation_zs) => {
permutation_zs.extend(lookup_data.z_polys());
permutation_zs.extend(ctl_data.z_polys());
permutation_zs
}
};
@ -182,24 +184,26 @@ where
}
let alphas = challenger.get_n_challenges(config.num_challenges);
test_it(
stark,
trace_commitment,
permutation_ctl_zs_commitment.as_ref(),
permutation_challenges.as_ref(),
lookup_data,
public_inputs,
alphas.clone(),
degree_bits,
num_permutation_zs,
config,
);
if cfg!(test) {
check_constraints(
stark,
trace_commitment,
permutation_ctl_zs_commitment.as_ref(),
permutation_challenges.as_ref(),
ctl_data,
public_inputs,
alphas.clone(),
degree_bits,
num_permutation_zs,
config,
);
}
let quotient_polys = compute_quotient_polys::<F, <F as Packable>::Packing, C, S, D>(
stark,
trace_commitment,
permutation_ctl_zs_commitment.as_ref(),
permutation_challenges.as_ref(),
lookup_data,
ctl_data,
public_inputs,
alphas,
degree_bits,
@ -241,7 +245,6 @@ where
"Opening point is in the subgroup."
);
// TODO: Add openings of lookup Z polynomials.
let openings = StarkOpeningSet::new(
zeta,
g,
@ -262,7 +265,7 @@ where
timing,
"compute openings proof",
PolynomialBatch::prove_openings(
&stark.fri_instance(zeta, g, degree_bits, lookup_data.len(), config),
&stark.fri_instance(zeta, g, degree_bits, ctl_data.len(), config),
&initial_merkle_trees,
challenger,
&fri_params,
@ -290,7 +293,7 @@ fn compute_quotient_polys<'a, F, P, C, S, const D: usize>(
trace_commitment: &'a PolynomialBatch<F, C, D>,
permutation_ctl_zs_commitment: Option<&'a PolynomialBatch<F, C, D>>,
permutation_challenges: Option<&'a Vec<GrandProductChallengeSet<F>>>,
lookup_data: &LookupData<F>,
ctl_data: &CtlData<F>,
public_inputs: &[F],
alphas: Vec<F>,
degree_bits: usize,
@ -377,7 +380,7 @@ where
} else {
None
};
let lookup_check_data = lookup_data
let ctl_vars = ctl_data
.zs_columns
.iter()
.enumerate()
@ -388,7 +391,7 @@ where
next_z: permutation_ctl_zs_commitment
.unwrap()
.get_lde_values_packed(i_next_start, step)[num_permutation_zs + i],
challenges: lookup_data.challenges.challenges[i % config.num_challenges],
challenges: ctl_data.challenges.challenges[i % config.num_challenges],
columns,
})
.collect::<Vec<_>>();
@ -397,7 +400,7 @@ where
config,
vars,
permutation_check_data,
&lookup_check_data,
&ctl_vars,
&mut consumer,
);
let mut constraints_evals = consumer.accumulators();
@ -417,12 +420,14 @@ where
.collect()
}
fn test_it<'a, F, C, S, const D: usize>(
/// Check that all constraints evaluate to zero on `H`.
/// Can also be used to check the degree of the constraints by evaluating on a larger subgroup.
fn check_constraints<'a, F, C, S, const D: usize>(
stark: &S,
trace_commitment: &'a PolynomialBatch<F, C, D>,
permutation_ctl_zs_commitment: Option<&'a PolynomialBatch<F, C, D>>,
permutation_challenges: Option<&'a Vec<GrandProductChallengeSet<F>>>,
lookup_data: &LookupData<F>,
ctl_data: &CtlData<F>,
public_inputs: &[F],
alphas: Vec<F>,
degree_bits: usize,
@ -434,23 +439,23 @@ fn test_it<'a, F, C, S, const D: usize>(
S: Stark<F, D>,
{
let degree = 1 << degree_bits;
let rate_bits = 0;
let rate_bits = 0; // Set this to higher value to check constraint degree.
let size = degree << rate_bits;
let step = 1 << rate_bits;
// Evaluation of the first Lagrange polynomial on the LDE domain.
// Evaluation of the first Lagrange polynomial.
let lagrange_first = PolynomialValues::selector(degree, 0).lde(rate_bits);
// Evaluation of the last Lagrange polynomial on the LDE domain.
// Evaluation of the last Lagrange polynomial.
let lagrange_last = PolynomialValues::selector(degree, degree - 1).lde(rate_bits);
let subgroup = F::two_adic_subgroup(degree_bits + rate_bits);
// Retrieve the LDE values at index `i`.
// Retrieve the polynomials values at index `i`.
let get_comm_values = |comm: &PolynomialBatch<F, C, D>, i| -> Vec<F> {
comm.polynomials
.iter()
.map(|poly| poly.eval(subgroup[i]))
.map(|poly| poly.eval(subgroup[i])) // O(n^2) FTW
.collect()
};
@ -493,7 +498,7 @@ fn test_it<'a, F, C, S, const D: usize>(
} else {
None
};
let lookup_check_data = lookup_data
let ctl_vars = ctl_data
.zs_columns
.iter()
.enumerate()
@ -502,7 +507,7 @@ fn test_it<'a, F, C, S, const D: usize>(
[num_permutation_zs + iii],
next_z: get_comm_values(permutation_ctl_zs_commitment.unwrap(), i_next)
[num_permutation_zs + iii],
challenges: lookup_data.challenges.challenges[iii % config.num_challenges],
challenges: ctl_data.challenges.challenges[iii % config.num_challenges],
columns,
})
.collect::<Vec<_>>();
@ -511,7 +516,7 @@ fn test_it<'a, F, C, S, const D: usize>(
config,
vars,
permutation_check_data,
&lookup_check_data,
&ctl_vars,
&mut consumer,
);
consumer.accumulators()

View File

@ -92,16 +92,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_lookup_zs_info = (num_permutation_batches + num_ctl_zs > 0).then(|| {
let permutation_lookup_index = oracle_indices.next().unwrap();
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_lookup_index,
permutation_ctl_index,
0..num_permutation_batches + num_ctl_zs,
)
});
let lookup_zs_info = (num_ctl_zs > 0).then(|| {
let index = permutation_lookup_zs_info
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());
@ -119,19 +119,19 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
let zeta_batch = FriBatchInfo {
point: zeta,
polynomials: once(trace_info.clone())
.chain(permutation_lookup_zs_info.clone())
.chain(permutation_ctl_zs_info.clone())
.chain(once(quotient_info))
.collect::<Vec<_>>()
.concat(),
};
let zeta_right_batch = FriBatchInfo {
point: zeta.scalar_mul(g),
polynomials: once(trace_info.clone())
.chain(permutation_lookup_zs_info.clone())
polynomials: once(trace_info)
.chain(permutation_ctl_zs_info)
.collect::<Vec<_>>()
.concat(),
};
let lookup_batch = lookup_zs_info.map(|info| FriBatchInfo {
let ctl_last_batch = ctl_zs_info.map(|info| FriBatchInfo {
point: F::Extension::primitive_root_of_unity(degree_bits).inverse(),
polynomials: info,
});
@ -139,7 +139,7 @@ pub trait Stark<F: RichField + Extendable<D>, const D: usize>: Sync {
oracles: vec![no_blinding_oracle; oracle_indices.next().unwrap()],
batches: once(zeta_batch)
.chain(once(zeta_right_batch))
.chain(lookup_batch)
.chain(ctl_last_batch)
.collect::<Vec<_>>(),
}
}

View File

@ -18,8 +18,8 @@ pub(crate) fn eval_vanishing_poly<F, FE, P, C, S, const D: usize, const D2: usiz
stark: &S,
config: &StarkConfig,
vars: StarkEvaluationVars<FE, P>,
permutation_data: Option<PermutationCheckVars<F, FE, P, D2>>,
lookup_data: &[CTLCheckVars<F, FE, P, D2>],
permutation_vars: Option<PermutationCheckVars<F, FE, P, D2>>,
ctl_vars: &[CTLCheckVars<F, FE, P, D2>],
consumer: &mut ConstraintConsumer<P>,
) where
F: RichField + Extendable<D>,
@ -29,16 +29,16 @@ pub(crate) fn eval_vanishing_poly<F, FE, P, C, S, const D: usize, const D2: usiz
S: Stark<F, D>,
{
stark.eval_packed_generic(vars, consumer);
if let Some(permutation_data) = permutation_data {
if let Some(permutation_vars) = permutation_vars {
eval_permutation_checks::<F, FE, P, C, S, D, D2>(
stark,
config,
vars,
permutation_data,
permutation_vars,
consumer,
);
}
eval_cross_table_lookup_checks::<F, FE, P, C, S, D, D2>(vars, lookup_data, consumer);
eval_cross_table_lookup_checks::<F, FE, P, C, S, D, D2>(vars, ctl_vars, consumer);
}
pub(crate) fn eval_vanishing_poly_recursively<F, C, S, const D: usize>(

View File

@ -76,27 +76,6 @@ where
)
}
// pub fn verify_stark_proof<
// F: RichField + Extendable<D>,
// C: GenericConfig<D, F = F>,
// S: Stark<F, D>,
// const D: usize,
// >(
// stark: S,
// proof_with_pis: StarkProofWithPublicInputs<F, C, D>,
// config: &StarkConfig,
// ) -> Result<()>
// where
// [(); S::COLUMNS]:,
// [(); S::PUBLIC_INPUTS]:,
// [(); C::Hasher::HASH_SIZE]:,
// {
// 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);
// verify_stark_proof_with_challenges(stark, proof_with_pis, challenges, degree_bits, config)
// }
pub(crate) fn verify_stark_proof_with_challenges<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
@ -106,7 +85,7 @@ pub(crate) fn verify_stark_proof_with_challenges<
stark: S,
proof_with_pis: &StarkProofWithPublicInputs<F, C, D>,
challenges: StarkProofChallenges<F, D>,
lookup_data: &[CTLCheckVars<F, F::Extension, F::Extension, D>],
ctl_vars: &[CTLCheckVars<F, F::Extension, F::Extension, D>],
config: &StarkConfig,
) -> Result<()>
where
@ -123,9 +102,9 @@ where
let StarkOpeningSet {
local_values,
next_values,
permutation_lookup_zs,
permutation_lookup_zs_right,
lookup_zs_last,
permutation_ctl_zs,
permutation_ctl_zs_right,
ctl_zs_last,
quotient_polys,
} = &proof.openings;
let vars = StarkEvaluationVars {
@ -154,8 +133,8 @@ where
);
let num_permutation_zs = stark.num_permutation_batches(config);
let permutation_data = stark.uses_permutation_args().then(|| PermutationCheckVars {
local_zs: permutation_lookup_zs.as_ref().unwrap()[..num_permutation_zs].to_vec(),
next_zs: permutation_lookup_zs_right.as_ref().unwrap()[..num_permutation_zs].to_vec(),
local_zs: permutation_ctl_zs.as_ref().unwrap()[..num_permutation_zs].to_vec(),
next_zs: permutation_ctl_zs_right.as_ref().unwrap()[..num_permutation_zs].to_vec(),
permutation_challenge_sets: challenges.permutation_challenge_sets.unwrap(),
});
eval_vanishing_poly::<F, F::Extension, F::Extension, C, S, D, D>(
@ -163,7 +142,7 @@ where
config,
vars,
permutation_data,
lookup_data,
ctl_vars,
&mut consumer,
);
let vanishing_polys_zeta = consumer.accumulators();
@ -196,7 +175,7 @@ where
challenges.stark_zeta,
F::primitive_root_of_unity(degree_bits),
degree_bits,
lookup_zs_last.len(),
ctl_zs_last.len(),
config,
),
&proof.openings.to_fri_openings(),
@ -236,15 +215,11 @@ fn check_permutation_options<
) -> 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_lookup_zs
.is_some(),
proof_with_pis
.proof
.openings
.permutation_lookup_zs_right
.permutation_ctl_zs_right
.is_some(),
challenges.permutation_challenge_sets.is_some(),
];