use crate::{round_constants::ROUND_CONSTANTS, PARTIAL_ROUNDS, TOTAL_FULL_ROUNDS};
use dusk_bls12_381::BlsScalar;
#[cfg(feature = "plonk")]
mod gadget;
mod scalar;
#[cfg(feature = "plonk")]
pub use gadget::GadgetStrategy;
pub use scalar::ScalarStrategy;
pub trait Strategy<T: Clone + Copy> {
fn next_c<'b, I>(constants: &mut I) -> BlsScalar
where
I: Iterator<Item = &'b BlsScalar>,
{
constants
.next()
.copied()
.expect("Hades252 out of ARK constants")
}
fn add_round_key<'b, I>(&mut self, constants: &mut I, words: &mut [T])
where
I: Iterator<Item = &'b BlsScalar>;
fn quintic_s_box(&mut self, value: &mut T);
fn mul_matrix<'b, I>(&mut self, constants: &mut I, values: &mut [T])
where
I: Iterator<Item = &'b BlsScalar>;
fn apply_partial_round<'b, I>(&mut self, constants: &mut I, words: &mut [T])
where
I: Iterator<Item = &'b BlsScalar>,
{
let last = words.len() - 1;
self.add_round_key(constants, words);
self.quintic_s_box(&mut words[last]);
self.mul_matrix(constants, words);
}
fn apply_full_round<'a, I>(&mut self, constants: &mut I, words: &mut [T])
where
I: Iterator<Item = &'a BlsScalar>,
{
self.add_round_key(constants, words);
words.iter_mut().for_each(|w| self.quintic_s_box(w));
self.mul_matrix(constants, words);
}
fn perm(&mut self, data: &mut [T]) {
let mut constants = ROUND_CONSTANTS.iter();
for _ in 0..TOTAL_FULL_ROUNDS / 2 {
self.apply_full_round(&mut constants, data);
}
for _ in 0..PARTIAL_ROUNDS {
self.apply_partial_round(&mut constants, data);
}
for _ in 0..TOTAL_FULL_ROUNDS / 2 {
self.apply_full_round(&mut constants, data);
}
}
fn rounds() -> usize {
TOTAL_FULL_ROUNDS + PARTIAL_ROUNDS
}
}