sparx_cipher/
lib.rs

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}