1use crate::Block;
2use cipher::{
3 Array,
4 array::ArraySize,
5 consts::{U2, U4},
6};
7use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, Shr};
8
9pub(crate) trait Word:
11 Sized
12 + Copy
13 + Default
14 + 'static
15 + BitAnd<Output = Self>
16 + BitAndAssign
17 + BitOr<Output = Self>
18 + BitOrAssign
19 + BitXor<Output = Self>
20 + BitXorAssign
21 + Not<Output = Self>
22 + Shl<u32, Output = Self>
23 + Shr<u32, Output = Self>
24{
25 type Blocks: ArraySize;
27
28 const ROW_BITS: u32 = (size_of::<Self>() * 2) as u32;
30
31 const HALF_ROW: u32 = Self::ROW_BITS / 2;
33 const QUARTER_ROW: u32 = Self::ROW_BITS / 4;
35
36 #[inline(always)]
38 fn ror_distance(rows: u32, cols: u32) -> u32 {
39 rows * Self::ROW_BITS + cols * Self::QUARTER_ROW
40 }
41
42 fn ror(self, n: u32) -> Self;
44
45 fn uniform_row(b: u8) -> Self;
47
48 fn pack_rows(r0: u8, r1: u8, r2: u8, r3: u8) -> Self;
50
51 fn byte_repeat(b: u8) -> Self;
53
54 fn bitslice(output: &mut [Self], input: &Array<Block, Self::Blocks>);
56
57 fn inv_bitslice(input: &[Self]) -> Array<Block, Self::Blocks>;
59}
60
61impl Word for u32 {
62 type Blocks = U2;
63
64 #[inline(always)]
65 fn ror(self, n: u32) -> u32 {
66 self.rotate_right(n)
67 }
68
69 #[inline(always)]
70 fn uniform_row(b: u8) -> u32 {
71 (b as u32) * 0x01010101
72 }
73
74 #[inline(always)]
75 fn pack_rows(r0: u8, r1: u8, r2: u8, r3: u8) -> u32 {
76 (r0 as u32) | ((r1 as u32) << 8) | ((r2 as u32) << 16) | ((r3 as u32) << 24)
77 }
78
79 #[inline(always)]
80 fn byte_repeat(b: u8) -> u32 {
81 (b as u32) * 0x01010101
82 }
83
84 fn bitslice(output: &mut [u32], input: &Array<Block, U2>) {
86 debug_assert_eq!(output.len(), 8);
87 let input0 = input[0].as_slice();
88 let input1 = input[1].as_slice();
89
90 let mut t = [
101 u32::from_le_bytes(input0[0x00..0x04].try_into().unwrap()),
102 u32::from_le_bytes(input1[0x00..0x04].try_into().unwrap()),
103 u32::from_le_bytes(input0[0x04..0x08].try_into().unwrap()),
104 u32::from_le_bytes(input1[0x04..0x08].try_into().unwrap()),
105 u32::from_le_bytes(input0[0x08..0x0c].try_into().unwrap()),
106 u32::from_le_bytes(input1[0x08..0x0c].try_into().unwrap()),
107 u32::from_le_bytes(input0[0x0c..0x10].try_into().unwrap()),
108 u32::from_le_bytes(input1[0x0c..0x10].try_into().unwrap()),
109 ];
110
111 bitslice_swaps(&mut t);
112
113 output[..8].copy_from_slice(&t);
116 }
117
118 fn inv_bitslice(input: &[u32]) -> Array<Block, U2> {
120 debug_assert_eq!(input.len(), 8);
121
122 let mut t = [
131 input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
132 ];
133
134 bitslice_swaps(&mut t);
135
136 let mut output = Array::<Block, U2>::default();
137 output[0][0x00..0x04].copy_from_slice(&t[0].to_le_bytes());
140 output[0][0x04..0x08].copy_from_slice(&t[2].to_le_bytes());
141 output[0][0x08..0x0c].copy_from_slice(&t[4].to_le_bytes());
142 output[0][0x0c..0x10].copy_from_slice(&t[6].to_le_bytes());
143 output[1][0x00..0x04].copy_from_slice(&t[1].to_le_bytes());
144 output[1][0x04..0x08].copy_from_slice(&t[3].to_le_bytes());
145 output[1][0x08..0x0c].copy_from_slice(&t[5].to_le_bytes());
146 output[1][0x0c..0x10].copy_from_slice(&t[7].to_le_bytes());
147
148 output
151 }
152}
153
154#[inline(always)]
158const fn double_bits(b: u8) -> u16 {
159 let x = b as u16;
160 let x = (x | (x << 4)) & 0x0f0f;
162 let x = (x | (x << 2)) & 0x3333;
163 let x = (x | (x << 1)) & 0x5555;
164 x | (x << 1)
166}
167
168impl Word for u64 {
169 type Blocks = U4;
170
171 #[inline(always)]
172 fn ror(self, n: u32) -> u64 {
173 self.rotate_right(n)
174 }
175
176 #[inline(always)]
177 fn uniform_row(b: u8) -> u64 {
178 (double_bits(b) as u64) * 0x0001_0001_0001_0001
179 }
180
181 #[inline(always)]
182 fn pack_rows(r0: u8, r1: u8, r2: u8, r3: u8) -> u64 {
183 (double_bits(r0) as u64)
184 | ((double_bits(r1) as u64) << 16)
185 | ((double_bits(r2) as u64) << 32)
186 | ((double_bits(r3) as u64) << 48)
187 }
188
189 #[inline(always)]
190 fn byte_repeat(b: u8) -> u64 {
191 (b as u64) * 0x0101010101010101
192 }
193
194 fn bitslice(output: &mut [u64], input: &Array<Block, U4>) {
196 debug_assert_eq!(output.len(), 8);
197
198 #[rustfmt::skip]
207 fn read_reordered(input: &[u8]) -> u64 {
208 (u64::from(input[0x0]) ) |
209 (u64::from(input[0x1]) << 0x10) |
210 (u64::from(input[0x2]) << 0x20) |
211 (u64::from(input[0x3]) << 0x30) |
212 (u64::from(input[0x8]) << 0x08) |
213 (u64::from(input[0x9]) << 0x18) |
214 (u64::from(input[0xa]) << 0x28) |
215 (u64::from(input[0xb]) << 0x38)
216 }
217
218 let mut t = [
223 read_reordered(&input[0][0x00..0x0c]),
224 read_reordered(&input[1][0x00..0x0c]),
225 read_reordered(&input[2][0x00..0x0c]),
226 read_reordered(&input[3][0x00..0x0c]),
227 read_reordered(&input[0][0x04..0x10]),
228 read_reordered(&input[1][0x04..0x10]),
229 read_reordered(&input[2][0x04..0x10]),
230 read_reordered(&input[3][0x04..0x10]),
231 ];
232
233 bitslice_swaps(&mut t);
234
235 output[..8].copy_from_slice(&t);
238 }
239
240 fn inv_bitslice(input: &[u64]) -> Array<Block, U4> {
242 debug_assert_eq!(input.len(), 8);
243
244 let mut t = [
253 input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
254 ];
255
256 bitslice_swaps(&mut t);
257
258 #[rustfmt::skip]
259 fn write_reordered(columns: u64, output: &mut [u8]) {
260 output[0x0] = (columns ) as u8;
261 output[0x1] = (columns >> 0x10) as u8;
262 output[0x2] = (columns >> 0x20) as u8;
263 output[0x3] = (columns >> 0x30) as u8;
264 output[0x8] = (columns >> 0x08) as u8;
265 output[0x9] = (columns >> 0x18) as u8;
266 output[0xa] = (columns >> 0x28) as u8;
267 output[0xb] = (columns >> 0x38) as u8;
268 }
269
270 let mut output = Array::<Block, U4>::default();
271 write_reordered(t[0], &mut output[0][0x00..0x0c]);
276 write_reordered(t[4], &mut output[0][0x04..0x10]);
277 write_reordered(t[1], &mut output[1][0x00..0x0c]);
278 write_reordered(t[5], &mut output[1][0x04..0x10]);
279 write_reordered(t[2], &mut output[2][0x00..0x0c]);
280 write_reordered(t[6], &mut output[2][0x04..0x10]);
281 write_reordered(t[3], &mut output[3][0x00..0x0c]);
282 write_reordered(t[7], &mut output[3][0x04..0x10]);
283
284 output
287 }
288}
289
290#[inline(always)]
297fn bitslice_swaps<W: Word>(t: &mut [W; 8]) {
298 use super::utils::delta_swap_2;
299 let [t0, t1, t2, t3, t4, t5, t6, t7] = t;
300
301 let m0 = W::byte_repeat(0x55);
304 delta_swap_2(t1, t0, 1, m0);
305 delta_swap_2(t3, t2, 1, m0);
306 delta_swap_2(t5, t4, 1, m0);
307 delta_swap_2(t7, t6, 1, m0);
308
309 let m1 = W::byte_repeat(0x33);
312 delta_swap_2(t2, t0, 2, m1);
313 delta_swap_2(t3, t1, 2, m1);
314 delta_swap_2(t6, t4, 2, m1);
315 delta_swap_2(t7, t5, 2, m1);
316
317 let m2 = W::byte_repeat(0x0f);
320 delta_swap_2(t4, t0, 4, m2);
321 delta_swap_2(t5, t1, 4, m2);
322 delta_swap_2(t6, t2, 4, m2);
323 delta_swap_2(t7, t3, 4, m2);
324}