use crate::variations::*;
use core::ops::Add;
pub const BUF_LEN_U8: usize = MATRIX_SIZE_U8 * DEPTH;
pub const BUF_LEN_U64: usize = BUF_LEN_U8 / size_of::<u64>();
pub const COLUMNS: usize = 4;
pub const ROWS: usize = 4;
pub const SEED_LEN_U8: usize = (ROWS - 1) * size_of::<Row>();
pub const SEED_LEN_U32: usize = SEED_LEN_U8 / size_of::<u32>();
pub const SEED_LEN_U64: usize = SEED_LEN_U8 / size_of::<u64>();
pub const MATRIX_SIZE_U8: usize = MATRIX_SIZE_U32 * size_of::<u32>();
pub const MATRIX_SIZE_U32: usize = COLUMNS * ROWS;
pub const DEPTH: usize = 4;
pub const ROW_A: Row = Row {
u8x16: *b"expand 32-byte k",
};
#[derive(Clone, Copy)]
#[repr(C, align(16))]
pub union Row {
pub u8x16: [u8; 16],
pub u16x8: [u16; 8],
pub u32x4: [u32; 4],
pub u64x2: [u64; 2],
}
#[repr(C)]
pub struct ChaChaNaked {
pub row_b: Row,
pub row_c: Row,
pub row_d: Row,
}
pub trait Machine: Add<Output = Self> + Clone {
#[inline]
fn new<V: Variant>(state: &ChaChaNaked) -> Self {
match V::VAR {
Variants::Djb => Self::new_djb(state),
Variants::Ietf => Self::new_ietf(state),
}
}
fn new_djb(state: &ChaChaNaked) -> Self;
fn new_ietf(state: &ChaChaNaked) -> Self;
#[inline]
fn increment<V: Variant>(&mut self) {
match V::VAR {
Variants::Djb => self.increment_djb(),
Variants::Ietf => self.increment_ietf(),
}
}
fn increment_djb(&mut self);
fn increment_ietf(&mut self);
fn double_round(&mut self);
fn fetch_result(self, buf: &mut [u8; BUF_LEN_U8]);
#[inline]
fn xor_result(self, buf: &mut [u8; BUF_LEN_U8]) {
let mut tmp = [0; BUF_LEN_U8];
self.fetch_result(&mut tmp);
for i in 0..BUF_LEN_U8 {
buf[i] ^= tmp[i];
}
}
}