1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
#![no_std] extern crate byteorder; use byteorder::{ ByteOrder, LittleEndian }; #[cfg(feature = "x64_128")] pub mod params { pub const BLOCK_BYTES: usize = 64 / 8; pub const KEY_BYTES: usize = 128 / 8; pub type SubKey = [[u32; ROUNDS_PER_STEP]; BRANCHES * STEPS + 1]; pub const BLOCK_SIZE: usize = BLOCK_BYTES / 4; pub const KEY_SIZE: usize = KEY_BYTES / 4; const ROUNDS: usize = 24; pub(crate) const ROUNDS_PER_STEP: usize = ROUNDS / STEPS; pub(crate) const STEPS: usize = 8; pub(crate) const BRANCHES: usize = 2; } #[cfg(feature = "x128_128")] pub mod params { pub const BLOCK_BYTES: usize = 128 / 8; pub const KEY_BYTES: usize = 128 / 8; pub type SubKey = [[u32; ROUNDS_PER_STEP]; BRANCHES * STEPS + 1]; pub const BLOCK_SIZE: usize = BLOCK_BYTES / 4; pub const KEY_SIZE: usize = KEY_BYTES / 4; const ROUNDS: usize = 32; pub(crate) const ROUNDS_PER_STEP: usize = ROUNDS / STEPS; pub(crate) const STEPS: usize = 8; pub(crate) const BRANCHES: usize = 4; } #[cfg(feature = "x128_256")] pub mod params { pub const BLOCK_BYTES: usize = 128 / 8; pub const KEY_BYTES: usize = 256 / 8; pub type SubKey = [[u32; ROUNDS_PER_STEP]; BRANCHES * STEPS + 1]; pub const BLOCK_SIZE: usize = BLOCK_BYTES / 4; pub const KEY_SIZE: usize = KEY_BYTES / 4; const ROUNDS: usize = 40; pub(crate) const ROUNDS_PER_STEP: usize = ROUNDS / STEPS; pub(crate) const STEPS: usize = 10; pub(crate) const BRANCHES: usize = 4; } pub mod block; use params::*; use block::{ key_schedule, encrypt_block, decrypt_block }; #[derive(Clone)] pub struct Sparx(SubKey); impl Sparx { pub fn new(key: &[u8; KEY_BYTES]) -> Self { let mut block = [0; KEY_SIZE]; let mut subkey = [[0; ROUNDS_PER_STEP]; BRANCHES * STEPS + 1]; LittleEndian::read_u32_into(key, &mut block); key_schedule(&mut block, &mut subkey); Sparx(subkey) } pub fn encrypt(&self, b: &mut [u8; BLOCK_BYTES]) { let mut nb = [0; BLOCK_SIZE]; LittleEndian::read_u32_into(b, &mut nb); encrypt_block(&self.0, &mut nb); LittleEndian::write_u32_into(&nb, b); } pub fn decrypt(&self, b: &mut [u8; BLOCK_BYTES]) { let mut nb = [0; BLOCK_SIZE]; LittleEndian::read_u32_into(b, &mut nb); decrypt_block(&self.0, &mut nb); LittleEndian::write_u32_into(&nb, b); } }