#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use itertools::Itertools;
use crate::{Element, Expression, Field, GadgetBuilder, WireValues};
pub trait BlockCipher<F: Field> {
fn encrypt(&self, builder: &mut GadgetBuilder<F>, key: &Expression<F>, input: &Expression<F>)
-> Expression<F>;
fn decrypt(&self, builder: &mut GadgetBuilder<F>, key: &Expression<F>, output: &Expression<F>)
-> Expression<F>;
fn encrypt_evaluate(&self, key: &Element<F>, input: &Element<F>) -> Element<F> {
let mut builder = GadgetBuilder::new();
let encrypted = self.encrypt(
&mut builder, &Expression::from(key), &Expression::from(input));
let mut values = WireValues::new();
builder.build().execute(&mut values);
encrypted.evaluate(&values)
}
fn decrypt_evaluate(&self, key: &Element<F>, output: &Element<F>) -> Element<F> {
let mut builder = GadgetBuilder::new();
let decrypted = self.decrypt(
&mut builder, &Expression::from(key), &Expression::from(output));
let mut values = WireValues::new();
builder.build().execute(&mut values);
decrypted.evaluate(&values)
}
}
pub trait CompressionFunction<F: Field> {
fn compress(&self, builder: &mut GadgetBuilder<F>, x: &Expression<F>, y: &Expression<F>)
-> Expression<F>;
fn compress_evaluate(&self, x: &Element<F>, y: &Element<F>) -> Element<F> {
let mut builder = GadgetBuilder::new();
let compressed = self.compress(&mut builder, &Expression::from(x), &Expression::from(y));
let mut values = WireValues::new();
builder.build().execute(&mut values);
compressed.evaluate(&values)
}
}
pub trait Permutation<F: Field> {
fn permute(&self, builder: &mut GadgetBuilder<F>, x: &Expression<F>) -> Expression<F>;
fn permute_evaluate(&self, x: &Element<F>) -> Element<F> {
let mut builder = GadgetBuilder::new();
let permuted = self.permute(&mut builder, &Expression::from(x));
let mut values = WireValues::new();
builder.build().execute(&mut values);
permuted.evaluate(&values)
}
fn inverse(&self, builder: &mut GadgetBuilder<F>, x: &Expression<F>) -> Expression<F>;
fn inverse_evaluate(&self, x: &Element<F>) -> Element<F> {
let mut builder = GadgetBuilder::new();
let inverse = self.inverse(&mut builder, &Expression::from(x));
let mut values = WireValues::new();
builder.build().execute(&mut values);
inverse.evaluate(&values)
}
}
pub trait MultiPermutation<F: Field> {
fn width(&self) -> usize;
fn permute(&self, builder: &mut GadgetBuilder<F>, inputs: &[Expression<F>])
-> Vec<Expression<F>>;
fn permute_evaluate(&self, inputs: &[Element<F>]) -> Vec<Element<F>> {
let mut builder = GadgetBuilder::new();
let input_expressions = inputs.iter().map(Expression::from).collect_vec();
let permuted = self.permute(&mut builder, &input_expressions);
let mut values = WireValues::new();
builder.build().execute(&mut values);
permuted.iter().map(|exp| exp.evaluate(&values)).collect()
}
fn inverse(&self, builder: &mut GadgetBuilder<F>, outputs: &[Expression<F>])
-> Vec<Expression<F>>;
fn inverse_evaluate(&self, outputs: &[Element<F>]) -> Vec<Element<F>> {
let mut builder = GadgetBuilder::new();
let output_expressions = outputs.iter().map(Expression::from).collect_vec();
let inversed = self.inverse(&mut builder, &output_expressions);
let mut values = WireValues::new();
builder.build().execute(&mut values);
inversed.iter().map(|exp| exp.evaluate(&values)).collect()
}
}
pub trait HashFunction<F: Field> {
fn hash(&self, builder: &mut GadgetBuilder<F>, blocks: &[Expression<F>]) -> Expression<F>;
fn hash_evaluate(&self, blocks: &[Element<F>]) -> Element<F> {
let mut builder = GadgetBuilder::new();
let block_expressions = blocks.iter().map(Expression::from).collect_vec();
let hash = self.hash(&mut builder, &block_expressions);
let mut values = WireValues::new();
builder.build().execute(&mut values);
hash.evaluate(&values)
}
}