macro_rules! mix {
($b:ident, $rotation:expr, $x:literal, $y:literal) => {
$b[$x] = $b[$x].wrapping_add($b[$y]);
$b[$y] = $b[$y].rotate_left($rotation) ^ $b[$x];
};
}
macro_rules! unmix {
($b:ident, $rotation:expr, $x:literal, $y:literal) => {
$b[$y] = ($b[$y] ^ $b[$x]).rotate_right($rotation);
$b[$x] = $b[$x].wrapping_sub($b[$y]);
};
}
pub(crate) mod threefish1024;
pub(crate) mod threefish256;
pub(crate) mod threefish512;
pub(crate) const C_240: u64 = 0x1bd1_1bda_a9fc_1a22;
pub(crate) const fn valid_word_count(words: usize) -> bool {
matches!(words, 4 | 8 | 16)
}
#[inline(always)]
fn inject<const W: usize, const KW: usize>(
b: &mut [u64; W],
kw: &[u64; KW],
t: &[u64; 5],
k: usize,
s: usize,
counter: usize,
) {
for (i, word) in b.iter_mut().enumerate() {
*word = word.wrapping_add(kw[k + i]);
}
b[W - 3] = b[W - 3].wrapping_add(t[s]);
b[W - 2] = b[W - 2].wrapping_add(t[s + 1]);
b[W - 1] = b[W - 1].wrapping_add(counter as u64);
}
#[inline(always)]
fn eject<const W: usize, const KW: usize>(
b: &mut [u64; W],
kw: &[u64; KW],
t: &[u64; 5],
k: usize,
s: usize,
counter: usize,
) {
for (i, word) in b.iter_mut().enumerate() {
*word = word.wrapping_sub(kw[k + i]);
}
b[W - 3] = b[W - 3].wrapping_sub(t[s]);
b[W - 2] = b[W - 2].wrapping_sub(t[s + 1]);
b[W - 1] = b[W - 1].wrapping_sub(counter as u64);
}
#[inline(always)]
fn fixed<'a, const W: usize, const KW: usize>(
kw: &'a [u64],
block: &'a mut [u64],
) -> (&'a [u64; KW], &'a mut [u64; W]) {
(
kw.try_into().expect("the schedule holds 2 * W + 1 words"),
block.try_into().expect("the block holds W words"),
)
}