use super::InputLayout;
use crate::EXT_DEGREE;
const AIR_SELECTOR_FIRST_OFFSET: usize = 0;
const AIR_SELECTOR_LAST_OFFSET: usize = 1;
const AIR_SELECTOR_TRANSITION_OFFSET: usize = 2;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum InputKey {
Public(usize),
AuxRandAlpha,
AuxRandBeta,
MultiAirFoldBeta,
MultiAirFoldCoeff(usize),
Preprocessed { offset: usize, index: usize },
Main { offset: usize, index: usize },
AuxCoord {
offset: usize,
index: usize,
coord: usize,
},
AuxBusBoundary(usize),
Reserved,
Alpha,
ZPowN,
ZK,
IsFirst,
IsLast,
IsTransition,
IsFirstAir(usize),
IsLastAir(usize),
IsTransitionAir(usize),
Weight0,
F,
S0,
QuotientChunkCoord {
offset: usize,
chunk: usize,
coord: usize,
},
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct InputKeyMapper<'a> {
pub(super) layout: &'a InputLayout,
}
impl InputKeyMapper<'_> {
pub(crate) fn index_of(self, key: InputKey) -> Option<usize> {
let layout = self.layout;
match key {
InputKey::Public(i) => layout.regions.public_values.index(i),
InputKey::AuxRandAlpha => Some(layout.aux_rand_alpha),
InputKey::AuxRandBeta => Some(layout.aux_rand_beta),
InputKey::MultiAirFoldBeta => layout.stark.multi_air_fold_beta_index(),
InputKey::MultiAirFoldCoeff(_) => None,
InputKey::Preprocessed { offset, index } => match offset {
0 => layout.regions.preprocessed_curr.index(index),
1 => layout.regions.preprocessed_next.index(index),
_ => None,
},
InputKey::Main { offset, index } => match offset {
0 => layout.regions.main_curr.index(index),
1 => layout.regions.main_next.index(index),
_ => None,
},
InputKey::AuxCoord { offset, index, coord } => {
if index >= layout.counts.aux_width || coord >= EXT_DEGREE {
return None;
}
let local = index * EXT_DEGREE + coord;
match offset {
0 => layout.regions.aux_curr.index(local),
1 => layout.regions.aux_next.index(local),
_ => None,
}
},
InputKey::AuxBusBoundary(i) => layout.regions.aux_bus_boundary.index(i),
InputKey::Reserved => Some(layout.stark.reserved),
InputKey::Alpha => Some(layout.stark.alpha),
InputKey::ZPowN => Some(layout.stark.z_pow_n),
InputKey::ZK => Some(layout.stark.z_k),
InputKey::IsFirst => Some(layout.stark.is_first),
InputKey::IsLast => Some(layout.stark.is_last),
InputKey::IsTransition => Some(layout.stark.is_transition),
InputKey::IsFirstAir(i) => {
layout.stark.air_selector_index(i, AIR_SELECTOR_FIRST_OFFSET)
},
InputKey::IsLastAir(i) => layout.stark.air_selector_index(i, AIR_SELECTOR_LAST_OFFSET),
InputKey::IsTransitionAir(i) => {
layout.stark.air_selector_index(i, AIR_SELECTOR_TRANSITION_OFFSET)
},
InputKey::Weight0 => Some(layout.stark.weight0),
InputKey::F => Some(layout.stark.f),
InputKey::S0 => Some(layout.stark.s0),
InputKey::QuotientChunkCoord { offset, chunk, coord } => {
if chunk >= layout.counts.num_quotient_chunks || coord >= EXT_DEGREE {
return None;
}
let idx = chunk * EXT_DEGREE + coord;
match offset {
0 => layout.regions.quotient_curr.index(idx),
1 => layout.regions.quotient_next.index(idx),
_ => None,
}
},
}
}
}