ice_crypt/
lib.rs

1pub struct IceKey {
2    size: usize,
3    rounds: usize,
4    ice_sbox: [[u64; 4]; 1024],
5    keysched: Vec<[u64; 3]>
6}
7
8impl IceKey {
9    const ICE_SMOD: [[u32; 4]; 4] = [
10        [333, 313, 505, 369],
11        [379, 375, 319, 391],
12        [361, 445, 451, 397],
13        [397, 425, 395, 505]
14    ];
15
16    const ICE_SXOR: [[u32; 4]; 4] = [
17        [0x83, 0x85, 0x9b, 0xcd],
18        [0xcc, 0xa7, 0xad, 0x41],
19        [0x4b, 0x2e, 0xd4, 0x33],
20        [0xea, 0xcb, 0x2e, 0x04]
21    ];
22
23    const ICE_PBOX: [u64; 32] = [
24        0x00000001, 0x00000080, 0x00000400, 0x00002000,
25        0x00080000, 0x00200000, 0x01000000, 0x40000000,
26        0x00000008, 0x00000020, 0x00000100, 0x00004000,
27        0x00010000, 0x00800000, 0x04000000, 0x20000000,
28        0x00000004, 0x00000010, 0x00000200, 0x00008000,
29        0x00020000, 0x00400000, 0x08000000, 0x10000000,
30        0x00000002, 0x00000040, 0x00000800, 0x00001000,
31        0x00040000, 0x00100000, 0x02000000, 0x80000000
32    ];
33
34    const ICE_KEYROT: [u32; 16] = [
35        0, 1, 2, 3, 2, 1, 3, 0,
36        1, 3, 2, 0, 3, 1, 0, 2
37    ];
38
39    pub fn new(length: usize) -> Self {
40        let size: usize;
41        let rounds: usize;
42
43        if length < 1 {
44            size = 1;
45            rounds = 8;
46        } else {
47            size = length;
48            rounds = length * 16;
49        }
50
51        let mut keysched: Vec<[u64; 3]> = Vec::with_capacity(rounds);
52        for _ in 0..rounds {
53            keysched.push([0; 3]);
54        }
55
56        Self {
57            size,
58            rounds,
59            ice_sbox: Self::init_sbox(),
60            keysched
61        }
62    }
63
64    pub fn set(&mut self, key: Vec<u8>) {
65        let mut kb: [u16; 4] = [0; 4];
66
67        if self.rounds == 8 {
68            for i in 0..4 {
69                kb[3 - i] = ((key[i*2] as u16) << 8) | key[i*2 + 1] as u16;
70            }
71
72            _ = self.schedule_build(kb, 0, 0);
73            return;
74        }
75
76        for i in 0..self.size {
77            for j in 0..4 {
78                kb[3 - j] = ((key[i * 8 + j * 2] as u16 & 0xFF) << 8) | (key[i * 8 + j * 2 + 1] as u16 & 0xFF);
79            }
80
81            kb = self.schedule_build(kb, i*8, 0);
82            _ = self.schedule_build(kb, self.rounds - 8 - i*8, 8);
83        }
84    }
85
86    pub fn decrypt_all(&self, mut ctext: Vec<u8>) -> Vec<u8> {
87        let mut ptext: Vec<u8> = Vec::new();
88
89        ctext = Self::pad_vec(ctext);
90
91        for chunk in ctext.chunks_exact(8) {
92            for byte in self.decrypt(Vec::from(chunk)) {
93                ptext.push(byte);
94            }
95        }
96
97        ptext
98    }
99
100    pub fn encrypt_all(&self, mut ptext: Vec<u8>) -> Vec<u8> {
101        let mut ctext: Vec<u8> = Vec::new();
102
103        ptext = Self::pad_vec(ptext);
104
105        for chunk in ptext.chunks_exact(8) {
106            for byte in self.encrypt(Vec::from(chunk)) {
107                ctext.push(byte);
108            }
109        }
110
111        ctext
112    }
113
114    pub fn decrypt(&self, ctext: Vec<u8>) -> Vec<u8> {
115        let mut ptext: [u8; 8] = [0; 8];
116        let mut i: usize = self.rounds;
117
118        let mut l = (ctext[0] as u64) << 24 | (ctext[1] as u64) << 16 | (ctext[2] as u64) << 8 | ctext[3] as u64;
119        let mut r: u64 = (ctext[4] as u64) << 24 | (ctext[5] as u64) << 16 | (ctext[6] as u64) << 8 | ctext[7] as u64;
120
121        while i > 0 {
122            l ^= Self::ice_f(&self, r, self.keysched[i-1]);
123            r ^= Self::ice_f(&self, l, self.keysched[i-2]);
124
125            i -= 2;
126        }
127
128        for j in 0..4 {
129            ptext[3 - j] = (r & 0xFF) as u8;
130            ptext[7 - j] = (l & 0xFF) as u8;
131
132            r >>= 8;
133            l >>= 8;
134        }
135
136        ptext.to_vec()
137    }
138
139    pub fn encrypt(&self, ptext: Vec<u8>) -> Vec<u8> {
140        let mut ctext: [u8; 8] = [0; 8];
141        let mut i: usize = 0;
142
143        let mut l: u64 = (ptext[0] as u64) << 24 | (ptext[1] as u64) << 16 | (ptext[2] as u64) << 8 | ptext[3] as u64;
144        let mut r: u64 = (ptext[4] as u64) << 24 | (ptext[5] as u64) << 16 | (ptext[6] as u64) << 8 | ptext[7] as u64;
145
146        while i < self.rounds {
147            l ^= Self::ice_f(&self, r, self.keysched[i]);
148            r ^= Self::ice_f(&self, l, self.keysched[i+1]);
149
150            i += 2;
151        }
152
153        for j in 0..4 {
154            ctext[3 - j] = (r & 0xFF) as u8;
155            ctext[7 - j] = (l & 0xFF) as u8;
156
157            r >>= 8;
158            l >>= 8;
159        }
160
161        ctext.to_vec()
162    }
163
164    pub fn rounds(&self) -> usize {
165        self.rounds.clone()
166    }
167
168    pub fn size(&self) -> usize {
169        self.size.clone()
170    }
171
172    fn init_sbox() -> [[u64; 4]; 1024] {
173        let mut sbox: [[u64; 4]; 1024] = [[0; 4]; 1024];
174
175        for i in 0..1024 {
176            let col: u32 = (i >> 1) & 0xFF;
177            let row: usize = (((i & 0x1) | ((i & 0x200) >> 8))) as usize;
178            let mut x: u64;
179
180            x = Self::gf_exp7(col ^ Self::ICE_SXOR[0][row], Self::ICE_SMOD[0][row]) << 24;
181            sbox[i as usize][0] = Self::ice_perm32(x);
182
183            x = Self::gf_exp7(col ^ Self::ICE_SXOR[1][row], Self::ICE_SMOD[1][row]) << 16;
184            sbox[i as usize][1] = Self::ice_perm32(x);
185
186            x = Self::gf_exp7(col ^ Self::ICE_SXOR[2][row], Self::ICE_SMOD[2][row]) << 8;
187            sbox[i as usize][2] = Self::ice_perm32(x);
188
189            x = Self::gf_exp7(col ^ Self::ICE_SXOR[3][row], Self::ICE_SMOD[3][row]);
190            sbox[i as usize][3] = Self::ice_perm32(x);
191        }
192
193        sbox
194    }
195
196    fn ice_perm32(mut x: u64) -> u64 {
197        let mut res: u64 = 0;
198        let mut i: usize = 0;
199
200        while x != 0 {
201            if x & 1 == 1 {
202                res |= Self::ICE_PBOX[i];
203            }
204            
205            i += 1;
206            x >>= 1;
207        }
208
209        res
210    }
211
212    fn gf_mult(mut a: u32, mut b: u32, m: u32) -> u32 {
213        let mut res: u32 = 0;
214
215        while b != 0 {
216            if b & 1 == 1 {
217                res ^= a;
218            }
219
220            a <<= 1;
221            b >>= 1;
222
223            if a >= 256 {
224                a ^= m;
225            }
226        }
227
228        res
229    }
230
231    fn gf_exp7(b: u32, m: u32) -> u64 {
232        let mut x: u32;
233
234        if b == 0 {
235            return 0;
236        }
237
238        x = Self::gf_mult(b, b, m);
239        x = Self::gf_mult(b, x, m);
240        x = Self::gf_mult(x, x, m);
241
242        Self::gf_mult(b, x, m).into()
243    }
244
245    fn ice_f(&self, p: u64, sk: [u64; 3]) -> u64 {
246        let tl: u64 = ((p >> 16) & 0x3FF) | (((p >> 14) | (p << 18)) & 0xFFC00);
247        let tr: u64 = (p & 0x3FF) | ((p << 2) & 0xFFC00);
248        let mut al: u64;
249        let mut ar: u64;
250
251        al = sk[2] & (tl ^ tr);
252        ar = al ^ tr;
253        al ^= tl;
254
255        al ^= sk[0];
256        ar ^= sk[1];
257
258        self.ice_sbox[al as usize >> 10][0] | self.ice_sbox[al as usize & 0x3FF][1] | self.ice_sbox[ar as usize >> 10][2] | self.ice_sbox[ar as usize & 0x3FF][3]
259    }
260
261    fn schedule_build(&mut self, mut kb: [u16; 4], n: usize, l: usize) -> [u16; 4] {
262        for i in 0..8 {
263            let kr = Self::ICE_KEYROT[i + l];
264            let mut subkey: [u64; 3] = self.keysched[n + i];
265
266            for j in 0..3 {
267                subkey[j] = 0;
268            }
269
270            for j in 0..15 {
271                let curr_sk: usize = j % 3;
272
273                for k in 0..4 {
274                    let curr_kb = kb[((kr + k) & 3) as usize];
275                    let bit: u16 = curr_kb & 1;
276
277                    subkey[curr_sk] = (subkey[curr_sk] << 1) | bit as u64;
278                    kb[((kr + k) & 3) as usize] = (curr_kb >> 1) | ((bit ^ 1) << 15);
279                }
280            }
281
282            self.keysched[n + i] = subkey;
283        }
284
285        kb
286    }
287
288    fn pad_vec(mut vec: Vec<u8>) -> Vec<u8> {
289        let index = 8 - (vec.len() % 8);
290
291        if index == 8 {
292            return vec;
293        }
294
295        for _ in 0..index {
296            vec.push(0);
297        }
298
299        vec
300    }
301}