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