1use std::{
5 fmt::{Debug, Display, Formatter},
6 iter::{Product, Sum},
7 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
8};
9
10use bytemuck::Zeroable;
11
12use super::{Underlier, UnderlierView, extension::ExtensionField};
13use crate::{Field, underlier::U1};
14
15pub trait BinaryField: ExtensionField<BinaryField1b> + UnderlierView<Underlier: Underlier> {
17 const N_BITS: usize = Self::ORDER_EXPONENT;
18
19 const TRACE_ONE_ELEMENT: Self;
33}
34
35macro_rules! binary_field {
43 ($vis:vis $name:ident($typ:ty), $gen:expr, $trace_one:expr) => {
45 binary_field!(@base $vis $name($typ), $gen, $trace_one);
46 binary_field!(@arithmetic_via_packed $name, $typ);
47 };
48 (custom_arithmetic $vis:vis $name:ident($typ:ty), $gen:expr, $trace_one:expr) => {
50 binary_field!(@base $vis $name($typ), $gen, $trace_one);
51 };
52
53 (@base $vis:vis $name:ident($typ:ty), $gen:expr, $trace_one:expr) => {
54 #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Zeroable, bytemuck::TransparentWrapper)]
55 #[repr(transparent)]
56 $vis struct $name(pub(crate) $typ);
57
58 impl $name {
62 pub const fn val(self) -> $typ {
63 self.0
64 }
65 }
66
67 unsafe impl $crate::underlier::UnderlierView for $name {
68 type Underlier = $typ;
69 }
70
71 impl binius_utils::SerializeBytes for $name {
73 fn serialize(&self, write_buf: impl binius_utils::bytes::BufMut) -> Result<(), binius_utils::SerializationError> {
74 self.0.serialize(write_buf)
75 }
76 }
77
78 impl binius_utils::DeserializeBytes for $name {
79 fn deserialize(read_buf: impl binius_utils::bytes::Buf) -> Result<Self, binius_utils::SerializationError> {
80 Ok(Self(binius_utils::DeserializeBytes::deserialize(read_buf)?))
81 }
82 }
83
84 impl binius_utils::FixedSizeSerializeBytes for $name {
85 const BYTE_SIZE: usize = <$typ as binius_utils::FixedSizeSerializeBytes>::BYTE_SIZE;
86 }
87
88 impl Neg for $name {
89 type Output = Self;
90
91 fn neg(self) -> Self::Output {
92 self
93 }
94 }
95
96 impl Add<Self> for $name {
97 type Output = Self;
98
99 #[allow(clippy::suspicious_arithmetic_impl)]
100 fn add(self, rhs: Self) -> Self::Output {
101 $name(self.0 ^ rhs.0)
102 }
103 }
104
105 impl Add<&Self> for $name {
106 type Output = Self;
107
108 #[allow(clippy::suspicious_arithmetic_impl)]
109 fn add(self, rhs: &Self) -> Self::Output {
110 $name(self.0 ^ rhs.0)
111 }
112 }
113
114 impl Sub<Self> for $name {
115 type Output = Self;
116
117 #[allow(clippy::suspicious_arithmetic_impl)]
118 fn sub(self, rhs: Self) -> Self::Output {
119 $name(self.0 ^ rhs.0)
120 }
121 }
122
123 impl Sub<&Self> for $name {
124 type Output = Self;
125
126 #[allow(clippy::suspicious_arithmetic_impl)]
127 fn sub(self, rhs: &Self) -> Self::Output {
128 $name(self.0 ^ rhs.0)
129 }
130 }
131
132 impl Mul<&Self> for $name {
133 type Output = Self;
134
135 fn mul(self, rhs: &Self) -> Self::Output {
136 self * *rhs
137 }
138 }
139
140 impl AddAssign<Self> for $name {
141 fn add_assign(&mut self, rhs: Self) {
142 *self = *self + rhs;
143 }
144 }
145
146 impl AddAssign<&Self> for $name {
147 fn add_assign(&mut self, rhs: &Self) {
148 *self = *self + *rhs;
149 }
150 }
151
152 impl SubAssign<Self> for $name {
153 fn sub_assign(&mut self, rhs: Self) {
154 *self = *self - rhs;
155 }
156 }
157
158 impl SubAssign<&Self> for $name {
159 fn sub_assign(&mut self, rhs: &Self) {
160 *self = *self - *rhs;
161 }
162 }
163
164 impl MulAssign<Self> for $name {
165 fn mul_assign(&mut self, rhs: Self) {
166 *self = *self * rhs;
167 }
168 }
169
170 impl MulAssign<&Self> for $name {
171 fn mul_assign(&mut self, rhs: &Self) {
172 *self = *self * rhs;
173 }
174 }
175
176 impl Sum<Self> for $name {
177 fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
178 iter.fold(Self::ZERO, |acc, x| acc + x)
179 }
180 }
181
182 impl<'a> Sum<&'a Self> for $name {
183 fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
184 iter.fold(Self::ZERO, |acc, x| acc + x)
185 }
186 }
187
188 impl Product<Self> for $name {
189 fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
190 iter.fold(Self::ONE, |acc, x| acc * x)
191 }
192 }
193
194 impl<'a> Product<&'a Self> for $name {
195 fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
196 iter.fold(Self::ONE, |acc, x| acc * x)
197 }
198 }
199
200
201 impl Field for $name {
202 const ZERO: Self = $name(<$typ as $crate::underlier::Underlier>::ZERO);
203 const ONE: Self = $name(<$typ as $crate::underlier::Underlier>::ONE);
204 const CHARACTERISTIC: usize = 2;
205 const ORDER_EXPONENT: usize = <$typ as $crate::underlier::Underlier>::BITS;
206 const MULTIPLICATIVE_GENERATOR: $name = $name($gen);
207
208 fn double(&self) -> Self {
209 Self::ZERO
210 }
211 }
212
213 impl $crate::Divisible<$name> for $name {
216 const LOG_N: usize = 0;
217
218 #[inline]
219 fn value_iter(value: Self) -> impl ExactSizeIterator<Item = $name> + Send + Clone {
220 std::iter::once(value)
221 }
222
223 #[inline]
224 fn ref_iter(value: &Self) -> impl ExactSizeIterator<Item = $name> + Send + Clone + '_ {
225 std::iter::once(*value)
226 }
227
228 #[inline]
229 fn slice_iter(slice: &[Self]) -> impl ExactSizeIterator<Item = $name> + Send + Clone + '_ {
230 slice.iter().copied()
231 }
232
233 #[inline]
234 unsafe fn get_unchecked(&self, _index: usize) -> $name {
235 *self
236 }
237
238 #[inline]
239 unsafe fn set_unchecked(&mut self, _index: usize, val: $name) {
240 *self = val;
241 }
242
243 #[inline]
244 fn broadcast(val: $name) -> Self {
245 val
246 }
247
248 #[inline]
249 fn from_iter(mut iter: impl Iterator<Item = $name>) -> Self {
250 iter.next().unwrap_or(Self::ZERO)
251 }
252 }
253
254 impl $crate::Maskable<$name> for $name {
258 type Mask = $typ;
259
260 #[inline]
261 fn make_mask(mut selectors: impl Iterator<Item = bool>) -> $typ {
262 <$typ as $crate::Divisible<_>>::broadcast(
263 $crate::underlier::U1::from(selectors.next().unwrap_or(false)),
264 )
265 }
266
267 #[inline]
268 fn select(&self, mask: &$typ) -> Self {
269 Self(self.0 & *mask)
270 }
271 }
272
273 impl $crate::PackedField for $name {
274 #[inline]
275 fn iter(&self) -> impl Iterator<Item = Self::Scalar> + Send + Clone + '_ {
276 std::iter::once(*self)
277 }
278
279 #[inline]
280 fn into_iter(self) -> impl Iterator<Item = Self::Scalar> + Send + Clone {
281 std::iter::once(self)
282 }
283
284 #[inline]
285 fn iter_slice(slice: &[Self]) -> impl Iterator<Item = Self::Scalar> + Send + Clone + '_ {
286 slice.iter().copied()
287 }
288
289 fn interleave(self, _other: Self, _log_block_len: usize) -> (Self, Self) {
290 panic!("cannot interleave when WIDTH = 1");
291 }
292
293 fn unzip(self, _other: Self, _log_block_len: usize) -> (Self, Self) {
294 panic!("cannot transpose when WIDTH = 1");
295 }
296
297 #[inline]
298 fn from_fn(mut f: impl FnMut(usize) -> Self::Scalar) -> Self {
299 f(0)
300 }
301
302 #[inline]
303 unsafe fn spread_unchecked(self, _log_block_len: usize, _block_idx: usize) -> Self {
304 self
305 }
306 }
307
308 impl ::rand::distr::Distribution<$name> for ::rand::distr::StandardUniform {
309 fn sample<R: ::rand::Rng + ?Sized>(&self, rng: &mut R) -> $name {
310 $name(::rand::distr::StandardUniform.sample(rng))
311 }
312 }
313
314 impl Display for $name {
315 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
316 write!(f, "0x{repr:0>width$x}", repr=self.val(), width=Self::N_BITS.max(4) / 4)
317 }
318 }
319
320 impl Debug for $name {
321 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
322 let structure_name = std::any::type_name::<$name>().split("::").last().expect("exist");
323
324 write!(f, "{}({})",structure_name, self)
325 }
326 }
327
328 impl BinaryField for $name {
329 const TRACE_ONE_ELEMENT: Self = $name($trace_one);
330 }
331
332 impl From<$typ> for $name {
333 fn from(val: $typ) -> Self {
334 return Self(val)
335 }
336 }
337
338 impl From<$name> for $typ {
339 fn from(val: $name) -> Self {
340 return val.0
341 }
342 }
343 };
344
345 (@arithmetic_via_packed $name:ident, $typ:ty) => {
347 impl Mul<Self> for $name {
348 type Output = Self;
349
350 #[inline]
351 fn mul(self, rhs: Self) -> Self {
352 type P = $crate::packed_fields::primitive::PackedPrimitiveType<$typ, $name>;
353 Self((P::from_underlier(self.0) * P::from_underlier(rhs.0)).to_underlier())
354 }
355 }
356
357 impl $crate::arithmetic_traits::Square for $name {
358 #[inline]
359 fn square(self) -> Self {
360 type P = $crate::packed_fields::primitive::PackedPrimitiveType<$typ, $name>;
361 Self(
362 $crate::arithmetic_traits::Square::square(P::from_underlier(self.0)).to_underlier(),
363 )
364 }
365 }
366
367 impl $crate::arithmetic_traits::InvertOrZero for $name {
368 #[inline]
369 fn invert_or_zero(self) -> Self {
370 type P = $crate::packed_fields::primitive::PackedPrimitiveType<$typ, $name>;
371 Self(
372 $crate::arithmetic_traits::InvertOrZero::invert_or_zero(P::from_underlier(self.0))
373 .to_underlier(),
374 )
375 }
376 }
377
378 impl $crate::arithmetic_traits::WideMul for $name {
379 type Output = <$crate::packed_fields::primitive::PackedPrimitiveType<$typ, $name> as $crate::arithmetic_traits::WideMul>::Output;
380
381 #[inline]
382 fn wide_mul(a: Self, b: Self) -> Self::Output {
383 type P = $crate::packed_fields::primitive::PackedPrimitiveType<$typ, $name>;
384 <P as $crate::arithmetic_traits::WideMul>::wide_mul(
385 P::from_underlier(a.0),
386 P::from_underlier(b.0),
387 )
388 }
389
390 #[inline]
391 fn reduce(wide: Self::Output) -> Self {
392 type P = $crate::packed_fields::primitive::PackedPrimitiveType<$typ, $name>;
393 Self(<P as $crate::arithmetic_traits::WideMul>::reduce(wide).to_underlier())
394 }
395 }
396 };
397}
398
399pub(crate) use binary_field;
400
401macro_rules! impl_field_extension {
402 ($subfield_name:ident($subfield_typ:ty) < @$log_degree:expr => $name:ident($typ:ty)) => {
403 impl TryFrom<$name> for $subfield_name {
404 type Error = ();
405
406 #[inline]
407 fn try_from(elem: $name) -> Result<Self, Self::Error> {
408 use $crate::{Divisible, underlier::Underlier};
409
410 let in_subfield = Divisible::<$subfield_typ>::ref_iter(&elem.0)
413 .skip(1)
414 .all(|limb| limb == <$subfield_typ as Underlier>::ZERO);
415 if in_subfield {
416 Ok($subfield_name(Divisible::<$subfield_typ>::get(&elem.0, 0)))
417 } else {
418 Err(())
419 }
420 }
421 }
422
423 impl From<$subfield_name> for $name {
424 #[inline]
425 fn from(elem: $subfield_name) -> Self {
426 $name(<$typ>::from(elem.val()))
427 }
428 }
429
430 impl Add<$subfield_name> for $name {
431 type Output = Self;
432
433 #[inline]
434 fn add(self, rhs: $subfield_name) -> Self::Output {
435 self + Self::from(rhs)
436 }
437 }
438
439 impl Sub<$subfield_name> for $name {
440 type Output = Self;
441
442 #[inline]
443 fn sub(self, rhs: $subfield_name) -> Self::Output {
444 self - Self::from(rhs)
445 }
446 }
447
448 impl Mul<$subfield_name> for $name {
452 type Output = Self;
453
454 #[inline]
455 fn mul(self, rhs: $subfield_name) -> Self::Output {
456 type P =
457 $crate::packed_fields::primitive::PackedPrimitiveType<$typ, $subfield_name>;
458 Self((P::from_underlier(self.0) * P::broadcast(rhs)).to_underlier())
459 }
460 }
461
462 impl AddAssign<$subfield_name> for $name {
463 #[inline]
464 fn add_assign(&mut self, rhs: $subfield_name) {
465 *self = *self + rhs;
466 }
467 }
468
469 impl SubAssign<$subfield_name> for $name {
470 #[inline]
471 fn sub_assign(&mut self, rhs: $subfield_name) {
472 *self = *self - rhs;
473 }
474 }
475
476 impl MulAssign<$subfield_name> for $name {
477 #[inline]
478 fn mul_assign(&mut self, rhs: $subfield_name) {
479 *self = *self * rhs;
480 }
481 }
482
483 impl Add<$name> for $subfield_name {
484 type Output = $name;
485
486 #[inline]
487 fn add(self, rhs: $name) -> Self::Output {
488 rhs + self
489 }
490 }
491
492 impl Sub<$name> for $subfield_name {
493 type Output = $name;
494
495 #[allow(clippy::suspicious_arithmetic_impl)]
496 #[inline]
497 fn sub(self, rhs: $name) -> Self::Output {
498 rhs + self
499 }
500 }
501
502 impl Mul<$name> for $subfield_name {
503 type Output = $name;
504
505 #[inline]
506 fn mul(self, rhs: $name) -> Self::Output {
507 rhs * self
508 }
509 }
510
511 impl ExtensionField<$subfield_name> for $name {
512 const LOG_DEGREE: usize = $log_degree;
513
514 #[inline]
515 fn basis(i: usize) -> Self {
516 use $crate::{Divisible, underlier::Underlier};
517
518 assert!(
519 i < 1 << $log_degree,
520 "index {} out of range for degree {}",
521 i,
522 1 << $log_degree
523 );
524 let mut underlier = <$typ as Underlier>::ZERO;
527 Divisible::<$subfield_typ>::set(
528 &mut underlier,
529 i,
530 <$subfield_typ as Underlier>::ONE,
531 );
532 Self(underlier)
533 }
534
535 #[inline]
536 fn from_bases_sparse(
537 base_elems: impl IntoIterator<Item = $subfield_name>,
538 log_stride: usize,
539 ) -> Self {
540 use $crate::{Divisible, underlier::Underlier};
541
542 debug_assert!($name::N_BITS.is_power_of_two());
543 let shift_step = ($subfield_name::N_BITS << log_stride) & ($name::N_BITS - 1);
544 let mut underlier = <$typ as Underlier>::ZERO;
545 let mut shift = 0;
546
547 for elem in base_elems.into_iter() {
548 assert!(shift < $name::N_BITS, "too many base elements for extension degree");
549 let limb = shift / $subfield_name::N_BITS;
552 let acc = Divisible::<$subfield_typ>::get(&underlier, limb) | elem.val();
553 Divisible::<$subfield_typ>::set(&mut underlier, limb, acc);
554 shift += shift_step;
555 }
556
557 Self(underlier)
558 }
559
560 #[inline]
561 fn iter_bases(&self) -> impl Iterator<Item = $subfield_name> {
562 use binius_utils::iter::IterExtensions;
563 use $crate::{Divisible, underlier::UnderlierView};
564
565 Divisible::<<$subfield_name as UnderlierView>::Underlier>::ref_iter(&self.0)
566 .map_skippable($subfield_name::from)
567 }
568
569 #[inline]
570 unsafe fn get_base_unchecked(&self, i: usize) -> $subfield_name {
571 use $crate::{Divisible, underlier::UnderlierView};
572 unsafe {
574 $subfield_name::from_underlier(Divisible::<
575 <$subfield_name as UnderlierView>::Underlier,
576 >::get_unchecked(&self.to_underlier(), i))
577 }
578 }
579
580 #[inline]
581 fn square_transpose(values: &mut [Self]) {
582 crate::transpose::square_transforms_extension_field::<$subfield_name, Self>(values)
583 }
584 }
585 };
586}
587
588pub(crate) use impl_field_extension;
589
590binary_field!(pub BinaryField1b(U1), U1::new(0x1), U1::new(0x1));
592
593impl BinaryField1b {
594 pub const fn new(value: U1) -> Self {
595 Self(value)
596 }
597}
598
599impl From<u8> for BinaryField1b {
600 #[inline]
601 fn from(val: u8) -> Self {
602 Self::new(U1::new(val))
603 }
604}
605
606impl From<BinaryField1b> for u8 {
607 #[inline]
608 fn from(value: BinaryField1b) -> Self {
609 value.val().into()
610 }
611}
612
613impl From<bool> for BinaryField1b {
614 #[inline]
615 fn from(value: bool) -> Self {
616 Self::from(U1::new_unchecked(value.into()))
617 }
618}
619
620#[cfg(test)]
621pub(crate) mod tests {
622 use binius_utils::{DeserializeBytes, SerializeBytes, bytes::BytesMut};
623 use proptest::prelude::*;
624
625 use super::BinaryField1b as BF1;
626 use crate::{
627 BinaryField, BinaryField1b, ExtensionField, Field, Ghash128b, GhashSq256b, Rijndael8b,
628 arithmetic_traits::InvertOrZero,
629 };
630
631 #[test]
632 fn test_gf2_add() {
633 assert_eq!(BF1::from(0) + BF1::from(0), BF1::from(0));
634 assert_eq!(BF1::from(0) + BF1::from(1), BF1::from(1));
635 assert_eq!(BF1::from(1) + BF1::from(0), BF1::from(1));
636 assert_eq!(BF1::from(1) + BF1::from(1), BF1::from(0));
637 }
638
639 #[test]
640 fn test_gf2_sub() {
641 assert_eq!(BF1::from(0) - BF1::from(0), BF1::from(0));
642 assert_eq!(BF1::from(0) - BF1::from(1), BF1::from(1));
643 assert_eq!(BF1::from(1) - BF1::from(0), BF1::from(1));
644 assert_eq!(BF1::from(1) - BF1::from(1), BF1::from(0));
645 }
646
647 #[test]
648 fn test_gf2_mul() {
649 assert_eq!(BF1::from(0) * BF1::from(0), BF1::from(0));
650 assert_eq!(BF1::from(0) * BF1::from(1), BF1::from(0));
651 assert_eq!(BF1::from(1) * BF1::from(0), BF1::from(0));
652 assert_eq!(BF1::from(1) * BF1::from(1), BF1::from(1));
653 }
654
655 pub(crate) fn is_binary_field_valid_generator<F: BinaryField>() -> bool {
656 let mut order = if F::N_BITS == 128 {
658 u128::MAX
659 } else {
660 (1 << F::N_BITS) - 1
661 };
662
663 let mut factorization = Vec::new();
665
666 let mut prime = 2;
667 while prime * prime <= order {
668 while order.is_multiple_of(prime) {
669 order /= prime;
670 factorization.push(prime);
671 }
672
673 prime += if prime > 2 { 2 } else { 1 };
674 }
675
676 if order > 1 {
677 factorization.push(order);
678 }
679
680 for mask in 0..(1 << factorization.len()) {
682 let mut divisor = 1;
683
684 for (bit_index, &prime) in factorization.iter().enumerate() {
685 if (1 << bit_index) & mask != 0 {
686 divisor *= prime;
687 }
688 }
689
690 divisor = divisor.reverse_bits();
692
693 let mut pow_divisor = F::ONE;
694 while divisor > 0 {
695 pow_divisor *= pow_divisor;
696
697 if divisor & 1 != 0 {
698 pow_divisor *= F::MULTIPLICATIVE_GENERATOR;
699 }
700
701 divisor >>= 1;
702 }
703
704 let is_root_of_unity = pow_divisor == F::ONE;
706 let is_full_group = mask + 1 == 1 << factorization.len();
707
708 if is_root_of_unity && !is_full_group || !is_root_of_unity && is_full_group {
709 return false;
710 }
711 }
712
713 true
714 }
715
716 #[test]
717 fn test_multiplicative_generators() {
718 assert!(is_binary_field_valid_generator::<BinaryField1b>());
719 assert!(is_binary_field_valid_generator::<Rijndael8b>());
720 assert!(is_binary_field_valid_generator::<Ghash128b>());
721 }
722
723 fn trace<F: BinaryField>(x: F) -> F {
726 let mut acc = F::ZERO;
727 let mut square = x;
728 for _ in 0..F::N_BITS {
729 acc += square;
730 square = square.square();
731 }
732 acc
733 }
734
735 #[test]
740 fn test_trace_one_elements() {
741 fn check<F: BinaryField>() {
742 assert_eq!(trace(F::TRACE_ONE_ELEMENT), F::ONE);
743 }
744 check::<BinaryField1b>();
745 check::<Rijndael8b>();
746 check::<Ghash128b>();
747 check::<GhashSq256b>();
748 }
749
750 #[test]
754 fn test_trace_lands_in_the_prime_subfield() {
755 for value in 0..=u8::MAX {
756 let t = trace(Rijndael8b::new(value));
757 assert!(t == Rijndael8b::ZERO || t == Rijndael8b::ONE, "value {value:#04x}");
758 }
759 }
760
761 #[test]
762 fn test_field_degrees() {
763 assert_eq!(BinaryField1b::N_BITS, 1);
764 assert_eq!(Rijndael8b::N_BITS, 8);
765 assert_eq!(Ghash128b::N_BITS, 128);
766 }
767
768 #[test]
769 fn test_field_formatting() {
770 assert_eq!(format!("{}", BinaryField1b::from(1)), "0x1");
771 assert_eq!(format!("{}", Rijndael8b::from(3)), "0x03");
772 assert_eq!(format!("{}", Ghash128b::new(5)), "0x00000000000000000000000000000005");
773 }
774
775 #[test]
776 fn test_inverse_on_zero() {
777 assert!(BinaryField1b::ZERO.invert_or_zero().is_zero());
778 assert!(Rijndael8b::ZERO.invert_or_zero().is_zero());
779 assert!(Ghash128b::ZERO.invert_or_zero().is_zero());
780 }
781
782 proptest! {
783 #[test]
784 fn test_inverse_8b(val in 1u8..) {
785 let x = Rijndael8b::new(val);
786 let x_inverse = unsafe { x.invert() };
788 assert_eq!(x * x_inverse, Rijndael8b::ONE);
789 }
790
791 #[test]
792 fn test_inverse_128b(val in 1u128..) {
793 let x = Ghash128b::from(val);
794 let x_inverse = unsafe { x.invert() };
796 assert_eq!(x * x_inverse, Ghash128b::ONE);
797 }
798 }
799
800 fn assert_subfield_extraction<FSub: Field, F: ExtensionField<FSub>>() {
804 assert_eq!(TryInto::<FSub>::try_into(F::from(FSub::ZERO)).ok(), Some(FSub::ZERO));
805
806 let mut elem = FSub::ONE;
810 for _ in 0..4 {
811 assert_eq!(TryInto::<FSub>::try_into(F::from(elem)).ok(), Some(elem));
812 elem *= FSub::MULTIPLICATIVE_GENERATOR;
813 }
814
815 for i in 1..F::DEGREE {
818 assert!(TryInto::<FSub>::try_into(F::basis(i)).is_err());
819 assert!(TryInto::<FSub>::try_into(F::basis(i) + F::ONE).is_err());
820 }
821 }
822
823 #[test]
824 fn test_subfield_extraction() {
825 assert_subfield_extraction::<BinaryField1b, Ghash128b>();
826 assert_subfield_extraction::<BinaryField1b, Rijndael8b>();
827 assert_subfield_extraction::<Ghash128b, GhashSq256b>();
828 assert_subfield_extraction::<BinaryField1b, GhashSq256b>();
829 }
830
831 #[test]
832 fn test_serialization() {
833 let mut buffer = BytesMut::new();
834 let b1 = BinaryField1b::from(0x1);
835 let b8 = Rijndael8b::new(0x12);
836 let b128 = Ghash128b::new(0x147AD0369CF258BE8899AABBCCDDEEFF);
837
838 b1.serialize(&mut buffer).unwrap();
839 b8.serialize(&mut buffer).unwrap();
840 b128.serialize(&mut buffer).unwrap();
841
842 let mut read_buffer = buffer.freeze();
843
844 assert_eq!(BinaryField1b::deserialize(&mut read_buffer).unwrap(), b1);
845 assert_eq!(Rijndael8b::deserialize(&mut read_buffer).unwrap(), b8);
846 assert_eq!(Ghash128b::deserialize(&mut read_buffer).unwrap(), b128);
847 }
848}