use super::{KeySchedule, RoundFunction};
pub struct MagmaKeySchedule;
impl KeySchedule<u32, [u32; 8]> for MagmaKeySchedule {
type State = usize;
fn new_state(&self, _master_key: &[u32; 8]) -> Self::State {
0
}
fn next_key(&self, master_key: &[u32; 8], state: &mut Self::State) -> u32 {
let round = *state;
let key = if round < 24 {
master_key[round % 8]
} else {
master_key[7 - (round % 8)]
};
*state += 1;
key
}
}
pub struct MagmaRF;
impl MagmaRF {
const SBOX: [[u8; 16]; 8] = [
[12, 4, 6, 2, 10, 5, 11, 9, 14, 8, 13, 7, 0, 3, 15, 1],
[6, 8, 2, 3, 9, 10, 5, 12, 1, 14, 4, 7, 11, 13, 0, 15],
[11, 3, 5, 8, 2, 15, 10, 13, 14, 1, 7, 4, 12, 9, 6, 0],
[12, 8, 2, 1, 13, 4, 15, 6, 7, 0, 10, 5, 3, 14, 9, 11],
[7, 15, 5, 10, 8, 1, 6, 13, 0, 9, 3, 14, 11, 4, 2, 12],
[5, 13, 15, 6, 9, 2, 12, 10, 11, 7, 8, 1, 4, 3, 14, 0],
[8, 14, 2, 5, 6, 9, 1, 12, 15, 4, 11, 0, 13, 10, 3, 7],
[1, 7, 14, 13, 0, 5, 8, 3, 4, 15, 10, 6, 9, 12, 11, 2],
];
fn t(value: u32) -> u32 {
let mut result = 0u32;
for i in 0..8 {
let shift = (7 - i) * 4;
let nibble = ((value >> shift) & 0xF) as usize;
let sbox_index = 7 - i;
let substituted = Self::SBOX[sbox_index][nibble] as u32;
result |= substituted << shift;
}
result
}
}
impl RoundFunction<u32> for MagmaRF {
fn f(&self, right: &u32, round_key: &u32) -> u32 {
let value = right.wrapping_add(*round_key);
MagmaRF::t(value).rotate_left(11)
}
}
include!("magma_sbox.rs");
#[cfg(test)]
#[path = "magma_test.rs"]
mod magma_test;