use crate::utils::{
get_2bytes_at_bit,
get_4bytes_at_bit,
};
use crate::traits::{
Xfsr,
Accumulator,
};
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
pub struct GrainLfsr {
pub(crate) state: u128,
}
impl GrainLfsr {
pub fn new(initial_state: u128) -> GrainLfsr {
GrainLfsr {
state: initial_state,
}
}
}
impl Xfsr<u16> for GrainLfsr {
fn get_state(&self) -> u128 {
self.state
}
fn set_state(&mut self, new_value: u128) {
self.state = new_value;
}
fn feedback_function(&self) -> u128 {
(get_2bytes_at_bit(&self.state, 0) ^
get_2bytes_at_bit(&self.state, 7) ^
get_2bytes_at_bit(&self.state, 38) ^
get_2bytes_at_bit(&self.state, 70) ^
get_2bytes_at_bit(&self.state, 81) ^
get_2bytes_at_bit(&self.state, 96)) as u128
}
}
impl Xfsr<u32> for GrainLfsr {
fn get_state(&self) -> u128 {
self.state
}
fn set_state(&mut self, new_value: u128) {
self.state = new_value;
}
fn feedback_function(&self) -> u128 {
(get_4bytes_at_bit(&self.state, 0) ^
get_4bytes_at_bit(&self.state, 7) ^
get_4bytes_at_bit(&self.state, 38) ^
get_4bytes_at_bit(&self.state, 70) ^
get_4bytes_at_bit(&self.state, 81) ^
get_4bytes_at_bit(&self.state, 96)) as u128
}
}
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
pub struct GrainNfsr {
pub(crate) state: u128,
}
impl GrainNfsr {
pub fn new(initial_state: u128) -> Self {
GrainNfsr {
state: initial_state,
}
}
pub fn xor_last_2bytes(&mut self, bytes: u16) {
self.state ^= (bytes as u128) << 112;
}
pub fn xor_last_4bytes(&mut self, bytes: u32) {
self.state ^= (bytes as u128) << 96;
}
}
impl Xfsr<u16> for GrainNfsr {
fn get_state(&self) -> u128 {
self.state
}
fn set_state(&mut self, new_value: u128) {
self.state = new_value;
}
fn feedback_function(&self) -> u128 {
let output = (get_2bytes_at_bit(&self.state, 0) ^
get_2bytes_at_bit(&self.state, 26) ^
get_2bytes_at_bit(&self.state, 56) ^
get_2bytes_at_bit(&self.state, 91) ^
get_2bytes_at_bit(&self.state, 96) ^
get_2bytes_at_bit(&self.state, 3) & get_2bytes_at_bit(&self.state, 67) ^
get_2bytes_at_bit(&self.state, 11) & get_2bytes_at_bit(&self.state, 13) ^
get_2bytes_at_bit(&self.state, 17) & get_2bytes_at_bit(&self.state, 18) ^
get_2bytes_at_bit(&self.state, 27) & get_2bytes_at_bit(&self.state, 59) ^
get_2bytes_at_bit(&self.state, 40) & get_2bytes_at_bit(&self.state, 48) ^
get_2bytes_at_bit(&self.state, 61) & get_2bytes_at_bit(&self.state, 65) ^
get_2bytes_at_bit(&self.state, 68) & get_2bytes_at_bit(&self.state, 84) ^
(
get_2bytes_at_bit(&self.state, 22) &
get_2bytes_at_bit(&self.state, 24) &
get_2bytes_at_bit(&self.state, 25)
) ^
(
get_2bytes_at_bit(&self.state, 70) &
get_2bytes_at_bit(&self.state, 78) &
get_2bytes_at_bit(&self.state, 82)
) ^
(
get_2bytes_at_bit(&self.state, 88) &
get_2bytes_at_bit(&self.state, 92) &
get_2bytes_at_bit(&self.state, 93) &
get_2bytes_at_bit(&self.state, 95)
)) as u128;
debug_assert!(output < (1u128 << 16));
output
}
}
impl Xfsr<u32> for GrainNfsr {
fn get_state(&self) -> u128 {
self.state
}
fn set_state(&mut self, new_value: u128) {
self.state = new_value;
}
fn feedback_function(&self) -> u128 {
let output = (get_4bytes_at_bit(&self.state, 0) ^
get_4bytes_at_bit(&self.state, 26) ^
get_4bytes_at_bit(&self.state, 56) ^
get_4bytes_at_bit(&self.state, 91) ^
get_4bytes_at_bit(&self.state, 96) ^
get_4bytes_at_bit(&self.state, 3) & get_4bytes_at_bit(&self.state, 67) ^
get_4bytes_at_bit(&self.state, 11) & get_4bytes_at_bit(&self.state, 13) ^
get_4bytes_at_bit(&self.state, 17) & get_4bytes_at_bit(&self.state, 18) ^
get_4bytes_at_bit(&self.state, 27) & get_4bytes_at_bit(&self.state, 59) ^
get_4bytes_at_bit(&self.state, 40) & get_4bytes_at_bit(&self.state, 48) ^
get_4bytes_at_bit(&self.state, 61) & get_4bytes_at_bit(&self.state, 65) ^
get_4bytes_at_bit(&self.state, 68) & get_4bytes_at_bit(&self.state, 84) ^
(
get_4bytes_at_bit(&self.state, 22) &
get_4bytes_at_bit(&self.state, 24) &
get_4bytes_at_bit(&self.state, 25)
) ^
(
get_4bytes_at_bit(&self.state, 70) &
get_4bytes_at_bit(&self.state, 78) &
get_4bytes_at_bit(&self.state, 82)
) ^
(
get_4bytes_at_bit(&self.state, 88) &
get_4bytes_at_bit(&self.state, 92) &
get_4bytes_at_bit(&self.state, 93) &
get_4bytes_at_bit(&self.state, 95)
)) as u128;
debug_assert!(output < (1u128 << 32));
output
}
}
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
pub struct GrainAuthAccumulator {
pub(crate) state: u64,
}
impl GrainAuthAccumulator {
pub(crate) fn new() -> GrainAuthAccumulator {
GrainAuthAccumulator { state: 0u64 }
}
}
#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
pub struct GrainAuthRegister {
pub(crate) state: u64,
}
impl Accumulator<u8> for GrainAuthRegister {
fn accumulate(&mut self, new: u8) -> u8 {
let output = self.state & 1;
self.state >>= 1;
self.state |= (new as u64) << 63;
output as u8
}
fn new() -> GrainAuthRegister {
GrainAuthRegister { state: 0u64 }
}
}