use ark_ff::Field;
use kimchi::circuits::expr::{AlphaChallengeTerm, CacheId, ConstantExpr, Expr, FormattedOutput};
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fmt::{Display, Formatter, Result},
ops::Index,
};
use strum_macros::{EnumCount as EnumCountMacro, EnumIter};
#[derive(Debug, Clone, Copy, PartialEq, EnumCountMacro, EnumIter)]
pub enum Gadget {
App,
EllipticCurveAddition,
EllipticCurveScaling,
Poseidon,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Column {
Selector(Gadget),
PublicInput(usize),
X(usize),
}
pub struct Challenges<F: Field> {
pub alpha: F,
pub beta: F,
pub gamma: F,
pub homogenous_challenge: F,
pub r: F,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ChallengeTerm {
Alpha,
Beta,
Gamma,
HomogenousChallenge,
R,
}
impl Display for ChallengeTerm {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
ChallengeTerm::Alpha => write!(f, "alpha"),
ChallengeTerm::Beta => write!(f, "beta"),
ChallengeTerm::Gamma => write!(f, "gamma"),
ChallengeTerm::HomogenousChallenge => write!(f, "u"),
ChallengeTerm::R => write!(f, "r"),
}
}
}
impl<F: Field> Index<ChallengeTerm> for Challenges<F> {
type Output = F;
fn index(&self, term: ChallengeTerm) -> &Self::Output {
match term {
ChallengeTerm::Alpha => &self.alpha,
ChallengeTerm::Beta => &self.beta,
ChallengeTerm::Gamma => &self.gamma,
ChallengeTerm::HomogenousChallenge => &self.homogenous_challenge,
ChallengeTerm::R => &self.r,
}
}
}
impl<'a> AlphaChallengeTerm<'a> for ChallengeTerm {
const ALPHA: Self = Self::Alpha;
}
pub type E<Fp> = Expr<ConstantExpr<Fp, ChallengeTerm>, Column>;
impl FormattedOutput for Column {
fn latex(&self, _cache: &mut HashMap<CacheId, Self>) -> String {
match self {
Column::Selector(sel) => match sel {
Gadget::App => "q_app".to_string(),
Gadget::EllipticCurveAddition => "q_ec_add".to_string(),
Gadget::EllipticCurveScaling => "q_ec_mul".to_string(),
Gadget::Poseidon => "q_pos".to_string(),
},
Column::PublicInput(i) => format!("pi_{{{i}}}").to_string(),
Column::X(i) => format!("x_{{{i}}}").to_string(),
}
}
fn text(&self, _cache: &mut HashMap<CacheId, Self>) -> String {
match self {
Column::Selector(sel) => match sel {
Gadget::App => "q_app".to_string(),
Gadget::EllipticCurveAddition => "q_ec_add".to_string(),
Gadget::EllipticCurveScaling => "q_ec_mul".to_string(),
Gadget::Poseidon => "q_pos_next_row".to_string(),
},
Column::PublicInput(i) => format!("pi[{i}]"),
Column::X(i) => format!("x[{i}]"),
}
}
fn ocaml(&self, _cache: &mut HashMap<CacheId, Self>) -> String {
unimplemented!("Not used at the moment")
}
fn is_alpha(&self) -> bool {
unimplemented!("Not used at the moment")
}
}