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