1use super::turing_tables::{MULTAB, QBOX, SBOX};
2
3pub struct Turing {
4 key_length: usize,
5 mixed_key: [u32; MAX_KEY_LENGTH / 4],
6 shift_register: [u32; SHIFT_REGISTER_LENGTH],
7 s0: [u32; 256],
8 s1: [u32; 256],
9 s2: [u32; 256],
10 s3: [u32; 256],
11}
12
13pub const MAX_KEY_LENGTH: usize = 32; pub const MAX_IV_LENGTH: usize = 48; pub const MAX_STREAM_LENGTH: usize = 340; pub const SHIFT_REGISTER_LENGTH: usize = 17; pub const ROUND_OUTPUT_LENGTH: usize = 20; impl 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] as u32;
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] as u32;
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] as u32;
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] as u32;
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 as u32) << 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)
187 | ((b as u32) << 16);
188
189 b = SBOX[Self::get_byte(w, 2) as usize];
190 w = ((w ^ Self::left_rotate_word(QBOX[b as usize], 16)) & 0xffff00ff)
191 | ((b as u32) << 8);
192
193 b = SBOX[Self::get_byte(w, 3) as usize];
194 w = ((w ^ Self::left_rotate_word(QBOX[b as usize], 24)) & 0xffffff00) | b as u32;
195
196 w
197 }
198
199 fn s(&self, w: u32, r: u32) -> u32 {
208 self.s0[Self::get_byte(w, (r) & 0x3) as usize]
209 ^ self.s1[Self::get_byte(w, (1 + r) & 0x3) as usize]
210 ^ self.s2[Self::get_byte(w, (2 + r) & 0x3) as usize]
211 ^ self.s3[Self::get_byte(w, (3 + r) & 0x3) as usize]
212 }
213
214 fn mix_words(w: &mut [u32], n: usize) {
216 let mut sum: u32 = 0;
217 let mut i = 0;
218
219 while i < n - 1 {
220 sum = sum.wrapping_add(w[i]);
221 i += 1;
222 }
223 w[n - 1] = w[n - 1].wrapping_add(sum);
224 sum = w[n - 1];
225
226 i = 0;
227 while i < n - 1 {
228 w[i] = w[i].wrapping_add(sum);
229 i += 1;
230 }
231 }
232
233 fn turing_gen_round(&mut self, z: usize, buf: &mut [u8], offset: usize) -> usize {
237 self.step(z);
238
239 let mut a = self.shift_register[Self::offset(z + 1, 16)];
240 let mut b = self.shift_register[Self::offset(z + 1, 13)];
241 let mut c = self.shift_register[Self::offset(z + 1, 6)];
242 let mut d = self.shift_register[Self::offset(z + 1, 1)];
243 let mut e = self.shift_register[Self::offset(z + 1, 0)];
244
245 e = e.wrapping_add(a.wrapping_add(b).wrapping_add(c).wrapping_add(d));
247 a = a.wrapping_add(e);
248 b = b.wrapping_add(e);
249 c = c.wrapping_add(e);
250 d = d.wrapping_add(e);
251
252 a = self.s(a, 0);
253 b = self.s(b, 1);
254 c = self.s(c, 2);
255 d = self.s(d, 3);
256 e = self.s(e, 0);
257
258 e = e.wrapping_add(a.wrapping_add(b).wrapping_add(c).wrapping_add(d));
260 a = a.wrapping_add(e);
261 b = b.wrapping_add(e);
262 c = c.wrapping_add(e);
263 d = d.wrapping_add(e);
264
265 self.step(z + 1);
266 self.step(z + 2);
267 self.step(z + 3);
268
269 a = a.wrapping_add(self.shift_register[Self::offset(z + 4, 14)]);
270 b = b.wrapping_add(self.shift_register[Self::offset(z + 4, 12)]);
271 c = c.wrapping_add(self.shift_register[Self::offset(z + 4, 8)]);
272 d = d.wrapping_add(self.shift_register[Self::offset(z + 4, 1)]);
273 e = e.wrapping_add(self.shift_register[Self::offset(z + 4, 0)]);
274
275 Self::word_to_byte_array(a, buf, offset);
276 Self::word_to_byte_array(b, buf, offset + 4);
277 Self::word_to_byte_array(c, buf, offset + 8);
278 Self::word_to_byte_array(d, buf, offset + 12);
279 Self::word_to_byte_array(e, buf, offset + 16);
280
281 self.step(z + 4);
282
283 ROUND_OUTPUT_LENGTH
284 }
285
286 fn step(&mut self, z: usize) {
288 let sr15 = self.shift_register[Self::offset(z, 15)];
289 let sr4 = self.shift_register[Self::offset(z, 4)];
290 let sr0 = self.shift_register[Self::offset(z, 0)];
291
292 self.shift_register[Self::offset(z, 0)] =
293 sr15 ^ sr4 ^ (sr0 << 8) ^ MULTAB[((sr0 >> 24) & 0xFF) as usize];
294 }
295
296 fn offset(zero: usize, i: usize) -> usize {
298 (zero + i) % SHIFT_REGISTER_LENGTH
299 }
300
301 fn word_to_byte_array(word: u32, b: &mut [u8], offset: usize) {
303 b[offset] = (word >> 24) as u8;
304 b[offset + 1] = (word >> 16) as u8;
305 b[offset + 2] = (word >> 8) as u8;
306 b[offset + 3] = word as u8;
307 }
308}