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