1use std::{
4 any::TypeId,
5 fmt::{Debug, Display, Formatter},
6 iter::{Product, Sum},
7 marker::PhantomData,
8 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
9};
10
11use binius_utils::{
12 bytes::{Buf, BufMut},
13 DeserializeBytes, SerializationError, SerializationMode, SerializeBytes,
14};
15use bytemuck::{Pod, Zeroable};
16use rand::RngCore;
17use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
18
19use super::{
20 arithmetic_traits::InvertOrZero,
21 binary_field::{binary_field, impl_field_extension, BinaryField, BinaryField1b},
22 binary_field_arithmetic::TowerFieldArithmetic,
23 mul_by_binary_field_1b, BinaryField8b, Error, PackedExtension, PackedSubfield,
24};
25use crate::{
26 as_packed_field::AsPackedField,
27 binary_field_arithmetic::{impl_arithmetic_using_packed, impl_mul_primitive},
28 binary_tower,
29 linear_transformation::{
30 FieldLinearTransformation, PackedTransformationFactory, Transformation,
31 },
32 packed::PackedField,
33 underlier::U1,
34 BinaryField128b, BinaryField16b, BinaryField32b, BinaryField64b, ExtensionField, Field,
35 TowerField,
36};
37
38binary_field!(pub AESTowerField8b(u8), 0xD0);
45binary_field!(pub AESTowerField16b(u16), 0x4745);
46binary_field!(pub AESTowerField32b(u32), 0xBD478FAB);
47binary_field!(pub AESTowerField64b(u64), 0x0DE1555D2BD78EB4);
48binary_field!(pub AESTowerField128b(u128), 0x6DB54066349EDB96C33A87244A742678);
49
50unsafe impl Pod for AESTowerField8b {}
51unsafe impl Pod for AESTowerField16b {}
52unsafe impl Pod for AESTowerField32b {}
53unsafe impl Pod for AESTowerField64b {}
54unsafe impl Pod for AESTowerField128b {}
55
56binary_tower!(
57 AESTowerField8b(u8, BinaryField8b)
58 < AESTowerField16b(u16, BinaryField16b)
59 < AESTowerField32b(u32, BinaryField32b)
60 < AESTowerField64b(u64, BinaryField64b)
61 < AESTowerField128b(u128, BinaryField128b)
62);
63
64impl_field_extension!(BinaryField1b(U1) < @3 => AESTowerField8b(u8));
65impl_field_extension!(BinaryField1b(U1) < @4 => AESTowerField16b(u16));
66impl_field_extension!(BinaryField1b(U1) < @5 => AESTowerField32b(u32));
67impl_field_extension!(BinaryField1b(U1) < @6 => AESTowerField64b(u64));
68impl_field_extension!(BinaryField1b(U1) < @7 => AESTowerField128b(u128));
69
70mul_by_binary_field_1b!(AESTowerField8b);
71mul_by_binary_field_1b!(AESTowerField16b);
72mul_by_binary_field_1b!(AESTowerField32b);
73mul_by_binary_field_1b!(AESTowerField64b);
74mul_by_binary_field_1b!(AESTowerField128b);
75
76impl_arithmetic_using_packed!(AESTowerField8b);
77impl_arithmetic_using_packed!(AESTowerField16b);
78impl_arithmetic_using_packed!(AESTowerField32b);
79impl_arithmetic_using_packed!(AESTowerField64b);
80impl_arithmetic_using_packed!(AESTowerField128b);
81
82impl TowerField for AESTowerField8b {
83 type Canonical = BinaryField8b;
84
85 fn min_tower_level(self) -> usize {
86 match self {
87 Self::ZERO | Self::ONE => 0,
88 _ => 3,
89 }
90 }
91
92 fn mul_primitive(self, iota: usize) -> Result<Self, Error> {
93 match iota {
94 0..=1 => Ok(self * ISOMORPHIC_ALPHAS[iota]),
95 2 => Ok(self.multiply_alpha()),
96 _ => Err(Error::ExtensionDegreeMismatch),
97 }
98 }
99}
100
101#[inline(always)]
103pub fn is_aes_tower<F: TowerField>() -> bool {
104 TypeId::of::<F>() == TypeId::of::<F>()
105 || TypeId::of::<F>() == TypeId::of::<AESTowerField16b>()
106 || TypeId::of::<F>() == TypeId::of::<AESTowerField32b>()
107 || TypeId::of::<F>() == TypeId::of::<AESTowerField64b>()
108 || TypeId::of::<F>() == TypeId::of::<AESTowerField128b>()
109}
110
111pub const AES_TO_BINARY_LINEAR_TRANSFORMATION: FieldLinearTransformation<BinaryField8b> =
112 FieldLinearTransformation::new_const(&[
113 BinaryField8b(0x01),
114 BinaryField8b(0x3c),
115 BinaryField8b(0x8c),
116 BinaryField8b(0x8a),
117 BinaryField8b(0x59),
118 BinaryField8b(0x7a),
119 BinaryField8b(0x53),
120 BinaryField8b(0x27),
121 ]);
122
123impl From<AESTowerField8b> for BinaryField8b {
124 fn from(value: AESTowerField8b) -> Self {
125 AES_TO_BINARY_LINEAR_TRANSFORMATION.transform(&value)
126 }
127}
128
129pub const BINARY_TO_AES_LINEAR_TRANSFORMATION: FieldLinearTransformation<AESTowerField8b> =
130 FieldLinearTransformation::new_const(&[
131 AESTowerField8b(0x01),
132 AESTowerField8b(0xbc),
133 AESTowerField8b(0xb0),
134 AESTowerField8b(0xec),
135 AESTowerField8b(0xd3),
136 AESTowerField8b(0x8d),
137 AESTowerField8b(0x2e),
138 AESTowerField8b(0x58),
139 ]);
140
141impl From<BinaryField8b> for AESTowerField8b {
142 fn from(value: BinaryField8b) -> Self {
143 BINARY_TO_AES_LINEAR_TRANSFORMATION.transform(&value)
144 }
145}
146
147pub struct SubfieldTransformer<IF, OF, T> {
152 inner_transform: T,
153 _ip_pd: PhantomData<IF>,
154 _op_pd: PhantomData<OF>,
155}
156
157impl<IF, OF, T> SubfieldTransformer<IF, OF, T> {
158 const fn new(inner_transform: T) -> Self {
159 Self {
160 inner_transform,
161 _ip_pd: PhantomData,
162 _op_pd: PhantomData,
163 }
164 }
165}
166
167impl<IF, OF, IEP, OEP, T> Transformation<IEP, OEP> for SubfieldTransformer<IF, OF, T>
168where
169 IF: Field,
170 OF: Field,
171 IEP: PackedExtension<IF>,
172 OEP: PackedExtension<OF>,
173 T: Transformation<PackedSubfield<IEP, IF>, PackedSubfield<OEP, OF>>,
174{
175 fn transform(&self, input: &IEP) -> OEP {
176 OEP::cast_ext(self.inner_transform.transform(IEP::cast_base_ref(input)))
177 }
178}
179
180pub type AesToBinaryTransformation<IP, OP> = SubfieldTransformer<
181 AESTowerField8b,
182 BinaryField8b,
183 <PackedSubfield<IP, AESTowerField8b> as PackedTransformationFactory<
184 PackedSubfield<OP, BinaryField8b>,
185 >>::PackedTransformation<&'static [BinaryField8b]>,
186>;
187pub type BinaryToAesTransformation<IP, OP> = SubfieldTransformer<
188 BinaryField8b,
189 AESTowerField8b,
190 <PackedSubfield<IP, BinaryField8b> as PackedTransformationFactory<
191 PackedSubfield<OP, AESTowerField8b>,
192 >>::PackedTransformation<&'static [AESTowerField8b]>,
193>;
194
195pub fn make_aes_to_binary_packed_transformer<IP, OP>() -> AesToBinaryTransformation<IP, OP>
198where
199 IP: PackedExtension<AESTowerField8b>,
200 OP: PackedExtension<BinaryField8b>,
201 PackedSubfield<IP, AESTowerField8b>:
202 PackedTransformationFactory<PackedSubfield<OP, BinaryField8b>>,
203{
204 SubfieldTransformer::<AESTowerField8b, BinaryField8b, _>::new(PackedSubfield::<
205 IP,
206 AESTowerField8b,
207 >::make_packed_transformation(
208 AES_TO_BINARY_LINEAR_TRANSFORMATION,
209 ))
210}
211
212pub fn make_binary_to_aes_packed_transformer<IP, OP>() -> BinaryToAesTransformation<IP, OP>
215where
216 IP: PackedExtension<BinaryField8b>,
217 OP: PackedExtension<AESTowerField8b>,
218 PackedSubfield<IP, BinaryField8b>:
219 PackedTransformationFactory<PackedSubfield<OP, AESTowerField8b>>,
220{
221 SubfieldTransformer::<BinaryField8b, AESTowerField8b, _>::new(
222 PackedSubfield::<IP, BinaryField8b>::make_packed_transformation(
223 BINARY_TO_AES_LINEAR_TRANSFORMATION,
224 ),
225 )
226}
227
228const ISOMORPHIC_ALPHAS: [AESTowerField8b; 3] = [
230 AESTowerField8b(0xBC),
231 AESTowerField8b(0xB0),
232 AESTowerField8b(0xD3),
233];
234
235impl_mul_primitive!(AESTowerField16b,
237 mul_by 0 => ISOMORPHIC_ALPHAS[0],
238 mul_by 1 => ISOMORPHIC_ALPHAS[1],
239 repack 2 => AESTowerField8b,
240 repack 3 => AESTowerField16b,
241);
242impl_mul_primitive!(AESTowerField32b,
243 mul_by 0 => ISOMORPHIC_ALPHAS[0],
244 mul_by 1 => ISOMORPHIC_ALPHAS[1],
245 repack 2 => AESTowerField8b,
246 repack 3 => AESTowerField16b,
247 repack 4 => AESTowerField32b,
248);
249impl_mul_primitive!(AESTowerField64b,
250 mul_by 0 => ISOMORPHIC_ALPHAS[0],
251 mul_by 1 => ISOMORPHIC_ALPHAS[1],
252 repack 2 => AESTowerField8b,
253 repack 3 => AESTowerField16b,
254 repack 4 => AESTowerField32b,
255 repack 5 => AESTowerField64b,
256);
257impl_mul_primitive!(AESTowerField128b,
258 mul_by 0 => ISOMORPHIC_ALPHAS[0],
259 mul_by 1 => ISOMORPHIC_ALPHAS[1],
260 repack 2 => AESTowerField8b,
261 repack 3 => AESTowerField16b,
262 repack 4 => AESTowerField32b,
263 repack 5 => AESTowerField64b,
264 repack 6 => AESTowerField128b,
265);
266
267fn convert_as_packed_8b<F1, F2, Scalar1, Scalar2>(val: F1) -> F2
270where
271 Scalar1: Field,
272 Scalar2: Field + From<Scalar1>,
273 F1: AsPackedField<Scalar1>,
274 F2: AsPackedField<Scalar2>,
275{
276 assert_eq!(F1::Packed::WIDTH, F2::Packed::WIDTH);
277
278 let val_repacked = val.to_packed();
279 let converted_repacked = F2::Packed::from_fn(|i| val_repacked.get(i).into());
280
281 F2::from_packed(converted_repacked)
282}
283
284macro_rules! impl_tower_field_conversion {
285 ($aes_field:ty, $binary_field:ty) => {
286 impl From<$aes_field> for $binary_field {
287 fn from(value: $aes_field) -> Self {
288 convert_as_packed_8b::<_, _, AESTowerField8b, BinaryField8b>(value)
289 }
290 }
291
292 impl From<$binary_field> for $aes_field {
293 fn from(value: $binary_field) -> Self {
294 convert_as_packed_8b::<_, _, BinaryField8b, AESTowerField8b>(value)
295 }
296 }
297 };
298}
299
300impl_tower_field_conversion!(AESTowerField16b, BinaryField16b);
301impl_tower_field_conversion!(AESTowerField32b, BinaryField32b);
302impl_tower_field_conversion!(AESTowerField64b, BinaryField64b);
303impl_tower_field_conversion!(AESTowerField128b, BinaryField128b);
304
305macro_rules! serialize_deserialize_non_canonical {
306 ($field:ident, canonical=$canonical:ident) => {
307 impl SerializeBytes for $field {
308 fn serialize(
309 &self,
310 write_buf: impl BufMut,
311 mode: SerializationMode,
312 ) -> Result<(), SerializationError> {
313 match mode {
314 SerializationMode::Native => self.0.serialize(write_buf, mode),
315 SerializationMode::CanonicalTower => {
316 $canonical::from(*self).serialize(write_buf, mode)
317 }
318 }
319 }
320 }
321
322 impl DeserializeBytes for $field {
323 fn deserialize(
324 read_buf: impl Buf,
325 mode: SerializationMode,
326 ) -> Result<Self, SerializationError>
327 where
328 Self: Sized,
329 {
330 match mode {
331 SerializationMode::Native => {
332 Ok(Self(DeserializeBytes::deserialize(read_buf, mode)?))
333 }
334 SerializationMode::CanonicalTower => {
335 Ok(Self::from($canonical::deserialize(read_buf, mode)?))
336 }
337 }
338 }
339 }
340 };
341}
342
343serialize_deserialize_non_canonical!(AESTowerField8b, canonical = BinaryField8b);
344serialize_deserialize_non_canonical!(AESTowerField16b, canonical = BinaryField16b);
345serialize_deserialize_non_canonical!(AESTowerField32b, canonical = BinaryField32b);
346serialize_deserialize_non_canonical!(AESTowerField64b, canonical = BinaryField64b);
347serialize_deserialize_non_canonical!(AESTowerField128b, canonical = BinaryField128b);
348
349#[cfg(test)]
350mod tests {
351 use binius_utils::{bytes::BytesMut, SerializationMode, SerializeBytes};
352 use proptest::{arbitrary::any, proptest};
353 use rand::thread_rng;
354
355 use super::*;
356 use crate::{
357 binary_field::tests::is_binary_field_valid_generator, underlier::WithUnderlier,
358 PackedAESBinaryField16x32b, PackedAESBinaryField4x32b, PackedAESBinaryField8x32b,
359 PackedBinaryField16x32b, PackedBinaryField4x32b, PackedBinaryField8x32b,
360 };
361
362 fn check_square(f: impl Field) {
363 assert_eq!(f.square(), f * f);
364 }
365
366 proptest! {
367 #[test]
368 fn test_square_8(a in any::<u8>()) {
369 check_square(AESTowerField8b::from(a))
370 }
371
372 #[test]
373 fn test_square_16(a in any::<u16>()) {
374 check_square(AESTowerField16b::from(a))
375 }
376
377 #[test]
378 fn test_square_32(a in any::<u32>()) {
379 check_square(AESTowerField32b::from(a))
380 }
381
382 #[test]
383 fn test_square_64(a in any::<u64>()) {
384 check_square(AESTowerField64b::from(a))
385 }
386
387 #[test]
388 fn test_square_128(a in any::<u128>()) {
389 check_square(AESTowerField128b::from(a))
390 }
391 }
392
393 fn check_invert(f: impl Field) {
394 let inversed = f.invert();
395 if f.is_zero() {
396 assert!(inversed.is_none());
397 } else {
398 assert_eq!(inversed.unwrap() * f, Field::ONE);
399 }
400 }
401
402 fn check_isomorphism_preserves_ops<F1: Field, F2: Field + From<F1>>(a: F1, b: F1) {
403 assert_eq!(F2::from(a * b), F2::from(a) * F2::from(b));
404 assert_eq!(F2::from(a + b), F2::from(a) + F2::from(b));
405 }
406
407 proptest! {
408 #[test]
409 fn test_invert_8(a in any::<u8>()) {
410 check_invert(AESTowerField8b::from(a))
411 }
412
413 #[test]
414 fn test_invert_16(a in any::<u16>()) {
415 check_invert(AESTowerField16b::from(a))
416 }
417
418 #[test]
419 fn test_invert_32(a in any::<u32>()) {
420 check_invert(AESTowerField32b::from(a))
421 }
422
423 #[test]
424 fn test_invert_64(a in any::<u64>()) {
425 check_invert(AESTowerField64b::from(a))
426 }
427
428 #[test]
429 fn test_invert_128(a in any::<u128>()) {
430 check_invert(AESTowerField128b::from(a))
431 }
432
433 #[test]
434 fn test_isomorphism_to_binary_tower8b_roundtrip(a in any::<u8>()) {
435 let a_val = AESTowerField8b(a);
436 let projected = BinaryField8b::from(a_val);
437 let restored = AESTowerField8b::from(projected);
438 assert_eq!(a_val, restored);
439 }
440
441 #[test]
442 fn test_isomorphism_8b(a in any::<u8>(), b in any::<u8>()) {
443 check_isomorphism_preserves_ops::<AESTowerField8b, BinaryField8b>(a.into(), b.into());
444 check_isomorphism_preserves_ops::<BinaryField8b, AESTowerField8b>(a.into(), b.into());
445 }
446
447 #[test]
448 fn test_isomorphism_16b(a in any::<u16>(), b in any::<u16>()) {
449 check_isomorphism_preserves_ops::<AESTowerField16b, BinaryField16b>(a.into(), b.into());
450 check_isomorphism_preserves_ops::<BinaryField16b, AESTowerField16b>(a.into(), b.into());
451 }
452
453 #[test]
454 fn test_isomorphism_32b(a in any::<u32>(), b in any::<u32>()) {
455 check_isomorphism_preserves_ops::<AESTowerField32b, BinaryField32b>(a.into(), b.into());
456 check_isomorphism_preserves_ops::<BinaryField32b, AESTowerField32b>(a.into(), b.into());
457 }
458
459 #[test]
460 fn test_isomorphism_64b(a in any::<u64>(), b in any::<u64>()) {
461 check_isomorphism_preserves_ops::<AESTowerField64b, BinaryField64b>(a.into(), b.into());
462 check_isomorphism_preserves_ops::<BinaryField64b, AESTowerField64b>(a.into(), b.into());
463 }
464
465 #[test]
466 fn test_isomorphism_128b(a in any::<u128>(), b in any::<u128>()) {
467 check_isomorphism_preserves_ops::<AESTowerField128b, BinaryField128b>(a.into(), b.into());
468 check_isomorphism_preserves_ops::<BinaryField128b, AESTowerField128b>(a.into(), b.into());
469 }
470 }
471
472 fn check_mul_by_one<F: Field>(f: F) {
473 assert_eq!(F::ONE * f, f);
474 assert_eq!(f * F::ONE, f);
475 }
476
477 fn check_commutative<F: Field>(f_1: F, f_2: F) {
478 assert_eq!(f_1 * f_2, f_2 * f_1);
479 }
480
481 fn check_associativity_and_lineraity<F: Field>(f_1: F, f_2: F, f_3: F) {
482 assert_eq!(f_1 * (f_2 * f_3), (f_1 * f_2) * f_3);
483 assert_eq!(f_1 * (f_2 + f_3), f_1 * f_2 + f_1 * f_3);
484 }
485
486 fn check_mul<F: Field>(f_1: F, f_2: F, f_3: F) {
487 check_mul_by_one(f_1);
488 check_mul_by_one(f_2);
489 check_mul_by_one(f_3);
490
491 check_commutative(f_1, f_2);
492 check_commutative(f_1, f_3);
493 check_commutative(f_2, f_3);
494
495 check_associativity_and_lineraity(f_1, f_2, f_3);
496 check_associativity_and_lineraity(f_1, f_3, f_2);
497 check_associativity_and_lineraity(f_2, f_1, f_3);
498 check_associativity_and_lineraity(f_2, f_3, f_1);
499 check_associativity_and_lineraity(f_3, f_1, f_2);
500 check_associativity_and_lineraity(f_3, f_2, f_1);
501 }
502
503 proptest! {
504 #[test]
505 fn test_mul_8(a in any::<u8>(), b in any::<u8>(), c in any::<u8>()) {
506 check_mul(AESTowerField8b::from(a), AESTowerField8b::from(b), AESTowerField8b::from(c))
507 }
508
509 #[test]
510 fn test_mul_16(a in any::<u16>(), b in any::<u16>(), c in any::<u16>()) {
511 check_mul(AESTowerField16b::from(a), AESTowerField16b::from(b), AESTowerField16b::from(c))
512 }
513
514 #[test]
515 fn test_mul_32(a in any::<u32>(), b in any::<u32>(), c in any::<u32>()) {
516 check_mul(AESTowerField32b::from(a), AESTowerField32b::from(b), AESTowerField32b::from(c))
517 }
518
519 #[test]
520 fn test_mul_64(a in any::<u64>(), b in any::<u64>(), c in any::<u64>()) {
521 check_mul(AESTowerField64b::from(a), AESTowerField64b::from(b), AESTowerField64b::from(c))
522 }
523
524 #[test]
525 fn test_mul_128(a in any::<u128>(), b in any::<u128>(), c in any::<u128>()) {
526 check_mul(AESTowerField128b::from(a), AESTowerField128b::from(b), AESTowerField128b::from(c))
527 }
528
529 #[test]
530 fn test_conversion_roundtrip(a in any::<u8>()) {
531 let a_val = AESTowerField8b(a);
532 let converted = BinaryField8b::from(a_val);
533 assert_eq!(a_val, AESTowerField8b::from(converted));
534 }
535 }
536
537 #[test]
538 fn test_multiplicative_generators() {
539 assert!(is_binary_field_valid_generator::<AESTowerField8b>());
540 assert!(is_binary_field_valid_generator::<AESTowerField16b>());
541 assert!(is_binary_field_valid_generator::<AESTowerField32b>());
542 assert!(is_binary_field_valid_generator::<AESTowerField64b>());
543 assert!(is_binary_field_valid_generator::<AESTowerField128b>());
544 }
545
546 fn test_mul_primitive<F: TowerField + WithUnderlier<Underlier: From<u8>>>(val: F, iota: usize) {
547 let result = val.mul_primitive(iota);
548 let expected = match iota {
549 0..=2 => {
550 Ok(val
551 * F::from_underlier(F::Underlier::from(ISOMORPHIC_ALPHAS[iota].to_underlier())))
552 }
553 _ => <F as ExtensionField<BinaryField1b>>::basis(1 << iota).map(|b| val * b),
554 };
555 assert_eq!(result.is_ok(), expected.is_ok());
556 if result.is_ok() {
557 assert_eq!(result.unwrap(), expected.unwrap());
558 } else {
559 assert!(matches!(result.unwrap_err(), Error::ExtensionDegreeMismatch));
560 }
561 }
562
563 proptest! {
564 #[test]
565 fn test_mul_primitive_8b(val in 0u8.., iota in 3usize..8) {
566 test_mul_primitive::<AESTowerField8b>(val.into(), iota)
567 }
568
569 #[test]
570 fn test_mul_primitive_16b(val in 0u16.., iota in 3usize..8) {
571 test_mul_primitive::<AESTowerField16b>(val.into(), iota)
572 }
573
574 #[test]
575 fn test_mul_primitive_32b(val in 0u32.., iota in 3usize..8) {
576 test_mul_primitive::<AESTowerField32b>(val.into(), iota)
577 }
578
579 #[test]
580 fn test_mul_primitive_64b(val in 0u64.., iota in 3usize..8) {
581 test_mul_primitive::<AESTowerField64b>(val.into(), iota)
582 }
583
584 #[test]
585 fn test_mul_primitive_128b(val in 0u128.., iota in 3usize..8) {
586 test_mul_primitive::<AESTowerField128b>(val.into(), iota)
587 }
588 }
589
590 fn convert_pairwise<IP, OP>(val: IP) -> OP
591 where
592 IP: PackedField + WithUnderlier,
593 OP: PackedField<Scalar: From<IP::Scalar>> + WithUnderlier<Underlier = IP::Underlier>,
594 {
595 OP::from_fn(|i| val.get(i).into())
596 }
597
598 proptest! {
599 #[test]
600 fn test_aes_to_binary_packed_transform_128(val in 0u128..) {
601 let transform = make_aes_to_binary_packed_transformer::<PackedAESBinaryField4x32b, PackedBinaryField4x32b>();
602 let input = PackedAESBinaryField4x32b::from(val);
603 let result: PackedBinaryField4x32b = transform.transform(&input);
604 assert_eq!(result, convert_pairwise(input));
605 }
606
607 #[test]
608 fn test_binary_to_aes_packed_transform_128(val in 0u128..) {
609 let transform = make_binary_to_aes_packed_transformer::<PackedBinaryField4x32b, PackedAESBinaryField4x32b>();
610 let input = PackedBinaryField4x32b::from(val);
611 let result: PackedAESBinaryField4x32b = transform.transform(&input);
612 assert_eq!(result, convert_pairwise(input));
613 }
614
615 #[test]
616 fn test_aes_to_binary_packed_transform_256(val in any::<[u128; 2]>()) {
617 let transform = make_aes_to_binary_packed_transformer::<PackedAESBinaryField8x32b, PackedBinaryField8x32b>();
618 let input = PackedAESBinaryField8x32b::from(val);
619 let result: PackedBinaryField8x32b = transform.transform(&input);
620 assert_eq!(result, convert_pairwise(input));
621 }
622
623 #[test]
624 fn test_binary_to_aes_packed_transform_256(val in any::<[u128; 2]>()) {
625 let transform = make_binary_to_aes_packed_transformer::<PackedBinaryField8x32b, PackedAESBinaryField8x32b>();
626 let input = PackedBinaryField8x32b::from(val);
627 let result: PackedAESBinaryField8x32b = transform.transform(&input);
628 assert_eq!(result, convert_pairwise(input));
629 }
630
631 #[test]
632 fn test_aes_to_binary_packed_transform_512(val in any::<[u128; 4]>()) {
633 let transform = make_aes_to_binary_packed_transformer::<PackedAESBinaryField16x32b, PackedBinaryField16x32b>();
634 let input = PackedAESBinaryField16x32b::from_underlier(val.into());
635 let result: PackedBinaryField16x32b = transform.transform(&input);
636 assert_eq!(result, convert_pairwise(input));
637 }
638
639 #[test]
640 fn test_binary_to_aes_packed_transform_512(val in any::<[u128; 4]>()) {
641 let transform = make_binary_to_aes_packed_transformer::<PackedBinaryField16x32b, PackedAESBinaryField16x32b>();
642 let input = PackedBinaryField16x32b::from_underlier(val.into());
643 let result: PackedAESBinaryField16x32b = transform.transform(&input);
644 assert_eq!(result, convert_pairwise(input));
645 }
646 }
647
648 #[test]
649 fn test_canonical_serialization() {
650 let mut buffer = BytesMut::new();
651 let mut rng = thread_rng();
652 let aes8 = <AESTowerField8b as Field>::random(&mut rng);
653 let aes16 = <AESTowerField16b as Field>::random(&mut rng);
654 let aes32 = <AESTowerField32b as Field>::random(&mut rng);
655 let aes64 = <AESTowerField64b as Field>::random(&mut rng);
656 let aes128 = <AESTowerField128b as Field>::random(&mut rng);
657
658 let mode = SerializationMode::CanonicalTower;
659
660 SerializeBytes::serialize(&aes8, &mut buffer, mode).unwrap();
661 SerializeBytes::serialize(&aes16, &mut buffer, mode).unwrap();
662 SerializeBytes::serialize(&aes32, &mut buffer, mode).unwrap();
663 SerializeBytes::serialize(&aes64, &mut buffer, mode).unwrap();
664 SerializeBytes::serialize(&aes128, &mut buffer, mode).unwrap();
665
666 SerializeBytes::serialize(&aes128, &mut buffer, mode).unwrap();
667
668 let mut read_buffer = buffer.freeze();
669
670 assert_eq!(AESTowerField8b::deserialize(&mut read_buffer, mode).unwrap(), aes8);
671 assert_eq!(AESTowerField16b::deserialize(&mut read_buffer, mode).unwrap(), aes16);
672 assert_eq!(AESTowerField32b::deserialize(&mut read_buffer, mode).unwrap(), aes32);
673 assert_eq!(AESTowerField64b::deserialize(&mut read_buffer, mode).unwrap(), aes64);
674 assert_eq!(AESTowerField128b::deserialize(&mut read_buffer, mode).unwrap(), aes128);
675
676 assert_eq!(BinaryField128b::deserialize(&mut read_buffer, mode).unwrap(), aes128.into())
677 }
678}