turing_cipher/
turing.rs

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; // bytes
14pub const MAX_IV_LENGTH: usize = 48; // bytes
15pub const MAX_STREAM_LENGTH: usize = 340; // bytes, maximum stream generated by one call
16pub const SHIFT_REGISTER_LENGTH: usize = 17; // words
17pub const ROUND_OUTPUT_LENGTH: usize = 20; // bytes
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] 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    /// 获取字的指定字节
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 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    /// Pushes a word through the keyed S-boxes.
200    /// As the bytes bounce around the permutation table, they are used
201    /// to build up words from the Qbox entries. Then the byte position
202    /// corresponding to the input byte is replaced with the result of
203    /// the S-box, which is a permutation of the input and guarantees
204    /// a balanced function.
205    /// Also added a rotation of the input word, to combat a differential
206    /// trail allowed by the PHT.
207    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    /// General word-wide n-PHT (Pseudo-Hadamard Transform)
215    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    /// Generates a 5-word block of output.
234    /// Buffering issues are outside the scope of this implementation.
235    /// Returns the number of bytes of stream generated.
236    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        // 混合5个字(变种PHT)
246        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        // 再次混合5个字
259        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    /// 步进LFSR
287    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    /// 计算移位寄存器的当前偏移量
297    fn offset(zero: usize, i: usize) -> usize {
298        (zero + i) % SHIFT_REGISTER_LENGTH
299    }
300
301    /// 将字转换为字节数组(大端序)
302    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}