eva_crypto/
present.rs

1use super::generic::{
2    create_u8x16, create_u8x4x4, expand_bits, restore_data, transpose, u8x4x4, Ops, Permutation,
3};
4
5type PREstate = u8x4x4;
6
7#[derive(Debug, Clone)]
8pub struct PRESENT {
9    pub round_keys: Vec<PREstate>,
10    pub sbox: [u8; 16],
11    pub rsbox: [u8; 16],
12}
13
14impl PRESENT {
15    pub fn new(key: &[u8]) -> PRESENT {
16        let rounds = 32;
17        let mut round_keys: Vec<PREstate> = vec![Default::default(); rounds];
18        key_expansion(key.to_vec(), &mut round_keys);
19
20        PRESENT {
21            round_keys,
22            sbox: SBOX,
23            rsbox: RSBOX,
24        }
25    }
26
27    /// Encrypt a block.
28    pub fn encrypt(&self, data: &[u8]) -> [u8; 16] {
29        let rounds = 32;
30        let mut state = create_u8x4x4(data);
31        for i in 0..rounds - 1 {
32            state = add_round_key(&state, &self.round_keys[i]);
33            state = sbox_layer(&state, &self.sbox);
34            state = p_layer(&state, &PBOX);
35        }
36        state = add_round_key(&state, &self.round_keys[rounds - 1]);
37        create_u8x16(&state)
38    }
39
40    /// Decrypt a block.
41    pub fn decrypt(&self, data: &[u8]) -> [u8; 16] {
42        let rounds = 32;
43        let mut state = create_u8x4x4(data);
44        for i in (1..rounds).rev() {
45            state = add_round_key(&state, &self.round_keys[i]);
46            state = p_layer(&state, &RPBOX);
47            state = inv_sbox_layer(&state, &self.rsbox);
48        }
49        state = add_round_key(&state, &self.round_keys[0]);
50        create_u8x16(&state)
51    }
52
53    // Fault injection
54    pub fn with_sbox_byte(mut self, faulty_idx: usize, faulty_val: u8) -> Self {
55        let mut sbox = SBOX;
56        sbox[faulty_idx] = faulty_val;
57        self.sbox = sbox;
58        self
59    }
60
61    pub fn with_rsbox_byte(mut self, faulty_idx: usize, faulty_val: u8) -> Self {
62        let mut rsbox = RSBOX;
63        rsbox[faulty_idx] = faulty_val;
64        self.rsbox = rsbox;
65        self
66    }
67}
68fn add_round_key(state: &PREstate, round_key: &PREstate) -> PREstate {
69    state.xor(&transpose(&round_key))
70}
71fn sbox_layer(state: &PREstate, sbox: &[u8]) -> PREstate {
72    state.sub_sbox(sbox)
73}
74fn inv_sbox_layer(state: &PREstate, rsbox: &[u8]) -> PREstate {
75    state.sub_sbox(rsbox)
76}
77fn p_layer(state: &PREstate, pbox: &[u8]) -> PREstate {
78    let bits = expand_bits(&state.concat().to_vec(), 4);
79    let mut p_bits: Vec<bool> = vec![true; 64];
80    for i in 0..64 {
81        p_bits[i] = bits[pbox[i] as usize];
82    }
83    create_u8x4x4(&restore_data(&p_bits, 4)[0..16])
84}
85fn key_expansion(key: Vec<u8>, round_keys: &mut [PREstate]) {
86    let keysize = key.len() * 4;
87    let rounds = round_keys.len();
88    let mut k_register = expand_bits(&key, 4);
89    match keysize {
90        80 | 128 => (),
91        _ => panic!("Key length {} is not valid!", keysize),
92    }
93
94    for (i, round_key) in round_keys.iter_mut().enumerate().take(rounds) {
95        *round_key = create_u8x4x4(&restore_data(&k_register, 4)[0..16]);
96        // rotate left 61 bits
97        k_register[..].rotate_left(61);
98        let mut buffer = restore_data(&k_register, 4);
99        if keysize == 80 {
100            // Sbox
101            buffer[0] = SBOX[buffer[0] as usize];
102            //  XOR with the round counter
103            buffer[15] ^= (i + 1 >> 1) as u8;
104            buffer[16] ^= (i + 1 << 3 & 0xf) as u8;
105        } else {
106            // Sbox
107            buffer[0] = SBOX[buffer[0] as usize];
108            buffer[1] = SBOX[buffer[1] as usize];
109            //  XOR with the round counter
110            buffer[15] ^= (i + 1 >> 2) as u8;
111            buffer[16] ^= (i + 1 << 2 & 0xf) as u8;
112        }
113        k_register = expand_bits(&buffer, 4);
114    }
115}
116
117pub static SBOX: [u8; 16] = [
118    0xc, 0x5, 0x6, 0xb, 0x9, 0x0, 0xa, 0xd, 0x3, 0xe, 0xf, 0x8, 0x4, 0x7, 0x1, 0x2,
119];
120pub static RSBOX: [u8; 16] = [
121    0x5, 0xe, 0xf, 0x8, 0xc, 0x1, 0x2, 0xd, 0xb, 0x4, 0x6, 0x3, 0x0, 0x7, 0x9, 0xa,
122];
123
124pub static PBOX: [u8; 64] = [
125    0, 16, 32, 48, 1, 17, 33, 49, 2, 18, 34, 50, 3, 19, 35, 51, 4, 20, 36, 52, 5, 21, 37, 53, 6,
126    22, 38, 54, 7, 23, 39, 55, 8, 24, 40, 56, 9, 25, 41, 57, 10, 26, 42, 58, 11, 27, 43, 59, 12,
127    28, 44, 60, 13, 29, 45, 61, 14, 30, 46, 62, 15, 31, 47, 63,
128];
129pub static RPBOX: [u8; 64] = [
130    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 1, 5, 9, 13, 17, 21, 25, 29, 33,
131    37, 41, 45, 49, 53, 57, 61, 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 3, 7,
132    11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63,
133];