1use super::turing_tables::{MULTAB, QBOX, SBOX};
2
3const MAX_KEY_LENGTH: usize = 32; const MAX_IV_LENGTH: usize = 48; const MAX_STREAM_LENGTH: usize = 340; const SHIFT_REGISTER_LENGTH: usize = 17; const ROUND_OUTPUT_LENGTH: usize = 20; pub struct Turing {
10 key_length: usize,
11 mixed_key: [u32; MAX_KEY_LENGTH / 4],
12 shift_register: [u32; SHIFT_REGISTER_LENGTH],
13 s0: [u32; 256],
14 s1: [u32; 256],
15 s2: [u32; 256],
16 s3: [u32; 256],
17}
18
19impl Turing {
20 pub fn new() -> Self {
21 Turing {
22 key_length: 0,
23 mixed_key: [0; MAX_KEY_LENGTH / 4],
24 shift_register: [0; SHIFT_REGISTER_LENGTH],
25 s0: [0; 256],
26 s1: [0; 256],
27 s2: [0; 256],
28 s3: [0; 256],
29 }
30 }
31
32 pub fn turing_key(&mut self, key: &[u8], length: usize) -> Result<(), &'static str> {
34 if (length & 0x03) != 0 || length > MAX_KEY_LENGTH {
35 return Err("Invalid key length");
36 }
37
38 self.key_length = 0;
39 for i in (0..length).step_by(4) {
40 self.mixed_key[self.key_length] = Self::fixed_s(Self::byte_array_to_word(key, i));
41 self.key_length += 1;
42 }
43 Self::mix_words(&mut self.mixed_key, self.key_length);
44
45 self.build_s_box_tables();
46 Ok(())
47 }
48
49 pub fn turing_iv(&mut self, iv: &[u8], length: usize) -> Result<(), &'static str> {
51 if (length & 0x03) != 0 || (length + 4 * self.key_length) > MAX_IV_LENGTH {
52 return Err("Invalid IV length");
53 }
54
55 let mut i = 0;
56 let mut j = 0;
57
58 while j < length {
60 self.shift_register[i] = Self::fixed_s(Self::byte_array_to_word(iv, j));
61 i += 1;
62 j += 4;
63 }
64
65 for j in 0..self.key_length {
67 self.shift_register[i] = self.mixed_key[j];
68 i += 1;
69 }
70
71 self.shift_register[i] =
73 ((self.key_length as u32) << 4) | ((length as u32) >> 2) | 0x01020300;
74 i += 1;
75
76 let mut j = 0;
78 while i < SHIFT_REGISTER_LENGTH {
79 self.shift_register[i] = self.s(
80 self.shift_register[j].wrapping_add(self.shift_register[i - 1]),
81 0,
82 );
83 i += 1;
84 j += 1;
85 }
86
87 Self::mix_words(&mut self.shift_register, SHIFT_REGISTER_LENGTH);
89 Ok(())
90 }
91
92 pub fn turing_gen(&mut self, buf: &mut [u8]) -> Result<usize, &'static str> {
95 if buf.len() < MAX_STREAM_LENGTH {
96 return Err("Buffer is too small");
97 }
98
99 let rounds = [
100 (0, 0), (5, 20), (10, 40),
101 (15, 60), (3, 80), (8, 100),
102 (13, 120), (1, 140), (6, 160),
103 (11, 180), (16, 200), (4, 220),
104 (9, 240), (14, 260), (2, 280),
105 (7, 300), (12, 320),
106 ];
107
108 for (z, offset) in rounds {
109 self.turing_gen_round(z, buf, offset);
110 }
111
112 Ok(MAX_STREAM_LENGTH)
113 }
114
115 fn byte_array_to_word(b: &[u8], offset: usize) -> u32 {
117 ((b[offset] as u32) << 24)
118 | ((b[offset + 1] as u32) << 16)
119 | ((b[offset + 2] as u32) << 8)
120 | (b[offset + 3] as u32)
121 }
122
123 fn build_s_box_tables(&mut self) {
124 for j in 0..256 {
125 let mut w = 0;
126 let mut k = j as u32;
127 for i in 0..self.key_length {
128 k = SBOX[(Self::get_byte(self.mixed_key[i], 0) ^ k) as usize];
129 w ^= Self::left_rotate_word(QBOX[k as usize], i as u32);
130 }
131 self.s0[j] = (w & 0x00FFFFFF) | (k << 24);
132 }
133
134 for j in 0..256 {
135 let mut w = 0;
136 let mut k = j as u32;
137 for i in 0..self.key_length {
138 k = SBOX[(Self::get_byte(self.mixed_key[i], 1) ^ k) as usize];
139 w ^= Self::left_rotate_word(QBOX[k as usize], (i + 8) as u32);
140 }
141 self.s1[j] = (w & 0xFF00FFFF) | (k << 16);
142 }
143
144 for j in 0..256 {
145 let mut w = 0;
146 let mut k = j as u32;
147 for i in 0..self.key_length {
148 k = SBOX[(Self::get_byte(self.mixed_key[i], 2) ^ k) as usize];
149 w ^= Self::left_rotate_word(QBOX[k as usize], (i + 16) as u32);
150 }
151 self.s2[j] = (w & 0xFFFF00FF) | (k << 8);
152 }
153
154 for j in 0..256 {
155 let mut w = 0;
156 let mut k = j as u32;
157 for i in 0..self.key_length {
158 k = SBOX[(Self::get_byte(self.mixed_key[i], 3) ^ k) as usize];
159 w ^= Self::left_rotate_word(QBOX[k as usize], (i + 24) as u32);
160 }
161 self.s3[j] = (w & 0xFFFFFF00) | k;
162 }
163 }
164
165 fn get_byte(word: u32, i: u32) -> u32 {
167 (word >> (24 - 8 * i)) & 0xff
168 }
169
170 fn left_rotate_word(word: u32, bits: u32) -> u32 {
172 word.rotate_left(bits)
173 }
174
175 fn fixed_s(w: u32) -> u32 {
179 let mut w = w;
180 let mut b;
181
182 b = SBOX[Self::get_byte(w, 0) as usize];
183 w = ((w ^ QBOX[b as usize]) & 0x00ffffff) | (b << 24);
184
185 b = SBOX[Self::get_byte(w, 1) as usize];
186 w = ((w ^ Self::left_rotate_word(QBOX[b as usize], 8)) & 0xff00ffff) | (b << 16);
187
188 b = SBOX[Self::get_byte(w, 2) as usize];
189 w = ((w ^ Self::left_rotate_word(QBOX[b as usize], 16)) & 0xffff00ff) | (b << 8);
190
191 b = SBOX[Self::get_byte(w, 3) as usize];
192 w = ((w ^ Self::left_rotate_word(QBOX[b as usize], 24)) & 0xffffff00) | b;
193
194 w
195 }
196
197 fn s(&self, w: u32, r: u32) -> u32 {
206 self.s0[Self::get_byte(w, (r) & 0x3) as usize]
207 ^ self.s1[Self::get_byte(w, (1 + r) & 0x3) as usize]
208 ^ self.s2[Self::get_byte(w, (2 + r) & 0x3) as usize]
209 ^ self.s3[Self::get_byte(w, (3 + r) & 0x3) as usize]
210 }
211
212 fn mix_words(w: &mut [u32], n: usize) {
214 let mut sum: u32 = 0;
215 let mut i = 0;
216
217 while i < n - 1 {
218 sum = sum.wrapping_add(w[i]);
219 i += 1;
220 }
221 w[n - 1] = w[n - 1].wrapping_add(sum);
222 sum = w[n - 1];
223
224 i = 0;
225 while i < n - 1 {
226 w[i] = w[i].wrapping_add(sum);
227 i += 1;
228 }
229 }
230
231 fn turing_gen_round(&mut self, z: usize, buf: &mut [u8], offset: usize) -> usize {
235 self.step(z);
236
237 let mut a = self.shift_register[Self::offset(z + 1, 16)];
238 let mut b = self.shift_register[Self::offset(z + 1, 13)];
239 let mut c = self.shift_register[Self::offset(z + 1, 6)];
240 let mut d = self.shift_register[Self::offset(z + 1, 1)];
241 let mut e = self.shift_register[Self::offset(z + 1, 0)];
242
243 e = e.wrapping_add(a.wrapping_add(b).wrapping_add(c).wrapping_add(d));
245 a = a.wrapping_add(e);
246 b = b.wrapping_add(e);
247 c = c.wrapping_add(e);
248 d = d.wrapping_add(e);
249
250 a = self.s(a, 0);
251 b = self.s(b, 1);
252 c = self.s(c, 2);
253 d = self.s(d, 3);
254 e = self.s(e, 0);
255
256 e = e.wrapping_add(a.wrapping_add(b).wrapping_add(c).wrapping_add(d));
258 a = a.wrapping_add(e);
259 b = b.wrapping_add(e);
260 c = c.wrapping_add(e);
261 d = d.wrapping_add(e);
262
263 self.step(z + 1);
264 self.step(z + 2);
265 self.step(z + 3);
266
267 a = a.wrapping_add(self.shift_register[Self::offset(z + 4, 14)]);
268 b = b.wrapping_add(self.shift_register[Self::offset(z + 4, 12)]);
269 c = c.wrapping_add(self.shift_register[Self::offset(z + 4, 8)]);
270 d = d.wrapping_add(self.shift_register[Self::offset(z + 4, 1)]);
271 e = e.wrapping_add(self.shift_register[Self::offset(z + 4, 0)]);
272
273 Self::word_to_byte_array(a, buf, offset);
274 Self::word_to_byte_array(b, buf, offset + 4);
275 Self::word_to_byte_array(c, buf, offset + 8);
276 Self::word_to_byte_array(d, buf, offset + 12);
277 Self::word_to_byte_array(e, buf, offset + 16);
278
279 self.step(z + 4);
280
281 ROUND_OUTPUT_LENGTH
282 }
283
284 fn step(&mut self, z: usize) {
286 let sr15 = self.shift_register[Self::offset(z, 15)];
287 let sr4 = self.shift_register[Self::offset(z, 4)];
288 let sr0 = self.shift_register[Self::offset(z, 0)];
289
290 self.shift_register[Self::offset(z, 0)] =
291 sr15 ^ sr4 ^ (sr0 << 8) ^ MULTAB[((sr0 >> 24) & 0xFF) as usize];
292 }
293
294 fn offset(zero: usize, i: usize) -> usize {
296 (zero + i) % SHIFT_REGISTER_LENGTH
297 }
298
299 fn word_to_byte_array(word: u32, b: &mut [u8], offset: usize) {
301 b[offset] = (word >> 24) as u8;
302 b[offset + 1] = (word >> 16) as u8;
303 b[offset + 2] = (word >> 8) as u8;
304 b[offset + 3] = word as u8;
305 }
306}