1mod invert;
4mod multiply;
5mod packed_byte_sliced;
6mod square;
7
8pub use packed_byte_sliced::*;
9
10#[cfg(test)]
11pub mod tests {
12 use proptest::prelude::*;
13
14 use super::*;
15 use crate::{
16 packed::{get_packed_slice, set_packed_slice},
17 underlier::WithUnderlier,
18 PackedAESBinaryField16x16b, PackedAESBinaryField16x32b, PackedAESBinaryField16x8b,
19 PackedAESBinaryField1x128b, PackedAESBinaryField2x128b, PackedAESBinaryField2x64b,
20 PackedAESBinaryField32x16b, PackedAESBinaryField32x8b, PackedAESBinaryField4x128b,
21 PackedAESBinaryField4x32b, PackedAESBinaryField4x64b, PackedAESBinaryField64x8b,
22 PackedAESBinaryField8x16b, PackedAESBinaryField8x32b, PackedAESBinaryField8x64b,
23 PackedBinaryField128x1b, PackedBinaryField256x1b, PackedBinaryField512x1b, PackedField,
24 };
25
26 fn scalars_vec_strategy<P: PackedField<Scalar: WithUnderlier<Underlier: Arbitrary>>>(
27 ) -> impl Strategy<Value = Vec<P::Scalar>> {
28 proptest::collection::vec(
29 any::<<P::Scalar as WithUnderlier>::Underlier>().prop_map(P::Scalar::from_underlier),
30 P::WIDTH..=P::WIDTH,
31 )
32 }
33
34 macro_rules! define_byte_sliced_test {
35 ($module_name:ident, $name:ident, $scalar_type:ty, $associated_packed:ty) => {
36 mod $module_name {
37 use super::*;
38
39 proptest! {
40 #[test]
41 fn check_from_fn(scalar_elems in scalars_vec_strategy::<$name>()) {
42 let bytesliced = <$name>::from_fn(|i| scalar_elems[i]);
43 for i in 0..<$name>::WIDTH {
44 assert_eq!(scalar_elems[i], bytesliced.get(i));
45 }
46 }
47
48 #[test]
49 fn check_add(scalar_elems_a in scalars_vec_strategy::<$name>(), scalar_elems_b in scalars_vec_strategy::<$name>()) {
50 let bytesliced_a = <$name>::from_scalars(scalar_elems_a.iter().copied());
51 let bytesliced_b = <$name>::from_scalars(scalar_elems_b.iter().copied());
52
53 let bytesliced_result = bytesliced_a + bytesliced_b;
54
55 for i in 0..<$name>::WIDTH {
56 assert_eq!(scalar_elems_a[i] + scalar_elems_b[i], bytesliced_result.get(i));
57 }
58 }
59
60 #[test]
61 fn check_add_assign(scalar_elems_a in scalars_vec_strategy::<$name>(), scalar_elems_b in scalars_vec_strategy::<$name>()) {
62 let mut bytesliced_a = <$name>::from_scalars(scalar_elems_a.iter().copied());
63 let bytesliced_b = <$name>::from_scalars(scalar_elems_b.iter().copied());
64
65 bytesliced_a += bytesliced_b;
66
67 for i in 0..<$name>::WIDTH {
68 assert_eq!(scalar_elems_a[i] + scalar_elems_b[i], bytesliced_a.get(i));
69 }
70 }
71
72 #[test]
73 fn check_sub(scalar_elems_a in scalars_vec_strategy::<$name>(), scalar_elems_b in scalars_vec_strategy::<$name>()) {
74 let bytesliced_a = <$name>::from_scalars(scalar_elems_a.iter().copied());
75 let bytesliced_b = <$name>::from_scalars(scalar_elems_b.iter().copied());
76
77 let bytesliced_result = bytesliced_a - bytesliced_b;
78
79 for i in 0..<$name>::WIDTH {
80 assert_eq!(scalar_elems_a[i] - scalar_elems_b[i], bytesliced_result.get(i));
81 }
82 }
83
84 #[test]
85 fn check_sub_assign(scalar_elems_a in scalars_vec_strategy::<$name>(), scalar_elems_b in scalars_vec_strategy::<$name>()) {
86 let mut bytesliced_a = <$name>::from_scalars(scalar_elems_a.iter().copied());
87 let bytesliced_b = <$name>::from_scalars(scalar_elems_b.iter().copied());
88
89 bytesliced_a -= bytesliced_b;
90
91 for i in 0..<$name>::WIDTH {
92 assert_eq!(scalar_elems_a[i] - scalar_elems_b[i], bytesliced_a.get(i));
93 }
94 }
95
96 #[test]
97 fn check_mul(scalar_elems_a in scalars_vec_strategy::<$name>(), scalar_elems_b in scalars_vec_strategy::<$name>()) {
98 let bytesliced_a = <$name>::from_scalars(scalar_elems_a.iter().copied());
99 let bytesliced_b = <$name>::from_scalars(scalar_elems_b.iter().copied());
100
101 let bytesliced_result = bytesliced_a * bytesliced_b;
102
103 for i in 0..<$name>::WIDTH {
104 assert_eq!(scalar_elems_a[i] * scalar_elems_b[i], bytesliced_result.get(i));
105 }
106 }
107
108 #[test]
109 fn check_mul_assign(scalar_elems_a in scalars_vec_strategy::<$name>(), scalar_elems_b in scalars_vec_strategy::<$name>()) {
110 let mut bytesliced_a = <$name>::from_scalars(scalar_elems_a.iter().copied());
111 let bytesliced_b = <$name>::from_scalars(scalar_elems_b.iter().copied());
112
113 bytesliced_a *= bytesliced_b;
114
115 for i in 0..<$name>::WIDTH {
116 assert_eq!(scalar_elems_a[i] * scalar_elems_b[i], bytesliced_a.get(i));
117 }
118 }
119
120 #[test]
121 fn check_inv(scalar_elems in scalars_vec_strategy::<$name>()) {
122 let bytesliced = <$name>::from_scalars(scalar_elems.iter().copied());
123
124 let bytesliced_result = bytesliced.invert_or_zero();
125
126 for (i, scalar_elem) in scalar_elems.iter().enumerate() {
127 assert_eq!(scalar_elem.invert_or_zero(), bytesliced_result.get(i));
128 }
129 }
130
131 #[test]
132 fn check_square(scalar_elems in scalars_vec_strategy::<$name>()) {
133 let bytesliced = <$name>::from_scalars(scalar_elems.iter().copied());
134
135 let bytesliced_result = bytesliced.square();
136
137 for (i, scalar_elem) in scalar_elems.iter().enumerate() {
138 assert_eq!(scalar_elem.square(), bytesliced_result.get(i));
139 }
140 }
141
142 #[test]
143 fn check_linear_transformation(scalar_elems in scalars_vec_strategy::<$name>()) {
144 use crate::linear_transformation::{PackedTransformationFactory, FieldLinearTransformation, Transformation};
145 use rand::{rngs::StdRng, SeedableRng};
146
147 let bytesliced = <$name>::from_scalars(scalar_elems.iter().copied());
148
149 let linear_transformation = FieldLinearTransformation::random(StdRng::seed_from_u64(0));
150 let packed_transformation = <$name>::make_packed_transformation(linear_transformation.clone());
151
152 let bytesliced_result = packed_transformation.transform(&bytesliced);
153
154 for i in 0..<$name>::WIDTH {
155 assert_eq!(linear_transformation.transform(&scalar_elems[i]), bytesliced_result.get(i));
156 }
157 }
158
159 #[test]
160 fn check_interleave(scalar_elems_a in scalars_vec_strategy::<$name>(), scalar_elems_b in scalars_vec_strategy::<$name>()) {
161 let bytesliced_a = <$name>::from_scalars(scalar_elems_a.iter().copied());
162 let bytesliced_b = <$name>::from_scalars(scalar_elems_b.iter().copied());
163
164 for log_block_len in 0..<$name>::LOG_WIDTH {
165 let (bytesliced_c, bytesliced_d) = bytesliced_a.interleave(bytesliced_b, log_block_len);
166
167 let block_len = 1 << log_block_len;
168 for offset in (0..<$name>::WIDTH).step_by(2 * block_len) {
169 for i in 0..block_len {
170 assert_eq!(bytesliced_c.get(offset + i), scalar_elems_a[offset + i]);
171 assert_eq!(bytesliced_c.get(offset + block_len + i), scalar_elems_b[offset + i]);
172
173 assert_eq!(bytesliced_d.get(offset + i), scalar_elems_a[offset + block_len + i]);
174 assert_eq!(bytesliced_d.get(offset + block_len + i), scalar_elems_b[offset + block_len + i]);
175 }
176 }
177 }
178 }
179
180 #[test]
181 fn check_transpose_to(scalar_elems in scalars_vec_strategy::<$name>()) {
182 let bytesliced = <$name>::from_scalars(scalar_elems.iter().copied());
183 let mut destination = [<$associated_packed>::zero(); <$name>::HEIGHT_BYTES];
184 bytesliced.transpose_to(&mut destination);
185
186 for i in 0..<$name>::WIDTH {
187 assert_eq!(scalar_elems[i], get_packed_slice(&destination, i));
188 }
189 }
190
191 #[test]
192 fn check_transpose_from(scalar_elems in scalars_vec_strategy::<$name>()) {
193 let mut destination = [<$associated_packed>::zero(); <$name>::HEIGHT_BYTES];
194 for i in 0..<$name>::WIDTH {
195 set_packed_slice(&mut destination, i, scalar_elems[i]);
196 }
197
198 let bytesliced = <$name>::transpose_from(&destination);
199
200 for i in 0..<$name>::WIDTH {
201 assert_eq!(get_packed_slice(&destination, i), bytesliced.get(i));
202 }
203 }
204 }
205 }
206 };
207 }
208
209 define_byte_sliced_test!(
211 tests_3d_16x128,
212 ByteSlicedAES16x128b,
213 AESTowerField128b,
214 PackedAESBinaryField1x128b
215 );
216 define_byte_sliced_test!(
217 tests_3d_16x64,
218 ByteSlicedAES16x64b,
219 AESTowerField64b,
220 PackedAESBinaryField2x64b
221 );
222 define_byte_sliced_test!(
223 tests_3d_2x16x64,
224 ByteSlicedAES2x16x64b,
225 AESTowerField64b,
226 PackedAESBinaryField2x64b
227 );
228 define_byte_sliced_test!(
229 tests_3d_16x32,
230 ByteSlicedAES16x32b,
231 AESTowerField32b,
232 PackedAESBinaryField4x32b
233 );
234 define_byte_sliced_test!(
235 tests_3d_4x16x32,
236 ByteSlicedAES4x16x32b,
237 AESTowerField32b,
238 PackedAESBinaryField4x32b
239 );
240 define_byte_sliced_test!(
241 tests_3d_16x16,
242 ByteSlicedAES16x16b,
243 AESTowerField16b,
244 PackedAESBinaryField8x16b
245 );
246 define_byte_sliced_test!(
247 tests_3d_8x16x16,
248 ByteSlicedAES8x16x16b,
249 AESTowerField16b,
250 PackedAESBinaryField8x16b
251 );
252 define_byte_sliced_test!(
253 tests_3d_16x8,
254 ByteSlicedAES16x8b,
255 AESTowerField8b,
256 PackedAESBinaryField16x8b
257 );
258 define_byte_sliced_test!(
259 tests_3d_16x16x8,
260 ByteSlicedAES16x16x8b,
261 AESTowerField8b,
262 PackedAESBinaryField16x8b
263 );
264
265 define_byte_sliced_test!(
266 tests_3d_16x128x1,
267 ByteSliced16x128x1b,
268 BinaryField1b,
269 PackedBinaryField128x1b
270 );
271 define_byte_sliced_test!(
272 tests_3d_8x128x1,
273 ByteSliced8x128x1b,
274 BinaryField1b,
275 PackedBinaryField128x1b
276 );
277 define_byte_sliced_test!(
278 tests_3d_4x128x1,
279 ByteSliced4x128x1b,
280 BinaryField1b,
281 PackedBinaryField128x1b
282 );
283 define_byte_sliced_test!(
284 tests_3d_2x128x1,
285 ByteSliced2x128x1b,
286 BinaryField1b,
287 PackedBinaryField128x1b
288 );
289 define_byte_sliced_test!(
290 tests_3d_1x128x1,
291 ByteSliced1x128x1b,
292 BinaryField1b,
293 PackedBinaryField128x1b
294 );
295
296 define_byte_sliced_test!(
298 tests_3d_32x128,
299 ByteSlicedAES32x128b,
300 AESTowerField128b,
301 PackedAESBinaryField2x128b
302 );
303 define_byte_sliced_test!(
304 tests_3d_32x64,
305 ByteSlicedAES32x64b,
306 AESTowerField64b,
307 PackedAESBinaryField4x64b
308 );
309 define_byte_sliced_test!(
310 tests_3d_2x32x64,
311 ByteSlicedAES2x32x64b,
312 AESTowerField64b,
313 PackedAESBinaryField4x64b
314 );
315 define_byte_sliced_test!(
316 tests_3d_32x32,
317 ByteSlicedAES32x32b,
318 AESTowerField32b,
319 PackedAESBinaryField8x32b
320 );
321 define_byte_sliced_test!(
322 tests_3d_4x32x32,
323 ByteSlicedAES4x32x32b,
324 AESTowerField32b,
325 PackedAESBinaryField8x32b
326 );
327 define_byte_sliced_test!(
328 tests_3d_32x16,
329 ByteSlicedAES32x16b,
330 AESTowerField16b,
331 PackedAESBinaryField16x16b
332 );
333 define_byte_sliced_test!(
334 tests_3d_8x32x16,
335 ByteSlicedAES8x32x16b,
336 AESTowerField16b,
337 PackedAESBinaryField16x16b
338 );
339 define_byte_sliced_test!(
340 tests_3d_32x8,
341 ByteSlicedAES32x8b,
342 AESTowerField8b,
343 PackedAESBinaryField32x8b
344 );
345 define_byte_sliced_test!(
346 tests_3d_16x32x8,
347 ByteSlicedAES16x32x8b,
348 AESTowerField8b,
349 PackedAESBinaryField32x8b
350 );
351
352 define_byte_sliced_test!(
353 tests_3d_16x256x1,
354 ByteSliced16x256x1b,
355 BinaryField1b,
356 PackedBinaryField256x1b
357 );
358 define_byte_sliced_test!(
359 tests_3d_8x256x1,
360 ByteSliced8x256x1b,
361 BinaryField1b,
362 PackedBinaryField256x1b
363 );
364 define_byte_sliced_test!(
365 tests_3d_4x256x1,
366 ByteSliced4x256x1b,
367 BinaryField1b,
368 PackedBinaryField256x1b
369 );
370 define_byte_sliced_test!(
371 tests_3d_2x256x1,
372 ByteSliced2x256x1b,
373 BinaryField1b,
374 PackedBinaryField256x1b
375 );
376 define_byte_sliced_test!(
377 tests_3d_1x256x1,
378 ByteSliced1x256x1b,
379 BinaryField1b,
380 PackedBinaryField256x1b
381 );
382
383 define_byte_sliced_test!(
385 tests_3d_64x128,
386 ByteSlicedAES64x128b,
387 AESTowerField128b,
388 PackedAESBinaryField4x128b
389 );
390 define_byte_sliced_test!(
391 tests_3d_64x64,
392 ByteSlicedAES64x64b,
393 AESTowerField64b,
394 PackedAESBinaryField8x64b
395 );
396 define_byte_sliced_test!(
397 tests_3d_2x64x64,
398 ByteSlicedAES2x64x64b,
399 AESTowerField64b,
400 PackedAESBinaryField8x64b
401 );
402 define_byte_sliced_test!(
403 tests_3d_64x32,
404 ByteSlicedAES64x32b,
405 AESTowerField32b,
406 PackedAESBinaryField16x32b
407 );
408 define_byte_sliced_test!(
409 tests_3d_4x64x32,
410 ByteSlicedAES4x64x32b,
411 AESTowerField32b,
412 PackedAESBinaryField16x32b
413 );
414 define_byte_sliced_test!(
415 tests_3d_64x16,
416 ByteSlicedAES64x16b,
417 AESTowerField16b,
418 PackedAESBinaryField32x16b
419 );
420 define_byte_sliced_test!(
421 tests_3d_8x64x16,
422 ByteSlicedAES8x64x16b,
423 AESTowerField16b,
424 PackedAESBinaryField32x16b
425 );
426 define_byte_sliced_test!(
427 tests_3d_64x8,
428 ByteSlicedAES64x8b,
429 AESTowerField8b,
430 PackedAESBinaryField64x8b
431 );
432 define_byte_sliced_test!(
433 tests_3d_16x64x8,
434 ByteSlicedAES16x64x8b,
435 AESTowerField8b,
436 PackedAESBinaryField64x8b
437 );
438
439 define_byte_sliced_test!(
440 tests_3d_16x512x1,
441 ByteSliced16x512x1b,
442 BinaryField1b,
443 PackedBinaryField512x1b
444 );
445 define_byte_sliced_test!(
446 tests_3d_8x512x1,
447 ByteSliced8x512x1b,
448 BinaryField1b,
449 PackedBinaryField512x1b
450 );
451 define_byte_sliced_test!(
452 tests_3d_4x512x1,
453 ByteSliced4x512x1b,
454 BinaryField1b,
455 PackedBinaryField512x1b
456 );
457 define_byte_sliced_test!(
458 tests_3d_2x512x1,
459 ByteSliced2x512x1b,
460 BinaryField1b,
461 PackedBinaryField512x1b
462 );
463 define_byte_sliced_test!(
464 tests_3d_1x512x1,
465 ByteSliced1x512x1b,
466 BinaryField1b,
467 PackedBinaryField512x1b
468 );
469}