1use buffer::{BufferResult, RefReadBuffer, RefWriteBuffer};
9use symmetriccipher::{Encryptor, Decryptor, SynchronousStreamCipher, SymmetricCipherError};
10use cryptoutil::{read_u32_le, symm_enc_or_dec, write_u32v_le};
11
12use cryptoutil::copy_memory;
13
14
15const ALPHA_MUL_TABLE : [u32; 256] =
16[
17 0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835,
18 0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679,
19 0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD,
20 0xD320B2D4, 0x32BF7DC7, 0xB8B785F2, 0x59284AE1,
21 0x0AE71199, 0xEB78DE8A, 0x617026BF, 0x80EFE9AC,
22 0xDC607FD5, 0x3DFFB0C6, 0xB7F748F3, 0x566887E0,
23 0x0F40CD01, 0xEEDF0212, 0x64D7FA27, 0x85483534,
24 0xD9C7A34D, 0x38586C5E, 0xB250946B, 0x53CF5B78,
25 0x1467229B, 0xF5F8ED88, 0x7FF015BD, 0x9E6FDAAE,
26 0xC2E04CD7, 0x237F83C4, 0xA9777BF1, 0x48E8B4E2,
27 0x11C0FE03, 0xF05F3110, 0x7A57C925, 0x9BC80636,
28 0xC747904F, 0x26D85F5C, 0xACD0A769, 0x4D4F687A,
29 0x1E803302, 0xFF1FFC11, 0x75170424, 0x9488CB37,
30 0xC8075D4E, 0x2998925D, 0xA3906A68, 0x420FA57B,
31 0x1B27EF9A, 0xFAB82089, 0x70B0D8BC, 0x912F17AF,
32 0xCDA081D6, 0x2C3F4EC5, 0xA637B6F0, 0x47A879E3,
33 0x28CE449F, 0xC9518B8C, 0x435973B9, 0xA2C6BCAA,
34 0xFE492AD3, 0x1FD6E5C0, 0x95DE1DF5, 0x7441D2E6,
35 0x2D699807, 0xCCF65714, 0x46FEAF21, 0xA7616032,
36 0xFBEEF64B, 0x1A713958, 0x9079C16D, 0x71E60E7E,
37 0x22295506, 0xC3B69A15, 0x49BE6220, 0xA821AD33,
38 0xF4AE3B4A, 0x1531F459, 0x9F390C6C, 0x7EA6C37F,
39 0x278E899E, 0xC611468D, 0x4C19BEB8, 0xAD8671AB,
40 0xF109E7D2, 0x109628C1, 0x9A9ED0F4, 0x7B011FE7,
41 0x3CA96604, 0xDD36A917, 0x573E5122, 0xB6A19E31,
42 0xEA2E0848, 0x0BB1C75B, 0x81B93F6E, 0x6026F07D,
43 0x390EBA9C, 0xD891758F, 0x52998DBA, 0xB30642A9,
44 0xEF89D4D0, 0x0E161BC3, 0x841EE3F6, 0x65812CE5,
45 0x364E779D, 0xD7D1B88E, 0x5DD940BB, 0xBC468FA8,
46 0xE0C919D1, 0x0156D6C2, 0x8B5E2EF7, 0x6AC1E1E4,
47 0x33E9AB05, 0xD2766416, 0x587E9C23, 0xB9E15330,
48 0xE56EC549, 0x04F10A5A, 0x8EF9F26F, 0x6F663D7C,
49 0x50358897, 0xB1AA4784, 0x3BA2BFB1, 0xDA3D70A2,
50 0x86B2E6DB, 0x672D29C8, 0xED25D1FD, 0x0CBA1EEE,
51 0x5592540F, 0xB40D9B1C, 0x3E056329, 0xDF9AAC3A,
52 0x83153A43, 0x628AF550, 0xE8820D65, 0x091DC276,
53 0x5AD2990E, 0xBB4D561D, 0x3145AE28, 0xD0DA613B,
54 0x8C55F742, 0x6DCA3851, 0xE7C2C064, 0x065D0F77,
55 0x5F754596, 0xBEEA8A85, 0x34E272B0, 0xD57DBDA3,
56 0x89F22BDA, 0x686DE4C9, 0xE2651CFC, 0x03FAD3EF,
57 0x4452AA0C, 0xA5CD651F, 0x2FC59D2A, 0xCE5A5239,
58 0x92D5C440, 0x734A0B53, 0xF942F366, 0x18DD3C75,
59 0x41F57694, 0xA06AB987, 0x2A6241B2, 0xCBFD8EA1,
60 0x977218D8, 0x76EDD7CB, 0xFCE52FFE, 0x1D7AE0ED,
61 0x4EB5BB95, 0xAF2A7486, 0x25228CB3, 0xC4BD43A0,
62 0x9832D5D9, 0x79AD1ACA, 0xF3A5E2FF, 0x123A2DEC,
63 0x4B12670D, 0xAA8DA81E, 0x2085502B, 0xC11A9F38,
64 0x9D950941, 0x7C0AC652, 0xF6023E67, 0x179DF174,
65 0x78FBCC08, 0x9964031B, 0x136CFB2E, 0xF2F3343D,
66 0xAE7CA244, 0x4FE36D57, 0xC5EB9562, 0x24745A71,
67 0x7D5C1090, 0x9CC3DF83, 0x16CB27B6, 0xF754E8A5,
68 0xABDB7EDC, 0x4A44B1CF, 0xC04C49FA, 0x21D386E9,
69 0x721CDD91, 0x93831282, 0x198BEAB7, 0xF81425A4,
70 0xA49BB3DD, 0x45047CCE, 0xCF0C84FB, 0x2E934BE8,
71 0x77BB0109, 0x9624CE1A, 0x1C2C362F, 0xFDB3F93C,
72 0xA13C6F45, 0x40A3A056, 0xCAAB5863, 0x2B349770,
73 0x6C9CEE93, 0x8D032180, 0x070BD9B5, 0xE69416A6,
74 0xBA1B80DF, 0x5B844FCC, 0xD18CB7F9, 0x301378EA,
75 0x693B320B, 0x88A4FD18, 0x02AC052D, 0xE333CA3E,
76 0xBFBC5C47, 0x5E239354, 0xD42B6B61, 0x35B4A472,
77 0x667BFF0A, 0x87E43019, 0x0DECC82C, 0xEC73073F,
78 0xB0FC9146, 0x51635E55, 0xDB6BA660, 0x3AF46973,
79 0x63DC2392, 0x8243EC81, 0x084B14B4, 0xE9D4DBA7,
80 0xB55B4DDE, 0x54C482CD, 0xDECC7AF8, 0x3F53B5EB
81];
82
83const ALPHA_DIV_TABLE : [u32; 256] =
84[
85 0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE,
86 0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998,
87 0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32,
88 0xA04452AA, 0xB84B1267, 0x905AD299, 0x88559254,
89 0x29F05F31, 0x31FF1FFC, 0x19EEDF02, 0x01E19FCF,
90 0x49CCF657, 0x51C3B69A, 0x79D27664, 0x61DD36A9,
91 0xE988A4FD, 0xF187E430, 0xD99624CE, 0xC1996403,
92 0x89B40D9B, 0x91BB4D56, 0xB9AA8DA8, 0xA1A5CD65,
93 0x5249BE62, 0x4A46FEAF, 0x62573E51, 0x7A587E9C,
94 0x32751704, 0x2A7A57C9, 0x026B9737, 0x1A64D7FA,
95 0x923145AE, 0x8A3E0563, 0xA22FC59D, 0xBA208550,
96 0xF20DECC8, 0xEA02AC05, 0xC2136CFB, 0xDA1C2C36,
97 0x7BB9E153, 0x63B6A19E, 0x4BA76160, 0x53A821AD,
98 0x1B854835, 0x038A08F8, 0x2B9BC806, 0x339488CB,
99 0xBBC11A9F, 0xA3CE5A52, 0x8BDF9AAC, 0x93D0DA61,
100 0xDBFDB3F9, 0xC3F2F334, 0xEBE333CA, 0xF3EC7307,
101 0xA492D5C4, 0xBC9D9509, 0x948C55F7, 0x8C83153A,
102 0xC4AE7CA2, 0xDCA13C6F, 0xF4B0FC91, 0xECBFBC5C,
103 0x64EA2E08, 0x7CE56EC5, 0x54F4AE3B, 0x4CFBEEF6,
104 0x04D6876E, 0x1CD9C7A3, 0x34C8075D, 0x2CC74790,
105 0x8D628AF5, 0x956DCA38, 0xBD7C0AC6, 0xA5734A0B,
106 0xED5E2393, 0xF551635E, 0xDD40A3A0, 0xC54FE36D,
107 0x4D1A7139, 0x551531F4, 0x7D04F10A, 0x650BB1C7,
108 0x2D26D85F, 0x35299892, 0x1D38586C, 0x053718A1,
109 0xF6DB6BA6, 0xEED42B6B, 0xC6C5EB95, 0xDECAAB58,
110 0x96E7C2C0, 0x8EE8820D, 0xA6F942F3, 0xBEF6023E,
111 0x36A3906A, 0x2EACD0A7, 0x06BD1059, 0x1EB25094,
112 0x569F390C, 0x4E9079C1, 0x6681B93F, 0x7E8EF9F2,
113 0xDF2B3497, 0xC724745A, 0xEF35B4A4, 0xF73AF469,
114 0xBF179DF1, 0xA718DD3C, 0x8F091DC2, 0x97065D0F,
115 0x1F53CF5B, 0x075C8F96, 0x2F4D4F68, 0x37420FA5,
116 0x7F6F663D, 0x676026F0, 0x4F71E60E, 0x577EA6C3,
117 0xE18D0321, 0xF98243EC, 0xD1938312, 0xC99CC3DF,
118 0x81B1AA47, 0x99BEEA8A, 0xB1AF2A74, 0xA9A06AB9,
119 0x21F5F8ED, 0x39FAB820, 0x11EB78DE, 0x09E43813,
120 0x41C9518B, 0x59C61146, 0x71D7D1B8, 0x69D89175,
121 0xC87D5C10, 0xD0721CDD, 0xF863DC23, 0xE06C9CEE,
122 0xA841F576, 0xB04EB5BB, 0x985F7545, 0x80503588,
123 0x0805A7DC, 0x100AE711, 0x381B27EF, 0x20146722,
124 0x68390EBA, 0x70364E77, 0x58278E89, 0x4028CE44,
125 0xB3C4BD43, 0xABCBFD8E, 0x83DA3D70, 0x9BD57DBD,
126 0xD3F81425, 0xCBF754E8, 0xE3E69416, 0xFBE9D4DB,
127 0x73BC468F, 0x6BB30642, 0x43A2C6BC, 0x5BAD8671,
128 0x1380EFE9, 0x0B8FAF24, 0x239E6FDA, 0x3B912F17,
129 0x9A34E272, 0x823BA2BF, 0xAA2A6241, 0xB225228C,
130 0xFA084B14, 0xE2070BD9, 0xCA16CB27, 0xD2198BEA,
131 0x5A4C19BE, 0x42435973, 0x6A52998D, 0x725DD940,
132 0x3A70B0D8, 0x227FF015, 0x0A6E30EB, 0x12617026,
133 0x451FD6E5, 0x5D109628, 0x750156D6, 0x6D0E161B,
134 0x25237F83, 0x3D2C3F4E, 0x153DFFB0, 0x0D32BF7D,
135 0x85672D29, 0x9D686DE4, 0xB579AD1A, 0xAD76EDD7,
136 0xE55B844F, 0xFD54C482, 0xD545047C, 0xCD4A44B1,
137 0x6CEF89D4, 0x74E0C919, 0x5CF109E7, 0x44FE492A,
138 0x0CD320B2, 0x14DC607F, 0x3CCDA081, 0x24C2E04C,
139 0xAC977218, 0xB49832D5, 0x9C89F22B, 0x8486B2E6,
140 0xCCABDB7E, 0xD4A49BB3, 0xFCB55B4D, 0xE4BA1B80,
141 0x17566887, 0x0F59284A, 0x2748E8B4, 0x3F47A879,
142 0x776AC1E1, 0x6F65812C, 0x477441D2, 0x5F7B011F,
143 0xD72E934B, 0xCF21D386, 0xE7301378, 0xFF3F53B5,
144 0xB7123A2D, 0xAF1D7AE0, 0x870CBA1E, 0x9F03FAD3,
145 0x3EA637B6, 0x26A9777B, 0x0EB8B785, 0x16B7F748,
146 0x5E9A9ED0, 0x4695DE1D, 0x6E841EE3, 0x768B5E2E,
147 0xFEDECC7A, 0xE6D18CB7, 0xCEC04C49, 0xD6CF0C84,
148 0x9EE2651C, 0x86ED25D1, 0xAEFCE52F, 0xB6F3A5E2
149];
150
151
152#[derive(Copy)]
153pub struct Sosemanuk {
154 lfsr: [u32; 10],
155 fsm_r: [u32; 2],
156 subkeys: [u32; 100],
157 output: [u8; 80],
158 offset: u32
159}
160
161impl Clone for Sosemanuk { fn clone(&self) -> Sosemanuk { *self } }
162
163impl Sosemanuk {
164 pub fn new(key: &[u8], nonce: &[u8]) -> Sosemanuk {
165 let mut sosemanuk = Sosemanuk { lfsr: [0; 10], fsm_r: [0; 2], subkeys: [0; 100], output: [0; 80], offset: 80 };
166
167 assert!(key.len() <= 32);
168 assert!(nonce.len() <= 16);
169
170 key_setup(&key, &mut sosemanuk.subkeys);
171 iv_setup(&nonce, &mut sosemanuk.subkeys, &mut sosemanuk.lfsr, &mut sosemanuk.fsm_r);
172
173 sosemanuk
174 }
175
176 fn advance_state(&mut self) {
177 let mut s0 = self.lfsr[0];
178 let mut s1 = self.lfsr[1];
179 let mut s2 = self.lfsr[2];
180 let mut s3 = self.lfsr[3];
181 let mut s4 = self.lfsr[4];
182 let mut s5 = self.lfsr[5];
183 let mut s6 = self.lfsr[6];
184 let mut s7 = self.lfsr[7];
185 let mut s8 = self.lfsr[8];
186 let mut s9 = self.lfsr[9];
187 let mut r1 = self.fsm_r[0];
188 let mut r2 = self.fsm_r[1];
189 let mut f0 : u32;
190 let mut f1 : u32;
191 let mut f2 : u32;
192 let mut f3 : u32;
193 let mut f4 : u32;
194 let mut v0 : u32;
195 let mut v1 : u32;
196 let mut v2 : u32;
197 let mut v3 : u32;
198 let mut tt : u32;
199
200 let ref mul_alpha = ALPHA_MUL_TABLE;
201 let ref div_alpha = ALPHA_DIV_TABLE;
202
203 tt = r1;
204 r1 = r2.wrapping_add(s1 ^ match r1 & 0x01 {
206 0 => 0,
207 _ => s8
208 });
209 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
210 v0 = s0;
211 s0 = ((s0 << 8) ^ mul_alpha[s0 as usize >> 24])
212 ^ ((s3 >> 8) ^ div_alpha[s3 as usize & 0xFF]) ^ s9;
213 f0 = s9.wrapping_add(r1) ^ r2;
214
215 tt = r1;
216 r1 = r2.wrapping_add(s2 ^ match r1 & 0x01 {
218 0 => 0,
219 _ => s9
220 });
221 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
222 v1 = s1;
223 s1 = ((s1 << 8) ^ mul_alpha[s1 as usize >> 24])
224 ^ ((s4 >> 8) ^ div_alpha[s4 as usize & 0xFF]) ^ s0;
225 f1 = s0.wrapping_add(r1) ^ r2;
226
227 tt = r1;
228 r1 = r2.wrapping_add(s3 ^ match r1 & 0x01 {
230 0 => 0,
231 _ => s0
232 });
233 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
234 v2 = s2;
235 s2 = ((s2 << 8) ^ mul_alpha[s2 as usize >> 24])
236 ^ ((s5 >> 8) ^ div_alpha[s5 as usize & 0xFF]) ^ s1;
237 f2 = s1.wrapping_add(r1) ^ r2;
238
239 tt = r1;
240 r1 = r2.wrapping_add(s4 ^ match r1 & 0x01 {
242 0 => 0,
243 _ => s1
244 });
245 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
246 v3 = s3;
247 s3 = ((s3 << 8) ^ mul_alpha[s3 as usize >> 24])
248 ^ ((s6 >> 8) ^ div_alpha[s6 as usize & 0xFF]) ^ s2;
249 f3 = s2.wrapping_add(r1) ^ r2;
250
251 f4 = f0;
255 f0 &= f2;
256 f0 ^= f3;
257 f2 ^= f1;
258 f2 ^= f0;
259 f3 |= f4;
260 f3 ^= f1;
261 f4 ^= f2;
262 f1 = f3;
263 f3 |= f4;
264 f3 ^= f0;
265 f0 &= f1;
266 f4 ^= f0;
267 f1 ^= f3;
268 f1 ^= f4;
269 f4 = !f4;
270
271 let sbox_res = [(f2 ^ v0), (f3 ^ v1), (f1 ^ v2), (f4 ^ v3)];
275 write_u32v_le(&mut self.output[0..16], &sbox_res);
276
277 tt = r1;
278 r1 = r2.wrapping_add(s5 ^ match r1 & 0x01 {
280 0 => 0,
281 _ => s2
282 });
283 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
284 v0 = s4;
285 s4 = ((s4 << 8) ^ mul_alpha[s4 as usize >> 24])
286 ^ ((s7 >> 8) ^ div_alpha[s7 as usize & 0xFF]) ^ s3;
287 f0 = s3.wrapping_add(r1) ^ r2;
288
289 tt = r1;
290 r1 = r2.wrapping_add(s6 ^ match r1 & 0x01 {
292 0 => 0,
293 _ => s3
294 });
295 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
296 v1 = s5;
297 s5 = ((s5 << 8) ^ mul_alpha[s5 as usize >> 24])
298 ^ ((s8 >> 8) ^ div_alpha[s8 as usize & 0xFF]) ^ s4;
299 f1 = s4.wrapping_add(r1) ^ r2;
300
301 tt = r1;
302 r1 = r2.wrapping_add(s7 ^ match r1 & 0x01 {
304 0 => 0,
305 _ => s4
306 });
307 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
308 v2 = s6;
309 s6 = ((s6 << 8) ^ mul_alpha[s6 as usize >> 24])
310 ^ ((s9 >> 8) ^ div_alpha[s9 as usize & 0xFF]) ^ s5;
311 f2 = s5.wrapping_add(r1) ^ r2;
312
313 tt = r1;
314 r1 = r2.wrapping_add(s8 ^ match r1 & 0x01 {
316 0 => 0,
317 _ => s5
318 });
319 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
320 v3 = s7;
321 s7 = ((s7 << 8) ^ mul_alpha[s7 as usize >> 24])
322 ^ ((s0 >> 8) ^ div_alpha[s0 as usize & 0xFF]) ^ s6;
323 f3 = s6.wrapping_add(r1) ^ r2;
324
325 f4 = f0;
329 f0 &= f2;
330 f0 ^= f3;
331 f2 ^= f1;
332 f2 ^= f0;
333 f3 |= f4;
334 f3 ^= f1;
335 f4 ^= f2;
336 f1 = f3;
337 f3 |= f4;
338 f3 ^= f0;
339 f0 &= f1;
340 f4 ^= f0;
341 f1 ^= f3;
342 f1 ^= f4;
343 f4 = !f4;
344
345 let sbox_res = [(f2 ^ v0), (f3 ^ v1), (f1 ^ v2), (f4 ^ v3)];
349 write_u32v_le(&mut self.output[16..32], &sbox_res);
350
351 tt = r1;
352 r1 = r2.wrapping_add(s9 ^ match r1 & 0x01 {
354 0 => 0,
355 _ => s6
356 });
357 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
358 v0 = s8;
359 s8 = ((s8 << 8) ^ mul_alpha[s8 as usize >> 24])
360 ^ ((s1 >> 8) ^ div_alpha[s1 as usize & 0xFF]) ^ s7;
361 f0 = s7.wrapping_add(r1) ^ r2;
362
363 tt = r1;
364 r1 = r2.wrapping_add(s0 ^ match r1 & 0x01 {
366 0 => 0,
367 _ => s7
368 });
369 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
370 v1 = s9;
371 s9 = ((s9 << 8) ^ mul_alpha[s9 as usize >> 24])
372 ^ ((s2 >> 8) ^ div_alpha[s2 as usize & 0xFF]) ^ s8;
373 f1 = s8.wrapping_add(r1) ^ r2;
374
375 tt = r1;
376 r1 = r2.wrapping_add(s1 ^ match r1 & 0x01 {
378 0 => 0,
379 _ => s8
380 });
381 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
382 v2 = s0;
383 s0 = ((s0 << 8) ^ mul_alpha[s0 as usize >> 24])
384 ^ ((s3 >> 8) ^ div_alpha[s3 as usize & 0xFF]) ^ s9;
385 f2 = s9.wrapping_add(r1) ^ r2;
386
387 tt = r1;
388 r1 = r2.wrapping_add(s2 ^ match r1 & 0x01 {
390 0 => 0,
391 _ => s9
392 });
393 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
394 v3 = s1;
395 s1 = ((s1 << 8) ^ mul_alpha[s1 as usize >> 24])
396 ^ ((s4 >> 8) ^ div_alpha[s4 as usize & 0xFF]) ^ s0;
397 f3 = s0.wrapping_add(r1) ^ r2;
398
399 f4 = f0;
403 f0 &= f2;
404 f0 ^= f3;
405 f2 ^= f1;
406 f2 ^= f0;
407 f3 |= f4;
408 f3 ^= f1;
409 f4 ^= f2;
410 f1 = f3;
411 f3 |= f4;
412 f3 ^= f0;
413 f0 &= f1;
414 f4 ^= f0;
415 f1 ^= f3;
416 f1 ^= f4;
417 f4 = !f4;
418
419 let sbox_res = [(f2 ^ v0), (f3 ^ v1), (f1 ^ v2), (f4 ^ v3)];
423 write_u32v_le(&mut self.output[32..48], &sbox_res);
424
425 tt = r1;
426 r1 = r2.wrapping_add(s3 ^ match r1 & 0x01 {
428 0 => 0,
429 _ => s0
430 });
431 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
432 v0 = s2;
433 s2 = ((s2 << 8) ^ mul_alpha[s2 as usize >> 24])
434 ^ ((s5 >> 8) ^ div_alpha[s5 as usize & 0xFF]) ^ s1;
435 f0 = s1.wrapping_add(r1) ^ r2;
436
437 tt = r1;
438 r1 = r2.wrapping_add(s4 ^ match r1 & 0x01 {
440 0 => 0,
441 _ => s1
442 });
443 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
444 v1 = s3;
445 s3 = ((s3 << 8) ^ mul_alpha[s3 as usize >> 24])
446 ^ ((s6 >> 8) ^ div_alpha[s6 as usize & 0xFF]) ^ s2;
447 f1 = s2.wrapping_add(r1) ^ r2;
448
449 tt = r1;
450 r1 = r2.wrapping_add(s5 ^ match r1 & 0x01 {
452 0 => 0,
453 _ => s2
454 });
455 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
456 v2 = s4;
457 s4 = ((s4 << 8) ^ mul_alpha[s4 as usize >> 24])
458 ^ ((s7 >> 8) ^ div_alpha[s7 as usize & 0xFF]) ^ s3;
459 f2 = s3.wrapping_add(r1) ^ r2;
460
461 tt = r1;
462 r1 = r2.wrapping_add(s6 ^ match r1 & 0x01 {
464 0 => 0,
465 _ => s3
466 });
467 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
468 v3 = s5;
469 s5 = ((s5 << 8) ^ mul_alpha[s5 as usize >> 24])
470 ^ ((s8 >> 8) ^ div_alpha[s8 as usize & 0xFF]) ^ s4;
471 f3 = s4.wrapping_add(r1) ^ r2;
472
473 f4 = f0;
477 f0 &= f2;
478 f0 ^= f3;
479 f2 ^= f1;
480 f2 ^= f0;
481 f3 |= f4;
482 f3 ^= f1;
483 f4 ^= f2;
484 f1 = f3;
485 f3 |= f4;
486 f3 ^= f0;
487 f0 &= f1;
488 f4 ^= f0;
489 f1 ^= f3;
490 f1 ^= f4;
491 f4 = !f4;
492
493 let sbox_res = [(f2 ^ v0), (f3 ^ v1), (f1 ^ v2), (f4 ^ v3)];
497 write_u32v_le(&mut self.output[48..64], &sbox_res);
498
499 tt = r1;
500 r1 = r2.wrapping_add(s7 ^ match r1 & 0x01 {
502 0 => 0,
503 _ => s4
504 });
505 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
506 v0 = s6;
507 s6 = ((s6 << 8) ^ mul_alpha[s6 as usize >> 24])
508 ^ ((s9 >> 8) ^ div_alpha[s9 as usize & 0xFF]) ^ s5;
509 f0 = s5.wrapping_add(r1) ^ r2;
510
511 tt = r1;
512 r1 = r2.wrapping_add(s8 ^ match r1 & 0x01 {
514 0 => 0,
515 _ => s5
516 });
517 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
518 v1 = s7;
519 s7 = ((s7 << 8) ^ mul_alpha[s7 as usize >> 24])
520 ^ ((s0 >> 8) ^ div_alpha[s0 as usize & 0xFF]) ^ s6;
521 f1 = s6.wrapping_add(r1) ^ r2;
522
523 tt = r1;
524 r1 = r2.wrapping_add(s9 ^ match r1 & 0x01 {
526 0 => 0,
527 _ => s6
528 });
529 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
530 v2 = s8;
531 s8 = ((s8 << 8) ^ mul_alpha[s8 as usize >> 24])
532 ^ ((s1 >> 8) ^ div_alpha[s1 as usize & 0xFF]) ^ s7;
533 f2 = s7.wrapping_add(r1) ^ r2;
534
535 tt = r1;
536 r1 = r2.wrapping_add(s0 ^ match r1 & 0x01 {
538 0 => 0,
539 _ => s7
540 });
541 r2 = tt.wrapping_mul(0x54655307).rotate_left(7);
542 v3 = s9;
543 s9 = ((s9 << 8) ^ mul_alpha[s9 as usize >> 24])
544 ^ ( ( s2 >> 8) ^ div_alpha[s2 as usize & 0xFF]) ^ s8;
545 f3 = s8.wrapping_add(r1) ^ r2;
546
547 f4 = f0;
551 f0 &= f2;
552 f0 ^= f3;
553 f2 ^= f1;
554 f2 ^= f0;
555 f3 |= f4;
556 f3 ^= f1;
557 f4 ^= f2;
558 f1 = f3;
559 f3 |= f4;
560 f3 ^= f0;
561 f0 &= f1;
562 f4 ^= f0;
563 f1 ^= f3;
564 f1 ^= f4;
565 f4 = !f4;
566
567 let sbox_res = [(f2 ^ v0), (f3 ^ v1), (f1 ^ v2), (f4 ^ v3)];
571 write_u32v_le(&mut self.output[64..80], &sbox_res);
572
573 self.lfsr[0] = s0;
574 self.lfsr[1] = s1;
575 self.lfsr[2] = s2;
576 self.lfsr[3] = s3;
577 self.lfsr[4] = s4;
578 self.lfsr[5] = s5;
579 self.lfsr[6] = s6;
580 self.lfsr[7] = s7;
581 self.lfsr[8] = s8;
582 self.lfsr[9] = s9;
583 self.fsm_r[0] = r1;
584 self.fsm_r[1] = r2;
585 self.offset = 0;
586 }
587
588 fn next(&mut self) -> u8 {
589 if self.offset == 80 {
590 self.advance_state();
591 }
592 let ret = self.output[self.offset as usize];
593 self.offset += 1;
594 ret
595 }
596}
597
598
599fn key_setup(key : &[u8], subkeys : &mut[u32; 100]) {
600 let mut full_key : [u8; 32] = [0; 32];
601 if key.len() < 32 {
602 copy_memory(&key, &mut full_key[0..key.len()]);
603 full_key[key.len()] = 0x01;
604 } else {
605 copy_memory(&key[0..32], &mut full_key[0..32]);
606 }
607
608 let mut w0 = read_u32_le(&full_key[0..4]);
609 let mut w1 = read_u32_le(&full_key[4..8]);
610 let mut w2 = read_u32_le(&full_key[8..12]);
611 let mut w3 = read_u32_le(&full_key[12..16]);
612 let mut w4 = read_u32_le(&full_key[16..20]);
613 let mut w5 = read_u32_le(&full_key[20..24]);
614 let mut w6 = read_u32_le(&full_key[24..28]);
615 let mut w7 = read_u32_le(&full_key[28..32]);
616 let mut r0 : u32;
617 let mut r1 : u32;
618 let mut r2 : u32;
619 let mut r3 : u32;
620 let mut r4 : u32;
621 let mut tt : u32;
622 let mut i = 0;
623
624 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (0));
625 w0 = tt.rotate_left(11);
626 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (0 + 1));
627 w1 = tt.rotate_left(11);
628 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (0 + 2));
629 w2 = tt.rotate_left(11);
630 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (0 + 3));
631 w3 = tt.rotate_left(11);
632 r0 = w0;
633 r1 = w1;
634 r2 = w2;
635 r3 = w3;
636 r4 = r0;
637 r0 |= r3;
638 r3 ^= r1;
639 r1 &= r4;
640 r4 ^= r2;
641 r2 ^= r3;
642 r3 &= r0;
643 r4 |= r1;
644 r3 ^= r4;
645 r0 ^= r1;
646 r4 &= r0;
647 r1 ^= r3;
648 r4 ^= r2;
649 r1 |= r0;
650 r1 ^= r2;
651 r0 ^= r3;
652 r2 = r1;
653 r1 |= r3;
654 r1 ^= r0;
655 subkeys[i] = r1; i+=1;
656 subkeys[i] = r2; i+=1;
657 subkeys[i] = r3; i+=1;
658 subkeys[i] = r4; i+=1;
659 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (4));
660 w4 = tt.rotate_left(11);
661 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (4 + 1));
662 w5 = tt.rotate_left(11);
663 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (4 + 2));
664 w6 = tt.rotate_left(11);
665 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (4 + 3));
666 w7 = tt.rotate_left(11);
667 r0 = w4;
668 r1 = w5;
669 r2 = w6;
670 r3 = w7;
671 r4 = r0;
672 r0 &= r2;
673 r0 ^= r3;
674 r2 ^= r1;
675 r2 ^= r0;
676 r3 |= r4;
677 r3 ^= r1;
678 r4 ^= r2;
679 r1 = r3;
680 r3 |= r4;
681 r3 ^= r0;
682 r0 &= r1;
683 r4 ^= r0;
684 r1 ^= r3;
685 r1 ^= r4;
686 r4 = !r4;
687 subkeys[i] = r2; i+=1;
688 subkeys[i] = r3; i+=1;
689 subkeys[i] = r1; i+=1;
690 subkeys[i] = r4; i+=1;
691 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (8));
692 w0 = tt.rotate_left(11);
693 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (8 + 1));
694 w1 = tt.rotate_left(11);
695 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (8 + 2));
696 w2 = tt.rotate_left(11);
697 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (8 + 3));
698 w3 = tt.rotate_left(11);
699 r0 = w0;
700 r1 = w1;
701 r2 = w2;
702 r3 = w3;
703 r0 = !r0;
704 r2 = !r2;
705 r4 = r0;
706 r0 &= r1;
707 r2 ^= r0;
708 r0 |= r3;
709 r3 ^= r2;
710 r1 ^= r0;
711 r0 ^= r4;
712 r4 |= r1;
713 r1 ^= r3;
714 r2 |= r0;
715 r2 &= r4;
716 r0 ^= r1;
717 r1 &= r2;
718 r1 ^= r0;
719 r0 &= r2;
720 r0 ^= r4;
721 subkeys[i] = r2; i+=1;
722 subkeys[i] = r0; i+=1;
723 subkeys[i] = r3; i+=1;
724 subkeys[i] = r1; i+=1;
725 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (12));
726 w4 = tt.rotate_left(11);
727 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (12 + 1));
728 w5 = tt.rotate_left(11);
729 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (12 + 2));
730 w6 = tt.rotate_left(11);
731 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (12 + 3));
732 w7 = tt.rotate_left(11);
733 r0 = w4;
734 r1 = w5;
735 r2 = w6;
736 r3 = w7;
737 r3 ^= r0;
738 r4 = r1;
739 r1 &= r3;
740 r4 ^= r2;
741 r1 ^= r0;
742 r0 |= r3;
743 r0 ^= r4;
744 r4 ^= r3;
745 r3 ^= r2;
746 r2 |= r1;
747 r2 ^= r4;
748 r4 = !r4;
749 r4 |= r1;
750 r1 ^= r3;
751 r1 ^= r4;
752 r3 |= r0;
753 r1 ^= r3;
754 r4 ^= r3;
755 subkeys[i] = r1; i+=1;
756 subkeys[i] = r4; i+=1;
757 subkeys[i] = r2; i+=1;
758 subkeys[i] = r0; i+=1;
759 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (16));
760 w0 = tt.rotate_left(11);
761 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (16 + 1));
762 w1 = tt.rotate_left(11);
763 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (16 + 2));
764 w2 = tt.rotate_left(11);
765 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (16 + 3));
766 w3 = tt.rotate_left(11);
767 r0 = w0;
768 r1 = w1;
769 r2 = w2;
770 r3 = w3;
771 r4 = r1;
772 r1 |= r2;
773 r1 ^= r3;
774 r4 ^= r2;
775 r2 ^= r1;
776 r3 |= r4;
777 r3 &= r0;
778 r4 ^= r2;
779 r3 ^= r1;
780 r1 |= r4;
781 r1 ^= r0;
782 r0 |= r4;
783 r0 ^= r2;
784 r1 ^= r4;
785 r2 ^= r1;
786 r1 &= r0;
787 r1 ^= r4;
788 r2 = !r2;
789 r2 |= r0;
790 r4 ^= r2;
791 subkeys[i] = r4; i+=1;
792 subkeys[i] = r3; i+=1;
793 subkeys[i] = r1; i+=1;
794 subkeys[i] = r0; i+=1;
795 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (20));
796 w4 = tt.rotate_left(11);
797 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (20 + 1));
798 w5 = tt.rotate_left(11);
799 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (20 + 2));
800 w6 = tt.rotate_left(11);
801 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (20 + 3));
802 w7 = tt.rotate_left(11);
803 r0 = w4;
804 r1 = w5;
805 r2 = w6;
806 r3 = w7;
807 r2 = !r2;
808 r4 = r3;
809 r3 &= r0;
810 r0 ^= r4;
811 r3 ^= r2;
812 r2 |= r4;
813 r1 ^= r3;
814 r2 ^= r0;
815 r0 |= r1;
816 r2 ^= r1;
817 r4 ^= r0;
818 r0 |= r3;
819 r0 ^= r2;
820 r4 ^= r3;
821 r4 ^= r0;
822 r3 = !r3;
823 r2 &= r4;
824 r2 ^= r3;
825 subkeys[i] = r0; i+=1;
826 subkeys[i] = r1; i+=1;
827 subkeys[i] = r4; i+=1;
828 subkeys[i] = r2; i+=1;
829 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (24));
830 w0 = tt.rotate_left(11);
831 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (24 + 1));
832 w1 = tt.rotate_left(11);
833 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (24 + 2));
834 w2 = tt.rotate_left(11);
835 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (24 + 3));
836 w3 = tt.rotate_left(11);
837 r0 = w0;
838 r1 = w1;
839 r2 = w2;
840 r3 = w3;
841 r0 ^= r1;
842 r1 ^= r3;
843 r3 = !r3;
844 r4 = r1;
845 r1 &= r0;
846 r2 ^= r3;
847 r1 ^= r2;
848 r2 |= r4;
849 r4 ^= r3;
850 r3 &= r1;
851 r3 ^= r0;
852 r4 ^= r1;
853 r4 ^= r2;
854 r2 ^= r0;
855 r0 &= r3;
856 r2 = !r2;
857 r0 ^= r4;
858 r4 |= r3;
859 r2 ^= r4;
860 subkeys[i] = r1; i+=1;
861 subkeys[i] = r3; i+=1;
862 subkeys[i] = r0; i+=1;
863 subkeys[i] = r2; i+=1;
864 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (28));
865 w4 = tt.rotate_left(11);
866 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (28 + 1));
867 w5 = tt.rotate_left(11);
868 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (28 + 2));
869 w6 = tt.rotate_left(11);
870 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (28 + 3));
871 w7 = tt.rotate_left(11);
872 r0 = w4;
873 r1 = w5;
874 r2 = w6;
875 r3 = w7;
876 r1 ^= r3;
877 r3 = !r3;
878 r2 ^= r3;
879 r3 ^= r0;
880 r4 = r1;
881 r1 &= r3;
882 r1 ^= r2;
883 r4 ^= r3;
884 r0 ^= r4;
885 r2 &= r4;
886 r2 ^= r0;
887 r0 &= r1;
888 r3 ^= r0;
889 r4 |= r1;
890 r4 ^= r0;
891 r0 |= r3;
892 r0 ^= r2;
893 r2 &= r3;
894 r0 = !r0;
895 r4 ^= r2;
896 subkeys[i] = r1; i+=1;
897 subkeys[i] = r4; i+=1;
898 subkeys[i] = r0; i+=1;
899 subkeys[i] = r3; i+=1;
900 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (32));
901 w0 = tt.rotate_left(11);
902 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (32 + 1));
903 w1 = tt.rotate_left(11);
904 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (32 + 2));
905 w2 = tt.rotate_left(11);
906 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (32 + 3));
907 w3 = tt.rotate_left(11);
908 r0 = w0;
909 r1 = w1;
910 r2 = w2;
911 r3 = w3;
912 r4 = r0;
913 r0 |= r3;
914 r3 ^= r1;
915 r1 &= r4;
916 r4 ^= r2;
917 r2 ^= r3;
918 r3 &= r0;
919 r4 |= r1;
920 r3 ^= r4;
921 r0 ^= r1;
922 r4 &= r0;
923 r1 ^= r3;
924 r4 ^= r2;
925 r1 |= r0;
926 r1 ^= r2;
927 r0 ^= r3;
928 r2 = r1;
929 r1 |= r3;
930 r1 ^= r0;
931 subkeys[i] = r1; i+=1;
932 subkeys[i] = r2; i+=1;
933 subkeys[i] = r3; i+=1;
934 subkeys[i] = r4; i+=1;
935 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (36));
936 w4 = tt.rotate_left(11);
937 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (36 + 1));
938 w5 = tt.rotate_left(11);
939 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (36 + 2));
940 w6 = tt.rotate_left(11);
941 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (36 + 3));
942 w7 = tt.rotate_left(11);
943 r0 = w4;
944 r1 = w5;
945 r2 = w6;
946 r3 = w7;
947 r4 = r0;
948 r0 &= r2;
949 r0 ^= r3;
950 r2 ^= r1;
951 r2 ^= r0;
952 r3 |= r4;
953 r3 ^= r1;
954 r4 ^= r2;
955 r1 = r3;
956 r3 |= r4;
957 r3 ^= r0;
958 r0 &= r1;
959 r4 ^= r0;
960 r1 ^= r3;
961 r1 ^= r4;
962 r4 = !r4;
963 subkeys[i] = r2; i+=1;
964 subkeys[i] = r3; i+=1;
965 subkeys[i] = r1; i+=1;
966 subkeys[i] = r4; i+=1;
967 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (40));
968 w0 = tt.rotate_left(11);
969 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (40 + 1));
970 w1 = tt.rotate_left(11);
971 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (40 + 2));
972 w2 = tt.rotate_left(11);
973 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (40 + 3));
974 w3 = tt.rotate_left(11);
975 r0 = w0;
976 r1 = w1;
977 r2 = w2;
978 r3 = w3;
979 r0 = !r0;
980 r2 = !r2;
981 r4 = r0;
982 r0 &= r1;
983 r2 ^= r0;
984 r0 |= r3;
985 r3 ^= r2;
986 r1 ^= r0;
987 r0 ^= r4;
988 r4 |= r1;
989 r1 ^= r3;
990 r2 |= r0;
991 r2 &= r4;
992 r0 ^= r1;
993 r1 &= r2;
994 r1 ^= r0;
995 r0 &= r2;
996 r0 ^= r4;
997 subkeys[i] = r2; i+=1;
998 subkeys[i] = r0; i+=1;
999 subkeys[i] = r3; i+=1;
1000 subkeys[i] = r1; i+=1;
1001 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (44));
1002 w4 = tt.rotate_left(11);
1003 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (44 + 1));
1004 w5 = tt.rotate_left(11);
1005 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (44 + 2));
1006 w6 = tt.rotate_left(11);
1007 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (44 + 3));
1008 w7 = tt.rotate_left(11);
1009 r0 = w4;
1010 r1 = w5;
1011 r2 = w6;
1012 r3 = w7;
1013 r3 ^= r0;
1014 r4 = r1;
1015 r1 &= r3;
1016 r4 ^= r2;
1017 r1 ^= r0;
1018 r0 |= r3;
1019 r0 ^= r4;
1020 r4 ^= r3;
1021 r3 ^= r2;
1022 r2 |= r1;
1023 r2 ^= r4;
1024 r4 = !r4;
1025 r4 |= r1;
1026 r1 ^= r3;
1027 r1 ^= r4;
1028 r3 |= r0;
1029 r1 ^= r3;
1030 r4 ^= r3;
1031 subkeys[i] = r1; i+=1;
1032 subkeys[i] = r4; i+=1;
1033 subkeys[i] = r2; i+=1;
1034 subkeys[i] = r0; i+=1;
1035 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (48));
1036 w0 = tt.rotate_left(11);
1037 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (48 + 1));
1038 w1 = tt.rotate_left(11);
1039 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (48 + 2));
1040 w2 = tt.rotate_left(11);
1041 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (48 + 3));
1042 w3 = tt.rotate_left(11);
1043 r0 = w0;
1044 r1 = w1;
1045 r2 = w2;
1046 r3 = w3;
1047 r4 = r1;
1048 r1 |= r2;
1049 r1 ^= r3;
1050 r4 ^= r2;
1051 r2 ^= r1;
1052 r3 |= r4;
1053 r3 &= r0;
1054 r4 ^= r2;
1055 r3 ^= r1;
1056 r1 |= r4;
1057 r1 ^= r0;
1058 r0 |= r4;
1059 r0 ^= r2;
1060 r1 ^= r4;
1061 r2 ^= r1;
1062 r1 &= r0;
1063 r1 ^= r4;
1064 r2 = !r2;
1065 r2 |= r0;
1066 r4 ^= r2;
1067 subkeys[i] = r4; i+=1;
1068 subkeys[i] = r3; i+=1;
1069 subkeys[i] = r1; i+=1;
1070 subkeys[i] = r0; i+=1;
1071 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (52));
1072 w4 = tt.rotate_left(11);
1073 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (52 + 1));
1074 w5 = tt.rotate_left(11);
1075 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (52 + 2));
1076 w6 = tt.rotate_left(11);
1077 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (52 + 3));
1078 w7 = tt.rotate_left(11);
1079 r0 = w4;
1080 r1 = w5;
1081 r2 = w6;
1082 r3 = w7;
1083 r2 = !r2;
1084 r4 = r3;
1085 r3 &= r0;
1086 r0 ^= r4;
1087 r3 ^= r2;
1088 r2 |= r4;
1089 r1 ^= r3;
1090 r2 ^= r0;
1091 r0 |= r1;
1092 r2 ^= r1;
1093 r4 ^= r0;
1094 r0 |= r3;
1095 r0 ^= r2;
1096 r4 ^= r3;
1097 r4 ^= r0;
1098 r3 = !r3;
1099 r2 &= r4;
1100 r2 ^= r3;
1101 subkeys[i] = r0; i+=1;
1102 subkeys[i] = r1; i+=1;
1103 subkeys[i] = r4; i+=1;
1104 subkeys[i] = r2; i+=1;
1105 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (56));
1106 w0 = tt.rotate_left(11);
1107 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (56 + 1));
1108 w1 = tt.rotate_left(11);
1109 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (56 + 2));
1110 w2 = tt.rotate_left(11);
1111 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (56 + 3));
1112 w3 = tt.rotate_left(11);
1113 r0 = w0;
1114 r1 = w1;
1115 r2 = w2;
1116 r3 = w3;
1117 r0 ^= r1;
1118 r1 ^= r3;
1119 r3 = !r3;
1120 r4 = r1;
1121 r1 &= r0;
1122 r2 ^= r3;
1123 r1 ^= r2;
1124 r2 |= r4;
1125 r4 ^= r3;
1126 r3 &= r1;
1127 r3 ^= r0;
1128 r4 ^= r1;
1129 r4 ^= r2;
1130 r2 ^= r0;
1131 r0 &= r3;
1132 r2 = !r2;
1133 r0 ^= r4;
1134 r4 |= r3;
1135 r2 ^= r4;
1136 subkeys[i] = r1; i+=1;
1137 subkeys[i] = r3; i+=1;
1138 subkeys[i] = r0; i+=1;
1139 subkeys[i] = r2; i+=1;
1140 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (60));
1141 w4 = tt.rotate_left(11);
1142 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (60 + 1));
1143 w5 = tt.rotate_left(11);
1144 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (60 + 2));
1145 w6 = tt.rotate_left(11);
1146 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (60 + 3));
1147 w7 = tt.rotate_left(11);
1148 r0 = w4;
1149 r1 = w5;
1150 r2 = w6;
1151 r3 = w7;
1152 r1 ^= r3;
1153 r3 = !r3;
1154 r2 ^= r3;
1155 r3 ^= r0;
1156 r4 = r1;
1157 r1 &= r3;
1158 r1 ^= r2;
1159 r4 ^= r3;
1160 r0 ^= r4;
1161 r2 &= r4;
1162 r2 ^= r0;
1163 r0 &= r1;
1164 r3 ^= r0;
1165 r4 |= r1;
1166 r4 ^= r0;
1167 r0 |= r3;
1168 r0 ^= r2;
1169 r2 &= r3;
1170 r0 = !r0;
1171 r4 ^= r2;
1172 subkeys[i] = r1; i+=1;
1173 subkeys[i] = r4; i+=1;
1174 subkeys[i] = r0; i+=1;
1175 subkeys[i] = r3; i+=1;
1176 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (64));
1177 w0 = tt.rotate_left(11);
1178 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (64 + 1));
1179 w1 = tt.rotate_left(11);
1180 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (64 + 2));
1181 w2 = tt.rotate_left(11);
1182 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (64 + 3));
1183 w3 = tt.rotate_left(11);
1184 r0 = w0;
1185 r1 = w1;
1186 r2 = w2;
1187 r3 = w3;
1188 r4 = r0;
1189 r0 |= r3;
1190 r3 ^= r1;
1191 r1 &= r4;
1192 r4 ^= r2;
1193 r2 ^= r3;
1194 r3 &= r0;
1195 r4 |= r1;
1196 r3 ^= r4;
1197 r0 ^= r1;
1198 r4 &= r0;
1199 r1 ^= r3;
1200 r4 ^= r2;
1201 r1 |= r0;
1202 r1 ^= r2;
1203 r0 ^= r3;
1204 r2 = r1;
1205 r1 |= r3;
1206 r1 ^= r0;
1207 subkeys[i] = r1; i+=1;
1208 subkeys[i] = r2; i+=1;
1209 subkeys[i] = r3; i+=1;
1210 subkeys[i] = r4; i+=1;
1211 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (68));
1212 w4 = tt.rotate_left(11);
1213 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (68 + 1));
1214 w5 = tt.rotate_left(11);
1215 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (68 + 2));
1216 w6 = tt.rotate_left(11);
1217 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (68 + 3));
1218 w7 = tt.rotate_left(11);
1219 r0 = w4;
1220 r1 = w5;
1221 r2 = w6;
1222 r3 = w7;
1223 r4 = r0;
1224 r0 &= r2;
1225 r0 ^= r3;
1226 r2 ^= r1;
1227 r2 ^= r0;
1228 r3 |= r4;
1229 r3 ^= r1;
1230 r4 ^= r2;
1231 r1 = r3;
1232 r3 |= r4;
1233 r3 ^= r0;
1234 r0 &= r1;
1235 r4 ^= r0;
1236 r1 ^= r3;
1237 r1 ^= r4;
1238 r4 = !r4;
1239 subkeys[i] = r2; i+=1;
1240 subkeys[i] = r3; i+=1;
1241 subkeys[i] = r1; i+=1;
1242 subkeys[i] = r4; i+=1;
1243 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (72));
1244 w0 = tt.rotate_left(11);
1245 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (72 + 1));
1246 w1 = tt.rotate_left(11);
1247 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (72 + 2));
1248 w2 = tt.rotate_left(11);
1249 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (72 + 3));
1250 w3 = tt.rotate_left(11);
1251 r0 = w0;
1252 r1 = w1;
1253 r2 = w2;
1254 r3 = w3;
1255 r0 = !r0;
1256 r2 = !r2;
1257 r4 = r0;
1258 r0 &= r1;
1259 r2 ^= r0;
1260 r0 |= r3;
1261 r3 ^= r2;
1262 r1 ^= r0;
1263 r0 ^= r4;
1264 r4 |= r1;
1265 r1 ^= r3;
1266 r2 |= r0;
1267 r2 &= r4;
1268 r0 ^= r1;
1269 r1 &= r2;
1270 r1 ^= r0;
1271 r0 &= r2;
1272 r0 ^= r4;
1273 subkeys[i] = r2; i+=1;
1274 subkeys[i] = r0; i+=1;
1275 subkeys[i] = r3; i+=1;
1276 subkeys[i] = r1; i+=1;
1277 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (76));
1278 w4 = tt.rotate_left(11);
1279 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (76 + 1));
1280 w5 = tt.rotate_left(11);
1281 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (76 + 2));
1282 w6 = tt.rotate_left(11);
1283 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (76 + 3));
1284 w7 = tt.rotate_left(11);
1285 r0 = w4;
1286 r1 = w5;
1287 r2 = w6;
1288 r3 = w7;
1289 r3 ^= r0;
1290 r4 = r1;
1291 r1 &= r3;
1292 r4 ^= r2;
1293 r1 ^= r0;
1294 r0 |= r3;
1295 r0 ^= r4;
1296 r4 ^= r3;
1297 r3 ^= r2;
1298 r2 |= r1;
1299 r2 ^= r4;
1300 r4 = !r4;
1301 r4 |= r1;
1302 r1 ^= r3;
1303 r1 ^= r4;
1304 r3 |= r0;
1305 r1 ^= r3;
1306 r4 ^= r3;
1307 subkeys[i] = r1; i+=1;
1308 subkeys[i] = r4; i+=1;
1309 subkeys[i] = r2; i+=1;
1310 subkeys[i] = r0; i+=1;
1311 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (80));
1312 w0 = tt.rotate_left(11);
1313 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (80 + 1));
1314 w1 = tt.rotate_left(11);
1315 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (80 + 2));
1316 w2 = tt.rotate_left(11);
1317 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (80 + 3));
1318 w3 = tt.rotate_left(11);
1319 r0 = w0;
1320 r1 = w1;
1321 r2 = w2;
1322 r3 = w3;
1323 r4 = r1;
1324 r1 |= r2;
1325 r1 ^= r3;
1326 r4 ^= r2;
1327 r2 ^= r1;
1328 r3 |= r4;
1329 r3 &= r0;
1330 r4 ^= r2;
1331 r3 ^= r1;
1332 r1 |= r4;
1333 r1 ^= r0;
1334 r0 |= r4;
1335 r0 ^= r2;
1336 r1 ^= r4;
1337 r2 ^= r1;
1338 r1 &= r0;
1339 r1 ^= r4;
1340 r2 = !r2;
1341 r2 |= r0;
1342 r4 ^= r2;
1343 subkeys[i] = r4; i+=1;
1344 subkeys[i] = r3; i+=1;
1345 subkeys[i] = r1; i+=1;
1346 subkeys[i] = r0; i+=1;
1347 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (84));
1348 w4 = tt.rotate_left(11);
1349 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (84 + 1));
1350 w5 = tt.rotate_left(11);
1351 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (84 + 2));
1352 w6 = tt.rotate_left(11);
1353 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (84 + 3));
1354 w7 = tt.rotate_left(11);
1355 r0 = w4;
1356 r1 = w5;
1357 r2 = w6;
1358 r3 = w7;
1359 r2 = !r2;
1360 r4 = r3;
1361 r3 &= r0;
1362 r0 ^= r4;
1363 r3 ^= r2;
1364 r2 |= r4;
1365 r1 ^= r3;
1366 r2 ^= r0;
1367 r0 |= r1;
1368 r2 ^= r1;
1369 r4 ^= r0;
1370 r0 |= r3;
1371 r0 ^= r2;
1372 r4 ^= r3;
1373 r4 ^= r0;
1374 r3 = !r3;
1375 r2 &= r4;
1376 r2 ^= r3;
1377 subkeys[i] = r0; i+=1;
1378 subkeys[i] = r1; i+=1;
1379 subkeys[i] = r4; i+=1;
1380 subkeys[i] = r2; i+=1;
1381 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (88));
1382 w0 = tt.rotate_left(11);
1383 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (88 + 1));
1384 w1 = tt.rotate_left(11);
1385 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (88 + 2));
1386 w2 = tt.rotate_left(11);
1387 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (88 + 3));
1388 w3 = tt.rotate_left(11);
1389 r0 = w0;
1390 r1 = w1;
1391 r2 = w2;
1392 r3 = w3;
1393 r0 ^= r1;
1394 r1 ^= r3;
1395 r3 = !r3;
1396 r4 = r1;
1397 r1 &= r0;
1398 r2 ^= r3;
1399 r1 ^= r2;
1400 r2 |= r4;
1401 r4 ^= r3;
1402 r3 &= r1;
1403 r3 ^= r0;
1404 r4 ^= r1;
1405 r4 ^= r2;
1406 r2 ^= r0;
1407 r0 &= r3;
1408 r2 = !r2;
1409 r0 ^= r4;
1410 r4 |= r3;
1411 r2 ^= r4;
1412 subkeys[i] = r1; i+=1;
1413 subkeys[i] = r3; i+=1;
1414 subkeys[i] = r0; i+=1;
1415 subkeys[i] = r2; i+=1;
1416 tt = w4 ^ w7 ^ w1 ^ w3 ^ (0x9E3779B9 ^ (92));
1417 w4 = tt.rotate_left(11);
1418 tt = w5 ^ w0 ^ w2 ^ w4 ^ (0x9E3779B9 ^ (92 + 1));
1419 w5 = tt.rotate_left(11);
1420 tt = w6 ^ w1 ^ w3 ^ w5 ^ (0x9E3779B9 ^ (92 + 2));
1421 w6 = tt.rotate_left(11);
1422 tt = w7 ^ w2 ^ w4 ^ w6 ^ (0x9E3779B9 ^ (92 + 3));
1423 w7 = tt.rotate_left(11);
1424 r0 = w4;
1425 r1 = w5;
1426 r2 = w6;
1427 r3 = w7;
1428 r1 ^= r3;
1429 r3 = !r3;
1430 r2 ^= r3;
1431 r3 ^= r0;
1432 r4 = r1;
1433 r1 &= r3;
1434 r1 ^= r2;
1435 r4 ^= r3;
1436 r0 ^= r4;
1437 r2 &= r4;
1438 r2 ^= r0;
1439 r0 &= r1;
1440 r3 ^= r0;
1441 r4 |= r1;
1442 r4 ^= r0;
1443 r0 |= r3;
1444 r0 ^= r2;
1445 r2 &= r3;
1446 r0 = !r0;
1447 r4 ^= r2;
1448 subkeys[i] = r1; i+=1;
1449 subkeys[i] = r4; i+=1;
1450 subkeys[i] = r0; i+=1;
1451 subkeys[i] = r3; i+=1;
1452 tt = w0 ^ w3 ^ w5 ^ w7 ^ (0x9E3779B9 ^ (96));
1453 w0 = tt.rotate_left(11);
1454 tt = w1 ^ w4 ^ w6 ^ w0 ^ (0x9E3779B9 ^ (96 + 1));
1455 w1 = tt.rotate_left(11);
1456 tt = w2 ^ w5 ^ w7 ^ w1 ^ (0x9E3779B9 ^ (96 + 2));
1457 w2 = tt.rotate_left(11);
1458 tt = w3 ^ w6 ^ w0 ^ w2 ^ (0x9E3779B9 ^ (96 + 3));
1459 w3 = tt.rotate_left(11);
1460 r0 = w0;
1461 r1 = w1;
1462 r2 = w2;
1463 r3 = w3;
1464 r4 = r0;
1465 r0 |= r3;
1466 r3 ^= r1;
1467 r1 &= r4;
1468 r4 ^= r2;
1469 r2 ^= r3;
1470 r3 &= r0;
1471 r4 |= r1;
1472 r3 ^= r4;
1473 r0 ^= r1;
1474 r4 &= r0;
1475 r1 ^= r3;
1476 r4 ^= r2;
1477 r1 |= r0;
1478 r1 ^= r2;
1479 r0 ^= r3;
1480 r2 = r1;
1481 r1 |= r3;
1482 r1 ^= r0;
1483 subkeys[i] = r1; i+=1;
1484 subkeys[i] = r2; i+=1;
1485 subkeys[i] = r3; i+=1;
1486 subkeys[i] = r4;
1487}
1488
1489fn iv_setup(iv : &[u8], subkeys : &mut[u32; 100], lfsr : &mut[u32; 10], fsm_r : &mut[u32; 2]) {
1490 let mut nonce : [u8; 16] = [0; 16];
1491 if iv.len() < 16 {
1492 copy_memory(&iv, &mut nonce[0..iv.len()]);
1493 } else {
1494 copy_memory(&iv[0..16], &mut nonce[0..16]);
1495 }
1496
1497 let mut r0 : u32;
1498 let mut r1 : u32;
1499 let mut r2 : u32;
1500 let mut r3 : u32;
1501 let mut r4 : u32;
1502 r0 = read_u32_le(&nonce[0..4]);
1503 r1 = read_u32_le(&nonce[4..8]);
1504 r2 = read_u32_le(&nonce[8..12]);
1505 r3 = read_u32_le(&nonce[12..16]);
1506
1507 r0 ^= subkeys[0];
1508 r1 ^= subkeys[0 + 1];
1509 r2 ^= subkeys[0 + 2];
1510 r3 ^= subkeys[0 + 3];
1511 r3 ^= r0;
1512 r4 = r1;
1513 r1 &= r3;
1514 r4 ^= r2;
1515 r1 ^= r0;
1516 r0 |= r3;
1517 r0 ^= r4;
1518 r4 ^= r3;
1519 r3 ^= r2;
1520 r2 |= r1;
1521 r2 ^= r4;
1522 r4 = !r4;
1523 r4 |= r1;
1524 r1 ^= r3;
1525 r1 ^= r4;
1526 r3 |= r0;
1527 r1 ^= r3;
1528 r4 ^= r3;
1529 r1 = r1.rotate_left(13);
1530 r2 = r2.rotate_left(3);
1531 r4 = r4 ^ r1 ^ r2;
1532 r0 = r0 ^ r2 ^ (r1 << 3);
1533 r4 = r4.rotate_left(1);
1534 r0 = r0.rotate_left(7);
1535 r1 = r1 ^ r4 ^ r0;
1536 r2 = r2 ^ r0 ^ (r4 << 7);
1537 r1 = r1.rotate_left(5);
1538 r2 = r2.rotate_left(22);
1539 r1 ^= subkeys[4];
1540 r4 ^= subkeys[4 + 1];
1541 r2 ^= subkeys[4 + 2];
1542 r0 ^= subkeys[4 + 3];
1543 r1 = !r1;
1544 r2 = !r2;
1545 r3 = r1;
1546 r1 &= r4;
1547 r2 ^= r1;
1548 r1 |= r0;
1549 r0 ^= r2;
1550 r4 ^= r1;
1551 r1 ^= r3;
1552 r3 |= r4;
1553 r4 ^= r0;
1554 r2 |= r1;
1555 r2 &= r3;
1556 r1 ^= r4;
1557 r4 &= r2;
1558 r4 ^= r1;
1559 r1 &= r2;
1560 r1 ^= r3;
1561 r2 = r2.rotate_left(13);
1562 r0 = r0.rotate_left(3);
1563 r1 = r1 ^ r2 ^ r0;
1564 r4 = r4 ^ r0 ^ (r2 << 3);
1565 r1 = r1.rotate_left(1);
1566 r4 = r4.rotate_left(7);
1567 r2 = r2 ^ r1 ^ r4;
1568 r0 = r0 ^ r4 ^ (r1 << 7);
1569 r2 = r2.rotate_left(5);
1570 r0 = r0.rotate_left(22);
1571 r2 ^= subkeys[8];
1572 r1 ^= subkeys[8 + 1];
1573 r0 ^= subkeys[8 + 2];
1574 r4 ^= subkeys[8 + 3];
1575 r3 = r2;
1576 r2 &= r0;
1577 r2 ^= r4;
1578 r0 ^= r1;
1579 r0 ^= r2;
1580 r4 |= r3;
1581 r4 ^= r1;
1582 r3 ^= r0;
1583 r1 = r4;
1584 r4 |= r3;
1585 r4 ^= r2;
1586 r2 &= r1;
1587 r3 ^= r2;
1588 r1 ^= r4;
1589 r1 ^= r3;
1590 r3 = !r3;
1591 r0 = r0.rotate_left(13);
1592 r1 = r1.rotate_left(3);
1593 r4 = r4 ^ r0 ^ r1;
1594 r3 = r3 ^ r1 ^ (r0 << 3);
1595 r4 = r4.rotate_left(1);
1596 r3 = r3.rotate_left(7);
1597 r0 = r0 ^ r4 ^ r3;
1598 r1 = r1 ^ r3 ^ (r4 << 7);
1599 r0 = r0.rotate_left(5);
1600 r1 = r1.rotate_left(22);
1601 r0 ^= subkeys[12];
1602 r4 ^= subkeys[12 + 1];
1603 r1 ^= subkeys[12 + 2];
1604 r3 ^= subkeys[12 + 3];
1605 r2 = r0;
1606 r0 |= r3;
1607 r3 ^= r4;
1608 r4 &= r2;
1609 r2 ^= r1;
1610 r1 ^= r3;
1611 r3 &= r0;
1612 r2 |= r4;
1613 r3 ^= r2;
1614 r0 ^= r4;
1615 r2 &= r0;
1616 r4 ^= r3;
1617 r2 ^= r1;
1618 r4 |= r0;
1619 r4 ^= r1;
1620 r0 ^= r3;
1621 r1 = r4;
1622 r4 |= r3;
1623 r4 ^= r0;
1624 r4 = r4.rotate_left(13);
1625 r3 = r3.rotate_left(3);
1626 r1 = r1 ^ r4 ^ r3;
1627 r2 = r2 ^ r3 ^ (r4 << 3);
1628 r1 = r1.rotate_left(1);
1629 r2 = r2.rotate_left(7);
1630 r4 = r4 ^ r1 ^ r2;
1631 r3 = r3 ^ r2 ^ (r1 << 7);
1632 r4 = r4.rotate_left(5);
1633 r3 = r3.rotate_left(22);
1634 r4 ^= subkeys[16];
1635 r1 ^= subkeys[16 + 1];
1636 r3 ^= subkeys[16 + 2];
1637 r2 ^= subkeys[16 + 3];
1638 r1 ^= r2;
1639 r2 = !r2;
1640 r3 ^= r2;
1641 r2 ^= r4;
1642 r0 = r1;
1643 r1 &= r2;
1644 r1 ^= r3;
1645 r0 ^= r2;
1646 r4 ^= r0;
1647 r3 &= r0;
1648 r3 ^= r4;
1649 r4 &= r1;
1650 r2 ^= r4;
1651 r0 |= r1;
1652 r0 ^= r4;
1653 r4 |= r2;
1654 r4 ^= r3;
1655 r3 &= r2;
1656 r4 = !r4;
1657 r0 ^= r3;
1658 r1 = r1.rotate_left(13);
1659 r4 = r4.rotate_left(3);
1660 r0 = r0 ^ r1 ^ r4;
1661 r2 = r2 ^ r4 ^ (r1 << 3);
1662 r0 = r0.rotate_left(1);
1663 r2 = r2.rotate_left(7);
1664 r1 = r1 ^ r0 ^ r2;
1665 r4 = r4 ^ r2 ^ (r0 << 7);
1666 r1 = r1.rotate_left(5);
1667 r4 = r4.rotate_left(22);
1668 r1 ^= subkeys[20];
1669 r0 ^= subkeys[20 + 1];
1670 r4 ^= subkeys[20 + 2];
1671 r2 ^= subkeys[20 + 3];
1672 r1 ^= r0;
1673 r0 ^= r2;
1674 r2 = !r2;
1675 r3 = r0;
1676 r0 &= r1;
1677 r4 ^= r2;
1678 r0 ^= r4;
1679 r4 |= r3;
1680 r3 ^= r2;
1681 r2 &= r0;
1682 r2 ^= r1;
1683 r3 ^= r0;
1684 r3 ^= r4;
1685 r4 ^= r1;
1686 r1 &= r2;
1687 r4 = !r4;
1688 r1 ^= r3;
1689 r3 |= r2;
1690 r4 ^= r3;
1691 r0 = r0.rotate_left(13);
1692 r1 = r1.rotate_left(3);
1693 r2 = r2 ^ r0 ^ r1;
1694 r4 = r4 ^ r1 ^ (r0 << 3);
1695 r2 = r2.rotate_left(1);
1696 r4 = r4.rotate_left(7);
1697 r0 = r0 ^ r2 ^ r4;
1698 r1 = r1 ^ r4 ^ (r2 << 7);
1699 r0 = r0.rotate_left(5);
1700 r1 = r1.rotate_left(22);
1701 r0 ^= subkeys[24];
1702 r2 ^= subkeys[24 + 1];
1703 r1 ^= subkeys[24 + 2];
1704 r4 ^= subkeys[24 + 3];
1705 r1 = !r1;
1706 r3 = r4;
1707 r4 &= r0;
1708 r0 ^= r3;
1709 r4 ^= r1;
1710 r1 |= r3;
1711 r2 ^= r4;
1712 r1 ^= r0;
1713 r0 |= r2;
1714 r1 ^= r2;
1715 r3 ^= r0;
1716 r0 |= r4;
1717 r0 ^= r1;
1718 r3 ^= r4;
1719 r3 ^= r0;
1720 r4 = !r4;
1721 r1 &= r3;
1722 r1 ^= r4;
1723 r0 = r0.rotate_left(13);
1724 r3 = r3.rotate_left(3);
1725 r2 = r2 ^ r0 ^ r3;
1726 r1 = r1 ^ r3 ^ (r0 << 3);
1727 r2 = r2.rotate_left(1);
1728 r1 = r1.rotate_left(7);
1729 r0 = r0 ^ r2 ^ r1;
1730 r3 = r3 ^ r1 ^ (r2 << 7);
1731 r0 = r0.rotate_left(5);
1732 r3 = r3.rotate_left(22);
1733 r0 ^= subkeys[28];
1734 r2 ^= subkeys[28 + 1];
1735 r3 ^= subkeys[28 + 2];
1736 r1 ^= subkeys[28 + 3];
1737 r4 = r2;
1738 r2 |= r3;
1739 r2 ^= r1;
1740 r4 ^= r3;
1741 r3 ^= r2;
1742 r1 |= r4;
1743 r1 &= r0;
1744 r4 ^= r3;
1745 r1 ^= r2;
1746 r2 |= r4;
1747 r2 ^= r0;
1748 r0 |= r4;
1749 r0 ^= r3;
1750 r2 ^= r4;
1751 r3 ^= r2;
1752 r2 &= r0;
1753 r2 ^= r4;
1754 r3 = !r3;
1755 r3 |= r0;
1756 r4 ^= r3;
1757 r4 = r4.rotate_left(13);
1758 r2 = r2.rotate_left(3);
1759 r1 = r1 ^ r4 ^ r2;
1760 r0 = r0 ^ r2 ^ (r4 << 3);
1761 r1 = r1.rotate_left(1);
1762 r0 = r0.rotate_left(7);
1763 r4 = r4 ^ r1 ^ r0;
1764 r2 = r2 ^ r0 ^ (r1 << 7);
1765 r4 = r4.rotate_left(5);
1766 r2 = r2.rotate_left(22);
1767 r4 ^= subkeys[32];
1768 r1 ^= subkeys[32 + 1];
1769 r2 ^= subkeys[32 + 2];
1770 r0 ^= subkeys[32 + 3];
1771 r0 ^= r4;
1772 r3 = r1;
1773 r1 &= r0;
1774 r3 ^= r2;
1775 r1 ^= r4;
1776 r4 |= r0;
1777 r4 ^= r3;
1778 r3 ^= r0;
1779 r0 ^= r2;
1780 r2 |= r1;
1781 r2 ^= r3;
1782 r3 = !r3;
1783 r3 |= r1;
1784 r1 ^= r0;
1785 r1 ^= r3;
1786 r0 |= r4;
1787 r1 ^= r0;
1788 r3 ^= r0;
1789 r1 = r1.rotate_left(13);
1790 r2 = r2.rotate_left(3);
1791 r3 = r3 ^ r1 ^ r2;
1792 r4 = r4 ^ r2 ^ (r1 << 3);
1793 r3 = r3.rotate_left(1);
1794 r4 = r4.rotate_left(7);
1795 r1 = r1 ^ r3 ^ r4;
1796 r2 = r2 ^ r4 ^ (r3 << 7);
1797 r1 = r1.rotate_left(5);
1798 r2 = r2.rotate_left(22);
1799 r1 ^= subkeys[36];
1800 r3 ^= subkeys[36 + 1];
1801 r2 ^= subkeys[36 + 2];
1802 r4 ^= subkeys[36 + 3];
1803 r1 = !r1;
1804 r2 = !r2;
1805 r0 = r1;
1806 r1 &= r3;
1807 r2 ^= r1;
1808 r1 |= r4;
1809 r4 ^= r2;
1810 r3 ^= r1;
1811 r1 ^= r0;
1812 r0 |= r3;
1813 r3 ^= r4;
1814 r2 |= r1;
1815 r2 &= r0;
1816 r1 ^= r3;
1817 r3 &= r2;
1818 r3 ^= r1;
1819 r1 &= r2;
1820 r1 ^= r0;
1821 r2 = r2.rotate_left(13);
1822 r4 = r4.rotate_left(3);
1823 r1 = r1 ^ r2 ^ r4;
1824 r3 = r3 ^ r4 ^ (r2 << 3);
1825 r1 = r1.rotate_left(1);
1826 r3 = r3.rotate_left(7);
1827 r2 = r2 ^ r1 ^ r3;
1828 r4 = r4 ^ r3 ^ (r1 << 7);
1829 r2 = r2.rotate_left(5);
1830 r4 = r4.rotate_left(22);
1831 r2 ^= subkeys[40];
1832 r1 ^= subkeys[40 + 1];
1833 r4 ^= subkeys[40 + 2];
1834 r3 ^= subkeys[40 + 3];
1835 r0 = r2;
1836 r2 &= r4;
1837 r2 ^= r3;
1838 r4 ^= r1;
1839 r4 ^= r2;
1840 r3 |= r0;
1841 r3 ^= r1;
1842 r0 ^= r4;
1843 r1 = r3;
1844 r3 |= r0;
1845 r3 ^= r2;
1846 r2 &= r1;
1847 r0 ^= r2;
1848 r1 ^= r3;
1849 r1 ^= r0;
1850 r0 = !r0;
1851 r4 = r4.rotate_left(13);
1852 r1 = r1.rotate_left(3);
1853 r3 = r3 ^ r4 ^ r1;
1854 r0 = r0 ^ r1 ^ (r4 << 3);
1855 r3 = r3.rotate_left(1);
1856 r0 = r0.rotate_left(7);
1857 r4 = r4 ^ r3 ^ r0;
1858 r1 = r1 ^ r0 ^ (r3 << 7);
1859 r4 = r4.rotate_left(5);
1860 r1 = r1.rotate_left(22);
1861 r4 ^= subkeys[44];
1862 r3 ^= subkeys[44 + 1];
1863 r1 ^= subkeys[44 + 2];
1864 r0 ^= subkeys[44 + 3];
1865 r2 = r4;
1866 r4 |= r0;
1867 r0 ^= r3;
1868 r3 &= r2;
1869 r2 ^= r1;
1870 r1 ^= r0;
1871 r0 &= r4;
1872 r2 |= r3;
1873 r0 ^= r2;
1874 r4 ^= r3;
1875 r2 &= r4;
1876 r3 ^= r0;
1877 r2 ^= r1;
1878 r3 |= r4;
1879 r3 ^= r1;
1880 r4 ^= r0;
1881 r1 = r3;
1882 r3 |= r0;
1883 r3 ^= r4;
1884 r3 = r3.rotate_left(13);
1885 r0 = r0.rotate_left(3);
1886 r1 = r1 ^ r3 ^ r0;
1887 r2 = r2 ^ r0 ^ (r3 << 3);
1888 r1 = r1.rotate_left(1);
1889 r2 = r2.rotate_left(7);
1890 r3 = r3 ^ r1 ^ r2;
1891 r0 = r0 ^ r2 ^ (r1 << 7);
1892 r3 = r3.rotate_left(5);
1893 r0 = r0.rotate_left(22);
1894 lfsr[9] = r3;
1895 lfsr[8] = r1;
1896 lfsr[7] = r0;
1897 lfsr[6] = r2;
1898 r3 ^= subkeys[48];
1899 r1 ^= subkeys[48 + 1];
1900 r0 ^= subkeys[48 + 2];
1901 r2 ^= subkeys[48 + 3];
1902 r1 ^= r2;
1903 r2 = !r2;
1904 r0 ^= r2;
1905 r2 ^= r3;
1906 r4 = r1;
1907 r1 &= r2;
1908 r1 ^= r0;
1909 r4 ^= r2;
1910 r3 ^= r4;
1911 r0 &= r4;
1912 r0 ^= r3;
1913 r3 &= r1;
1914 r2 ^= r3;
1915 r4 |= r1;
1916 r4 ^= r3;
1917 r3 |= r2;
1918 r3 ^= r0;
1919 r0 &= r2;
1920 r3 = !r3;
1921 r4 ^= r0;
1922 r1 = r1.rotate_left(13);
1923 r3 = r3.rotate_left(3);
1924 r4 = r4 ^ r1 ^ r3;
1925 r2 = r2 ^ r3 ^ (r1 << 3);
1926 r4 = r4.rotate_left(1);
1927 r2 = r2.rotate_left(7);
1928 r1 = r1 ^ r4 ^ r2;
1929 r3 = r3 ^ r2 ^ (r4 << 7);
1930 r1 = r1.rotate_left(5);
1931 r3 = r3.rotate_left(22);
1932 r1 ^= subkeys[52];
1933 r4 ^= subkeys[52 + 1];
1934 r3 ^= subkeys[52 + 2];
1935 r2 ^= subkeys[52 + 3];
1936 r1 ^= r4;
1937 r4 ^= r2;
1938 r2 = !r2;
1939 r0 = r4;
1940 r4 &= r1;
1941 r3 ^= r2;
1942 r4 ^= r3;
1943 r3 |= r0;
1944 r0 ^= r2;
1945 r2 &= r4;
1946 r2 ^= r1;
1947 r0 ^= r4;
1948 r0 ^= r3;
1949 r3 ^= r1;
1950 r1 &= r2;
1951 r3 = !r3;
1952 r1 ^= r0;
1953 r0 |= r2;
1954 r3 ^= r0;
1955 r4 = r4.rotate_left(13);
1956 r1 = r1.rotate_left(3);
1957 r2 = r2 ^ r4 ^ r1;
1958 r3 = r3 ^ r1 ^ (r4 << 3);
1959 r2 = r2.rotate_left(1);
1960 r3 = r3.rotate_left(7);
1961 r4 = r4 ^ r2 ^ r3;
1962 r1 = r1 ^ r3 ^ (r2 << 7);
1963 r4 = r4.rotate_left(5);
1964 r1 = r1.rotate_left(22);
1965 r4 ^= subkeys[56];
1966 r2 ^= subkeys[56 + 1];
1967 r1 ^= subkeys[56 + 2];
1968 r3 ^= subkeys[56 + 3];
1969 r1 = !r1;
1970 r0 = r3;
1971 r3 &= r4;
1972 r4 ^= r0;
1973 r3 ^= r1;
1974 r1 |= r0;
1975 r2 ^= r3;
1976 r1 ^= r4;
1977 r4 |= r2;
1978 r1 ^= r2;
1979 r0 ^= r4;
1980 r4 |= r3;
1981 r4 ^= r1;
1982 r0 ^= r3;
1983 r0 ^= r4;
1984 r3 = !r3;
1985 r1 &= r0;
1986 r1 ^= r3;
1987 r4 = r4.rotate_left(13);
1988 r0 = r0.rotate_left(3);
1989 r2 = r2 ^ r4 ^ r0;
1990 r1 = r1 ^ r0 ^ (r4 << 3);
1991 r2 = r2.rotate_left(1);
1992 r1 = r1.rotate_left(7);
1993 r4 = r4 ^ r2 ^ r1;
1994 r0 = r0 ^ r1 ^ (r2 << 7);
1995 r4 = r4.rotate_left(5);
1996 r0 = r0.rotate_left(22);
1997 r4 ^= subkeys[60];
1998 r2 ^= subkeys[60 + 1];
1999 r0 ^= subkeys[60 + 2];
2000 r1 ^= subkeys[60 + 3];
2001 r3 = r2;
2002 r2 |= r0;
2003 r2 ^= r1;
2004 r3 ^= r0;
2005 r0 ^= r2;
2006 r1 |= r3;
2007 r1 &= r4;
2008 r3 ^= r0;
2009 r1 ^= r2;
2010 r2 |= r3;
2011 r2 ^= r4;
2012 r4 |= r3;
2013 r4 ^= r0;
2014 r2 ^= r3;
2015 r0 ^= r2;
2016 r2 &= r4;
2017 r2 ^= r3;
2018 r0 = !r0;
2019 r0 |= r4;
2020 r3 ^= r0;
2021 r3 = r3.rotate_left(13);
2022 r2 = r2.rotate_left(3);
2023 r1 = r1 ^ r3 ^ r2;
2024 r4 = r4 ^ r2 ^ (r3 << 3);
2025 r1 = r1.rotate_left(1);
2026 r4 = r4.rotate_left(7);
2027 r3 = r3 ^ r1 ^ r4;
2028 r2 = r2 ^ r4 ^ (r1 << 7);
2029 r3 = r3.rotate_left(5);
2030 r2 = r2.rotate_left(22);
2031 r3 ^= subkeys[64];
2032 r1 ^= subkeys[64 + 1];
2033 r2 ^= subkeys[64 + 2];
2034 r4 ^= subkeys[64 + 3];
2035 r4 ^= r3;
2036 r0 = r1;
2037 r1 &= r4;
2038 r0 ^= r2;
2039 r1 ^= r3;
2040 r3 |= r4;
2041 r3 ^= r0;
2042 r0 ^= r4;
2043 r4 ^= r2;
2044 r2 |= r1;
2045 r2 ^= r0;
2046 r0 = !r0;
2047 r0 |= r1;
2048 r1 ^= r4;
2049 r1 ^= r0;
2050 r4 |= r3;
2051 r1 ^= r4;
2052 r0 ^= r4;
2053 r1 = r1.rotate_left(13);
2054 r2 = r2.rotate_left(3);
2055 r0 = r0 ^ r1 ^ r2;
2056 r3 = r3 ^ r2 ^ (r1 << 3);
2057 r0 = r0.rotate_left(1);
2058 r3 = r3.rotate_left(7);
2059 r1 = r1 ^ r0 ^ r3;
2060 r2 = r2 ^ r3 ^ (r0 << 7);
2061 r1 = r1.rotate_left(5);
2062 r2 = r2.rotate_left(22);
2063 r1 ^= subkeys[68];
2064 r0 ^= subkeys[68 + 1];
2065 r2 ^= subkeys[68 + 2];
2066 r3 ^= subkeys[68 + 3];
2067 r1 = !r1;
2068 r2 = !r2;
2069 r4 = r1;
2070 r1 &= r0;
2071 r2 ^= r1;
2072 r1 |= r3;
2073 r3 ^= r2;
2074 r0 ^= r1;
2075 r1 ^= r4;
2076 r4 |= r0;
2077 r0 ^= r3;
2078 r2 |= r1;
2079 r2 &= r4;
2080 r1 ^= r0;
2081 r0 &= r2;
2082 r0 ^= r1;
2083 r1 &= r2;
2084 r1 ^= r4;
2085 r2 = r2.rotate_left(13);
2086 r3 = r3.rotate_left(3);
2087 r1 = r1 ^ r2 ^ r3;
2088 r0 = r0 ^ r3 ^ (r2 << 3);
2089 r1 = r1.rotate_left(1);
2090 r0 = r0.rotate_left(7);
2091 r2 = r2 ^ r1 ^ r0;
2092 r3 = r3 ^ r0 ^ (r1 << 7);
2093 r2 = r2.rotate_left(5);
2094 r3 = r3.rotate_left(22);
2095 fsm_r[0] = r2;
2096 lfsr[4] = r1;
2097 fsm_r[1] = r3;
2098 lfsr[5] = r0;
2099 r2 ^= subkeys[72];
2100 r1 ^= subkeys[72 + 1];
2101 r3 ^= subkeys[72 + 2];
2102 r0 ^= subkeys[72 + 3];
2103 r4 = r2;
2104 r2 &= r3;
2105 r2 ^= r0;
2106 r3 ^= r1;
2107 r3 ^= r2;
2108 r0 |= r4;
2109 r0 ^= r1;
2110 r4 ^= r3;
2111 r1 = r0;
2112 r0 |= r4;
2113 r0 ^= r2;
2114 r2 &= r1;
2115 r4 ^= r2;
2116 r1 ^= r0;
2117 r1 ^= r4;
2118 r4 = !r4;
2119 r3 = r3.rotate_left(13);
2120 r1 = r1.rotate_left(3);
2121 r0 = r0 ^ r3 ^ r1;
2122 r4 = r4 ^ r1 ^ (r3 << 3);
2123 r0 = r0.rotate_left(1);
2124 r4 = r4.rotate_left(7);
2125 r3 = r3 ^ r0 ^ r4;
2126 r1 = r1 ^ r4 ^ (r0 << 7);
2127 r3 = r3.rotate_left(5);
2128 r1 = r1.rotate_left(22);
2129 r3 ^= subkeys[76];
2130 r0 ^= subkeys[76 + 1];
2131 r1 ^= subkeys[76 + 2];
2132 r4 ^= subkeys[76 + 3];
2133 r2 = r3;
2134 r3 |= r4;
2135 r4 ^= r0;
2136 r0 &= r2;
2137 r2 ^= r1;
2138 r1 ^= r4;
2139 r4 &= r3;
2140 r2 |= r0;
2141 r4 ^= r2;
2142 r3 ^= r0;
2143 r2 &= r3;
2144 r0 ^= r4;
2145 r2 ^= r1;
2146 r0 |= r3;
2147 r0 ^= r1;
2148 r3 ^= r4;
2149 r1 = r0;
2150 r0 |= r4;
2151 r0 ^= r3;
2152 r0 = r0.rotate_left(13);
2153 r4 = r4.rotate_left(3);
2154 r1 = r1 ^ r0 ^ r4;
2155 r2 = r2 ^ r4 ^ (r0 << 3);
2156 r1 = r1.rotate_left(1);
2157 r2 = r2.rotate_left(7);
2158 r0 = r0 ^ r1 ^ r2;
2159 r4 = r4 ^ r2 ^ (r1 << 7);
2160 r0 = r0.rotate_left(5);
2161 r4 = r4.rotate_left(22);
2162 r0 ^= subkeys[80];
2163 r1 ^= subkeys[80 + 1];
2164 r4 ^= subkeys[80 + 2];
2165 r2 ^= subkeys[80 + 3];
2166 r1 ^= r2;
2167 r2 = !r2;
2168 r4 ^= r2;
2169 r2 ^= r0;
2170 r3 = r1;
2171 r1 &= r2;
2172 r1 ^= r4;
2173 r3 ^= r2;
2174 r0 ^= r3;
2175 r4 &= r3;
2176 r4 ^= r0;
2177 r0 &= r1;
2178 r2 ^= r0;
2179 r3 |= r1;
2180 r3 ^= r0;
2181 r0 |= r2;
2182 r0 ^= r4;
2183 r4 &= r2;
2184 r0 = !r0;
2185 r3 ^= r4;
2186 r1 = r1.rotate_left(13);
2187 r0 = r0.rotate_left(3);
2188 r3 = r3 ^ r1 ^ r0;
2189 r2 = r2 ^ r0 ^ (r1 << 3);
2190 r3 = r3.rotate_left(1);
2191 r2 = r2.rotate_left(7);
2192 r1 = r1 ^ r3 ^ r2;
2193 r0 = r0 ^ r2 ^ (r3 << 7);
2194 r1 = r1.rotate_left(5);
2195 r0 = r0.rotate_left(22);
2196 r1 ^= subkeys[84];
2197 r3 ^= subkeys[84 + 1];
2198 r0 ^= subkeys[84 + 2];
2199 r2 ^= subkeys[84 + 3];
2200 r1 ^= r3;
2201 r3 ^= r2;
2202 r2 = !r2;
2203 r4 = r3;
2204 r3 &= r1;
2205 r0 ^= r2;
2206 r3 ^= r0;
2207 r0 |= r4;
2208 r4 ^= r2;
2209 r2 &= r3;
2210 r2 ^= r1;
2211 r4 ^= r3;
2212 r4 ^= r0;
2213 r0 ^= r1;
2214 r1 &= r2;
2215 r0 = !r0;
2216 r1 ^= r4;
2217 r4 |= r2;
2218 r0 ^= r4;
2219 r3 = r3.rotate_left(13);
2220 r1 = r1.rotate_left(3);
2221 r2 = r2 ^ r3 ^ r1;
2222 r0 = r0 ^ r1 ^ (r3 << 3);
2223 r2 = r2.rotate_left(1);
2224 r0 = r0.rotate_left(7);
2225 r3 = r3 ^ r2 ^ r0;
2226 r1 = r1 ^ r0 ^ (r2 << 7);
2227 r3 = r3.rotate_left(5);
2228 r1 = r1.rotate_left(22);
2229 r3 ^= subkeys[88];
2230 r2 ^= subkeys[88 + 1];
2231 r1 ^= subkeys[88 + 2];
2232 r0 ^= subkeys[88 + 3];
2233 r1 = !r1;
2234 r4 = r0;
2235 r0 &= r3;
2236 r3 ^= r4;
2237 r0 ^= r1;
2238 r1 |= r4;
2239 r2 ^= r0;
2240 r1 ^= r3;
2241 r3 |= r2;
2242 r1 ^= r2;
2243 r4 ^= r3;
2244 r3 |= r0;
2245 r3 ^= r1;
2246 r4 ^= r0;
2247 r4 ^= r3;
2248 r0 = !r0;
2249 r1 &= r4;
2250 r1 ^= r0;
2251 r3 = r3.rotate_left(13);
2252 r4 = r4.rotate_left(3);
2253 r2 = r2 ^ r3 ^ r4;
2254 r1 = r1 ^ r4 ^ (r3 << 3);
2255 r2 = r2.rotate_left(1);
2256 r1 = r1.rotate_left(7);
2257 r3 = r3 ^ r2 ^ r1;
2258 r4 = r4 ^ r1 ^ (r2 << 7);
2259 r3 = r3.rotate_left(5);
2260 r4 = r4.rotate_left(22);
2261 r3 ^= subkeys[92];
2262 r2 ^= subkeys[92 + 1];
2263 r4 ^= subkeys[92 + 2];
2264 r1 ^= subkeys[92 + 3];
2265 r0 = r2;
2266 r2 |= r4;
2267 r2 ^= r1;
2268 r0 ^= r4;
2269 r4 ^= r2;
2270 r1 |= r0;
2271 r1 &= r3;
2272 r0 ^= r4;
2273 r1 ^= r2;
2274 r2 |= r0;
2275 r2 ^= r3;
2276 r3 |= r0;
2277 r3 ^= r4;
2278 r2 ^= r0;
2279 r4 ^= r2;
2280 r2 &= r3;
2281 r2 ^= r0;
2282 r4 = !r4;
2283 r4 |= r3;
2284 r0 ^= r4;
2285 r0 = r0.rotate_left(13);
2286 r2 = r2.rotate_left(3);
2287 r1 = r1 ^ r0 ^ r2;
2288 r3 = r3 ^ r2 ^ (r0 << 3);
2289 r1 = r1.rotate_left(1);
2290 r3 = r3.rotate_left(7);
2291 r0 = r0 ^ r1 ^ r3;
2292 r2 = r2 ^ r3 ^ (r1 << 7);
2293 r0 = r0.rotate_left(5);
2294 r2 = r2.rotate_left(22);
2295 r0 ^= subkeys[96];
2296 r1 ^= subkeys[96 + 1];
2297 r2 ^= subkeys[96 + 2];
2298 r3 ^= subkeys[96 + 3];
2299 lfsr[3] = r0;
2300 lfsr[2] = r1;
2301 lfsr[1] = r2;
2302 lfsr[0] = r3;
2303}
2304
2305
2306impl SynchronousStreamCipher for Sosemanuk {
2307 fn process(&mut self, input: &[u8], output: &mut [u8]) {
2308 assert!(input.len() == output.len());
2309 for (x, y) in input.iter().zip(output.iter_mut()) {
2310 *y = *x ^ self.next();
2311 }
2312 }
2313}
2314
2315impl Encryptor for Sosemanuk {
2316 fn encrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
2317 -> Result<BufferResult, SymmetricCipherError> {
2318 symm_enc_or_dec(self, input, output)
2319 }
2320}
2321
2322impl Decryptor for Sosemanuk {
2323 fn decrypt(&mut self, input: &mut RefReadBuffer, output: &mut RefWriteBuffer, _: bool)
2324 -> Result<BufferResult, SymmetricCipherError> {
2325 symm_enc_or_dec(self, input, output)
2326 }
2327}
2328
2329
2330#[cfg(test)]
2331mod test {
2332 use sosemanuk::Sosemanuk;
2333 use symmetriccipher::SynchronousStreamCipher;
2334 use serialize::hex::{FromHex};
2335
2336 #[test]
2339 fn test_sosemanuk_ecrypt_set_1_vector_0() {
2340 let key = "8000000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap();
2341 let nonce = "00000000000000000000000000000000".from_hex().unwrap();
2342
2343 let input = [0u8; 64];
2344 let expected_output_hex = "1782FABFF497A0E89E16E1BCF22F0FE8AA8C566D293AA35B2425E4F26E31C3E7701C08A0D614AF3D3861A7DFF7D6A38A0EFE84A29FADF68D390A3D15B75C972D";
2345 let expected_output = expected_output_hex.from_hex().unwrap();
2346
2347 let mut output = [0u8; 64];
2348
2349 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2350 sosemanuk.process(&input, &mut output);
2351 let expected: &[u8] = expected_output.as_ref();
2352 assert!(output.as_ref() == expected);
2353 }
2354
2355 #[test]
2356 fn test_sosemanuk_ecrypt_set_2_vector_63() {
2357 let key = "3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F".from_hex().unwrap();
2358 let nonce = "00000000000000000000000000000000".from_hex().unwrap();
2359
2360 let input = [0u8; 64];
2361 let expected_output_hex = "7D755F30A2B747A50D7D28147EDF0B3E3FAB6856A7373C7306C00D1D4076969354D7AB4343C0115E7839502C5C699ED06DB119968AEBFD08D8B968A7161D613F";
2362 let expected_output = expected_output_hex.from_hex().unwrap();
2363
2364 let mut output = [0u8; 64];
2365
2366 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2367 sosemanuk.process(&input, &mut output);
2368 let expected: &[u8] = expected_output.as_ref();
2369 assert!(output.as_ref() == expected);
2370 }
2371
2372 #[test]
2373 fn test_sosemanuk_ecrypt_set_2_vector_90() {
2374 let key = "5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A".from_hex().unwrap();
2375 let nonce = "00000000000000000000000000000000".from_hex().unwrap();
2376
2377 let input = [0u8; 64];
2378 let expected_output_hex = "F5D7D72686322D1751AFD16A1DD98282D2B9A1EE0C305DF52F86AE1B831E90C22E2DE089CEE656A992736385D9135B823B3611098674BF820986A4342B89ABF7";
2379 let expected_output = expected_output_hex.from_hex().unwrap();
2380
2381 let mut output = [0u8; 64];
2382
2383 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2384 sosemanuk.process(&input, &mut output);
2385 let expected: &[u8] = expected_output.as_ref();
2386 assert!(output.as_ref() == expected);
2387 }
2388
2389 #[test]
2390 fn test_sosemanuk_ecrypt_set_3_vector_135() {
2391 let key = "8788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4".from_hex().unwrap();
2392 let nonce = "00000000000000000000000000000000".from_hex().unwrap();
2393
2394 let input = [0u8; 64];
2395 let expected_output_hex = "9D7EE5A10BBB0756D66B8DAA5AE08F41B05C9E7C6B13532EAA81F224282B61C66DEEE5AF6251DB26C49B865C5AD4250AE89787FC86C35409CF2986CF820293AA";
2396 let expected_output = expected_output_hex.from_hex().unwrap();
2397
2398 let mut output = [0u8; 64];
2399
2400 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2401 sosemanuk.process(&input, &mut output);
2402 let expected: &[u8] = expected_output.as_ref();
2403 assert!(output.as_ref() == expected);
2404 }
2405
2406 #[test]
2407 fn test_sosemanuk_ecrypt_set_3_vector_207() {
2408 let key = "CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEE".from_hex().unwrap();
2409 let nonce = "00000000000000000000000000000000".from_hex().unwrap();
2410
2411 let input = [0u8; 64];
2412 let expected_output_hex = "F028923659C6C0A17065E013368D93EBCF2F4FD892B6E27E104EF0A2605708EA26336AE966D5058BC144F7954FE2FC3C258F00734AA5BEC8281814B746197084";
2413 let expected_output = expected_output_hex.from_hex().unwrap();
2414
2415 let mut output = [0u8; 64];
2416
2417 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2418 sosemanuk.process(&input, &mut output);
2419 let expected: &[u8] = expected_output.as_ref();
2420 assert!(output.as_ref() == expected);
2421 }
2422
2423 #[test]
2424 fn test_sosemanuk_ecrypt_set_6_vector_3() {
2425 let key = "0F62B5085BAE0154A7FA4DA0F34699EC3F92E5388BDE3184D72A7DD02376C91C".from_hex().unwrap();
2426 let nonce = "288FF65DC42B92F960C72E95FC63CA31".from_hex().unwrap();
2427
2428 let input = [0u8; 64];
2429 let expected_output_hex = "1FC4F2E266B21C24FDDB3492D40A3FA6DE32CDF13908511E84420ABDFA1D3B0FEC600F83409C57CBE0394B90CDB1D759243EFD8B8E2AB7BC453A8D8A3515183E";
2430 let expected_output = expected_output_hex.from_hex().unwrap();
2431
2432 let mut output = [0u8; 64];
2433
2434 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2435 sosemanuk.process(&input, &mut output);
2436 let expected: &[u8] = expected_output.as_ref();
2437 assert!(output.as_ref() == expected);
2438 }
2439
2440 #[test]
2443 fn test_sosemanuk_vector128_test1() {
2444 let key = "A7C083FEB7".from_hex().unwrap();
2445 let nonce = "00112233445566778899AABBCCDDEEFF".from_hex().unwrap();
2446
2447 let input = [0u8; 160];
2448 let expected_output_hex = "FE81D2162C9A100D04895C454A77515BBE6A431A935CB90E2221EBB7EF502328943539492EFF6310C871054C2889CC728F82E86B1AFFF4334B6127A13A155C75151630BD482EB673FF5DB477FA6C53EBE1A4EC38C23C5400C315455D93A2ACED9598604727FA340D5F2A8BD757B77833F74BD2BC049313C80616B4A06268AE350DB92EEC4FA56C171374A67A80C006D0EAD048CE7B640F17D3D5A62D1F251C21";
2449 let expected_output = expected_output_hex.from_hex().unwrap();
2450
2451 let mut output = [0u8; 160];
2452
2453 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2454 sosemanuk.process(&input, &mut output);
2455 let expected: &[u8] = expected_output.as_ref();
2456 assert!(output.as_ref() == expected);
2457 }
2458
2459 #[test]
2460 fn test_sosemanuk_vector128_test2() {
2461 let key = "00112233445566778899AABBCCDDEEFF".from_hex().unwrap();
2462 let nonce = "8899AABBCCDDEEFF0011223344556677".from_hex().unwrap();
2463
2464 let input = [0u8; 160];
2465 let expected_output_hex = "FA61DBEB71178131A77C714BD2EABF4E1394207A25698AA1308F2F063A0F760604CF67569BA59A3DFAD7F00145C78D29C5FFE5F964950486424451952C84039D234D9C37EECBBCA1EBFB0DD16EA1194A6AFC1A460E33E33FE8D55C48977079C687810D74FEDDEE1B3986218FB1E1C1765E4DF64D7F6911C19A270C59C74B24461717F86CE3B11808FACD4F2E714168DA44CF6360D54DDA2241BCB79401A4EDCC";
2466 let expected_output = expected_output_hex.from_hex().unwrap();
2467
2468 let mut output = [0u8; 160];
2469
2470 let mut sosemanuk = Sosemanuk::new(key.as_ref(), nonce.as_ref());
2471 sosemanuk.process(&input, &mut output);
2472 let expected: &[u8] = expected_output.as_ref();
2473 assert!(output.as_ref() == expected);
2474 }
2475}
2476
2477#[cfg(all(test, feature = "with-bench"))]
2478mod bench {
2479 use test::Bencher;
2480 use symmetriccipher::SynchronousStreamCipher;
2481 use sosemanuk::Sosemanuk;
2482
2483 #[bench]
2484 pub fn sosemanuk_10(bh: & mut Bencher) {
2485 let mut sosemanuk = Sosemanuk::new(&[0; 32], &[0; 16]);
2486 let input = [1u8; 10];
2487 let mut output = [0u8; 10];
2488 bh.iter( || {
2489 sosemanuk.process(&input, &mut output);
2490 });
2491 bh.bytes = input.len() as u64;
2492 }
2493
2494 #[bench]
2495 pub fn sosemanuk_1k(bh: & mut Bencher) {
2496 let mut sosemanuk = Sosemanuk::new(&[0; 32], &[0; 16]);
2497 let input = [1u8; 1024];
2498 let mut output = [0u8; 1024];
2499 bh.iter( || {
2500 sosemanuk.process(&input, &mut output);
2501 });
2502 bh.bytes = input.len() as u64;
2503 }
2504
2505 #[bench]
2506 pub fn sosemanuk_64k(bh: & mut Bencher) {
2507 let mut sosemanuk = Sosemanuk::new(&[0; 32], &[0; 16]);
2508 let input = [1u8; 65536];
2509 let mut output = [0u8; 65536];
2510 bh.iter( || {
2511 sosemanuk.process(&input, &mut output);
2512 });
2513 bh.bytes = input.len() as u64;
2514 }
2515}