turing_cipher/
turing.rs

1use super::turing_tables::{MULTAB, QBOX, SBOX};
2
3const MAX_KEY_LENGTH: usize = 32; // bytes
4const MAX_IV_LENGTH: usize = 48; // bytes
5const MAX_STREAM_LENGTH: usize = 340; // bytes, maximum stream generated by one call
6const SHIFT_REGISTER_LENGTH: usize = 17; // words
7const ROUND_OUTPUT_LENGTH: usize = 20; // bytes
8
9pub 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    /// 设置密钥
33    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    /// 设置初始化向量
50    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        // 首先复制IV并进行混合
59        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        // 继续使用预混合的密钥
66        for j in 0..self.key_length {
67            self.shift_register[i] = self.mixed_key[j];
68            i += 1;
69        }
70
71        // 长度相关的字
72        self.shift_register[i] =
73            ((self.key_length as u32) << 4) | ((length as u32) >> 2) | 0x01020300;
74        i += 1;
75
76        // 填充寄存器的其余部分
77        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        // 混合所有字
88        Self::mix_words(&mut self.shift_register, SHIFT_REGISTER_LENGTH);
89        Ok(())
90    }
91
92    /// Generate a 340-byte buffer of cipher data.
93    /// Return the number of bytes generated
94    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    /// 字节数组转字(大端序)
116    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    /// 获取字的指定字节
166    fn get_byte(word: u32, i: u32) -> u32 {
167        (word >> (24 - 8 * i)) & 0xff
168    }
169
170    /// 字左循环移位
171    fn left_rotate_word(word: u32, bits: u32) -> u32 {
172        word.rotate_left(bits)
173    }
174
175    /// Performs a reversible transformation of a word, based on the S-boxes.
176    /// The reversibility isn't used, but it guarantees no loss of information,
177    /// and hence no equivalent keys or IVs.
178    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    /// Pushes a word through the keyed S-boxes.
198    /// As the bytes bounce around the permutation table, they are used
199    /// to build up words from the Qbox entries. Then the byte position
200    /// corresponding to the input byte is replaced with the result of
201    /// the S-box, which is a permutation of the input and guarantees
202    /// a balanced function.
203    /// Also added a rotation of the input word, to combat a differential
204    /// trail allowed by the PHT.
205    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    /// General word-wide n-PHT (Pseudo-Hadamard Transform)
213    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    /// Generates a 5-word block of output.
232    /// Buffering issues are outside the scope of this implementation.
233    /// Returns the number of bytes of stream generated.
234    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        // 混合5个字(变种PHT)
244        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        // 再次混合5个字
257        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    /// 步进LFSR
285    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    /// 计算移位寄存器的当前偏移量
295    fn offset(zero: usize, i: usize) -> usize {
296        (zero + i) % SHIFT_REGISTER_LENGTH
297    }
298
299    /// 将字转换为字节数组(大端序)
300    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}