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