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}