use ethereum_types::U256; mod add; mod compare; mod modular; mod mul; mod sub; mod utils; pub mod arithmetic_stark; pub(crate) mod columns; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub(crate) enum BinaryOperator { Add, Mul, Sub, Div, Mod, Lt, Gt, Shl, Shr, } impl BinaryOperator { pub(crate) fn result(&self, input0: U256, input1: U256) -> U256 { match self { BinaryOperator::Add => input0 + input1, BinaryOperator::Mul => input0 * input1, BinaryOperator::Sub => input0 - input1, BinaryOperator::Div => input0 / input1, BinaryOperator::Mod => input0 % input1, BinaryOperator::Lt => { if input0 < input1 { U256::one() } else { U256::zero() } } BinaryOperator::Gt => { if input0 > input1 { U256::one() } else { U256::zero() } } BinaryOperator::Shl => input0 << input1, BinaryOperator::Shr => input0 >> input1, } } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub(crate) enum TernaryOperator { AddMod, MulMod, } impl TernaryOperator { pub(crate) fn result(&self, input0: U256, input1: U256, input2: U256) -> U256 { match self { TernaryOperator::AddMod => (input0 + input1) % input2, TernaryOperator::MulMod => (input0 * input1) % input2, } } } #[derive(Debug)] pub(crate) enum Operation { BinaryOperation { operator: BinaryOperator, input0: U256, input1: U256, result: U256, }, TernaryOperation { operator: TernaryOperator, input0: U256, input1: U256, input2: U256, result: U256, }, } impl Operation { pub(crate) fn binary(operator: BinaryOperator, input0: U256, input1: U256) -> Self { let result = operator.result(input0, input1); Self::BinaryOperation { operator, input0, input1, result, } } pub(crate) fn ternary( operator: TernaryOperator, input0: U256, input1: U256, input2: U256, ) -> Self { let result = operator.result(input0, input1, input2); Self::TernaryOperation { operator, input0, input1, input2, result, } } pub(crate) fn result(&self) -> U256 { match self { Operation::BinaryOperation { result, .. } => *result, Operation::TernaryOperation { result, .. } => *result, } } }