use crate::{Block, Key, ParBlocks, Tag, field_element::FieldElement};
#[cfg_attr(target_arch = "aarch64", path = "intrinsics/armv8.rs")]
#[cfg_attr(
any(target_arch = "x86", target_arch = "x86_64"),
path = "intrinsics/x86.rs"
)]
mod intrinsics_impl;
use intrinsics_impl::InitToken;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
#[derive(Clone)]
pub(crate) struct State {
expanded_key: ExpandedKey,
acc: FieldElement,
init_token: InitToken,
}
impl State {
pub(crate) fn new(h: &Key) -> Self {
let (init_token, has_intrinsics) = InitToken::init_get();
let expanded_key = if has_intrinsics {
unsafe { intrinsics_impl::expand_key(&h.0) }
} else {
ExpandedKey {
h1: FieldElement::from(*h),
..Default::default()
}
};
let y = FieldElement::default();
Self {
expanded_key,
acc: y,
init_token,
}
}
pub(crate) fn proc_block(&mut self, block: &Block) {
self.acc = if self.has_intrinsics() {
unsafe { intrinsics_impl::proc_block(&self.expanded_key, self.acc, block) }
} else {
(self.acc + block.into()) * self.expanded_key.h1
};
}
pub(crate) fn proc_par_blocks(&mut self, par_blocks: &ParBlocks) {
if self.has_intrinsics() {
self.acc = unsafe {
intrinsics_impl::proc_par_blocks(&self.expanded_key, self.acc, par_blocks)
};
} else {
for block in par_blocks {
self.proc_block(block);
}
}
}
pub(crate) fn finalize(&self) -> Tag {
self.acc.into()
}
pub(crate) fn reset(&mut self) {
self.acc = FieldElement::default();
}
#[inline]
fn has_intrinsics(&self) -> bool {
self.init_token.get()
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for State {
fn zeroize(&mut self) {
self.expanded_key.zeroize();
self.acc.zeroize();
}
}
#[derive(Clone, Default)]
pub(crate) struct ExpandedKey {
h1: FieldElement,
d1: FieldElement,
h2: FieldElement,
d2: FieldElement,
h3: FieldElement,
d3: FieldElement,
h4: FieldElement,
d4: FieldElement,
}
#[cfg(feature = "zeroize")]
impl Zeroize for ExpandedKey {
fn zeroize(&mut self) {
self.h1.zeroize();
self.d1.zeroize();
self.h2.zeroize();
self.d2.zeroize();
self.h3.zeroize();
self.d3.zeroize();
self.h4.zeroize();
self.d4.zeroize();
}
}