use crate::{Block, SkipjackKey, Word, SBOX};
pub(crate) fn word_to_bytes(word: Word) -> (u8, u8) {
((word >> 8) as u8, word as u8)
}
pub(crate) fn bytes_to_word(bytes: (u8, u8)) -> u16 {
((bytes.0 as u16) << 8) | bytes.1 as u16
}
pub(crate) fn g_permutation(key: &SkipjackKey, word: Word, step: u16) -> Word {
let (g1, g2): (u8, u8) = word_to_bytes(word);
let g3: u8 = SBOX[(g2 ^ key[((4 * step) % 10) as usize]) as usize] ^ g1;
let g4: u8 = SBOX[(g3 ^ key[(((4 * step) + 1) % 10) as usize]) as usize] ^ g2;
let g5: u8 = SBOX[(g4 ^ key[(((4 * step) + 2) % 10) as usize]) as usize] ^ g3;
let g6: u8 = SBOX[(g5 ^ key[(((4 * step) + 3) % 10) as usize]) as usize] ^ g4;
bytes_to_word((g5, g6))
}
pub(crate) fn inv_g_permutation(key: &SkipjackKey, word: Word, step: u16) -> Word {
let (g5, g6): (u8, u8) = word_to_bytes(word);
let g4: u8 = SBOX[(g5 ^ key[(((4 * step) + 3) % 10) as usize]) as usize] ^ g6;
let g3: u8 = SBOX[(g4 ^ key[(((4 * step) + 2) % 10) as usize]) as usize] ^ g5;
let g2: u8 = SBOX[(g3 ^ key[(((4 * step) + 1) % 10) as usize]) as usize] ^ g4;
let g1: u8 = SBOX[(g2 ^ key[((4 * step) % 10) as usize]) as usize] ^ g3;
bytes_to_word((g1, g2))
}
pub(crate) fn rule_a(key: &SkipjackKey, words: &mut Block, counter: &mut u16) {
let orig_words: Block = words.clone();
words[0] = g_permutation(key, orig_words[0], *counter - 1) ^ orig_words[3] ^ *counter;
words[1] = g_permutation(key, orig_words[0], *counter - 1);
words[2] = orig_words[1];
words[3] = orig_words[2];
}
pub(crate) fn inv_rule_a(key: &SkipjackKey, words: &mut Block, counter: &mut u16) {
let orig_words: Block = words.clone();
words[0] = inv_g_permutation(key, orig_words[1], *counter - 1);
words[1] = orig_words[2];
words[2] = orig_words[3];
words[3] = orig_words[0] ^ orig_words[1] ^ *counter;
}
pub(crate) fn rule_b(key: &SkipjackKey, words: &mut Block, counter: &mut u16) {
let orig_words: Block = words.clone();
words[0] = orig_words[3];
words[1] = g_permutation(key, orig_words[0], *counter - 1);
words[2] = orig_words[0] ^ orig_words[1] ^ *counter;
words[3] = orig_words[2];
}
pub(crate) fn inv_rule_b(key: &SkipjackKey, words: &mut Block, counter: &mut u16) {
let orig_words: Block = words.clone();
words[0] = inv_g_permutation(key, orig_words[1], *counter - 1);
words[1] = inv_g_permutation(key, orig_words[1], *counter - 1) ^ orig_words[2] ^ *counter;
words[2] = orig_words[3];
words[3] = orig_words[0];
}