#![no_std]
pub struct LeeKoq;
impl LeeKoq {
pub const LUT: u32 = 0x3A5C742E;
pub fn encrypt(mut block: u32, mut key: u64) -> u32 {
for _ in 0..528 {
let lutkey = (block >> 1) & 1 | (block >> 8) & 2 | (block >> 18) & 4 | (block >> 23) & 8 | (block >> 27) & 16;
let msb = (block >> 16 & 1) ^ (block & 1) ^ (Self::LUT >> lutkey & 1) ^ ((key & 1) as u32);
block = msb << 31 | block >> 1;
key = (key & 1) << 63 | key >> 1;
}
block
}
pub fn decrypt(mut block: u32, mut key: u64) -> u32 {
for _ in 0..528 {
let lutkey = (block >> 0) & 1 | (block >> 7) & 2 | (block >> 17) & 4 | (block >> 22) & 8 | (block >> 26) & 16;
let lsb = (block >> 31) ^ (block >> 15 & 1) ^ (Self::LUT >> lutkey & 1) ^ ((key >> 15 & 1) as u32);
block = (block & 0x7FFFFFFF) << 1 | lsb;
key = (key & 0x7FFFFFFFFFFFFFFF) << 1 | key >> 63;
}
block
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encrypt() {
assert_eq!(LeeKoq::encrypt(0xf741e2db, 0x5cec6701b79fd949), 0xe44f4cdf);
assert_eq!(LeeKoq::encrypt(0x0ca69b92, 0x5cec6701b79fd949), 0xa6ac0ea2);
assert_eq!(LeeKoq::encrypt(0x12345678, 0xCAFED00D), 0xD0FB287C);
}
#[test]
fn decrypt() {
assert_eq!(LeeKoq::decrypt(0xe44f4cdf, 0x5cec6701b79fd949), 0xf741e2db);
assert_eq!(LeeKoq::decrypt(0xa6ac0ea2, 0x5cec6701b79fd949), 0x0ca69b92);
assert_eq!(LeeKoq::decrypt(0xD0FB287C, 0xCAFED00D), 0x12345678);
}
}