Skip to main content

binius_field/
binary_field.rs

1// Copyright 2023-2025 Irreducible Inc.
2// Copyright 2026 The Binius Developers
3
4use 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::{
17	UnderlierType, WithUnderlier, binary_field_arithmetic::TowerFieldArithmetic,
18	extension::ExtensionField,
19};
20use crate::{Field, underlier::U1};
21
22/// A finite field with characteristic 2.
23pub trait BinaryField:
24	ExtensionField<BinaryField1b> + WithUnderlier<Underlier: UnderlierType>
25{
26	const N_BITS: usize = Self::ORDER_EXPONENT;
27}
28
29/// A binary field *isomorphic* to a binary tower field.
30///
31/// The canonical binary field tower construction is specified in [DP23], section 2.3. This is a
32/// family of binary fields with extension degree $2^{\iota}$ for any tower height $\iota$. This
33/// trait can be implemented on any binary field *isomorphic* to the canonical tower field.
34///
35/// [DP23]: https://eprint.iacr.org/2023/1784
36pub trait TowerField: BinaryField {
37	/// The level $\iota$ in the tower, where this field is isomorphic to $T_{\iota}$.
38	const TOWER_LEVEL: usize = Self::N_BITS.ilog2() as usize;
39
40	/// Returns the smallest valid `TOWER_LEVEL` in the tower that can fit the same value.
41	///
42	/// Since which `TOWER_LEVEL` values are valid depends on the tower,
43	/// `F::Canonical::from(elem).min_tower_level()` can return a different result
44	/// from `elem.min_tower_level()`.
45	fn min_tower_level(self) -> usize;
46
47	/// Returns the i'th basis element of this field as an extension over the tower subfield with
48	/// level $\iota$.
49	///
50	/// # Preconditions
51	///
52	/// * `iota` must be at most `TOWER_LEVEL`.
53	/// * `i` must be less than `2^(TOWER_LEVEL - iota)`.
54	fn basis(iota: usize, i: usize) -> Self {
55		assert!(iota <= Self::TOWER_LEVEL, "iota {iota} exceeds tower level {}", Self::TOWER_LEVEL);
56		let n_basis_elts = 1 << (Self::TOWER_LEVEL - iota);
57		assert!(i < n_basis_elts, "index {i} out of range for {n_basis_elts} basis elements");
58		<Self as ExtensionField<BinaryField1b>>::basis(i << iota)
59	}
60}
61
62/// Returns the i'th basis element of `FExt` as a field extension of `FSub`.
63///
64/// This is an alias function for [`ExtensionField::basis`].
65///
66/// ## Pre-conditions
67///
68/// * `i` must be in the range $[0, d)$, where $d$ is the field extension degree.
69#[inline]
70pub fn ext_basis<FExt, FSub>(i: usize) -> FExt
71where
72	FSub: Field,
73	FExt: ExtensionField<FSub>,
74{
75	<FExt as ExtensionField<FSub>>::basis(i)
76}
77
78/// Macro to generate an implementation of a BinaryField.
79macro_rules! binary_field {
80	($vis:vis $name:ident($typ:ty), $gen:expr) => {
81		#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Zeroable, bytemuck::TransparentWrapper)]
82		#[repr(transparent)]
83		$vis struct $name(pub(crate) $typ);
84
85		// NOTE: `new` is intentionally NOT generated here. Each field defines its own `new` so it
86		// can take an ergonomic constructor type independent of the underlier (e.g.
87		// `BinaryField128bGhash::new` takes `u128` even though its underlier is `M128`).
88		impl $name {
89			pub const fn val(self) -> $typ {
90				self.0
91			}
92		}
93
94		unsafe impl $crate::underlier::WithUnderlier for $name {
95			type Underlier = $typ;
96		}
97
98		impl Neg for $name {
99			type Output = Self;
100
101			fn neg(self) -> Self::Output {
102				self
103			}
104		}
105
106		impl Add<Self> for $name {
107			type Output = Self;
108
109			#[allow(clippy::suspicious_arithmetic_impl)]
110			fn add(self, rhs: Self) -> Self::Output {
111				$name(self.0 ^ rhs.0)
112			}
113		}
114
115		impl Add<&Self> for $name {
116			type Output = Self;
117
118			#[allow(clippy::suspicious_arithmetic_impl)]
119			fn add(self, rhs: &Self) -> Self::Output {
120				$name(self.0 ^ rhs.0)
121			}
122		}
123
124		impl Sub<Self> for $name {
125			type Output = Self;
126
127			#[allow(clippy::suspicious_arithmetic_impl)]
128			fn sub(self, rhs: Self) -> Self::Output {
129				$name(self.0 ^ rhs.0)
130			}
131		}
132
133		impl Sub<&Self> for $name {
134			type Output = Self;
135
136			#[allow(clippy::suspicious_arithmetic_impl)]
137			fn sub(self, rhs: &Self) -> Self::Output {
138				$name(self.0 ^ rhs.0)
139			}
140		}
141
142		impl Mul<Self> for $name {
143			type Output = Self;
144
145			fn mul(self, rhs: Self) -> Self::Output {
146				$crate::tracing::trace_multiplication!($name);
147
148				TowerFieldArithmetic::multiply(self, rhs)
149			}
150		}
151
152		impl Mul<&Self> for $name {
153			type Output = Self;
154
155			fn mul(self, rhs: &Self) -> Self::Output {
156				self * *rhs
157			}
158		}
159
160		impl AddAssign<Self> for $name {
161			fn add_assign(&mut self, rhs: Self) {
162				*self = *self + rhs;
163			}
164		}
165
166		impl AddAssign<&Self> for $name {
167			fn add_assign(&mut self, rhs: &Self) {
168				*self = *self + *rhs;
169			}
170		}
171
172		impl SubAssign<Self> for $name {
173			fn sub_assign(&mut self, rhs: Self) {
174				*self = *self - rhs;
175			}
176		}
177
178		impl SubAssign<&Self> for $name {
179			fn sub_assign(&mut self, rhs: &Self) {
180				*self = *self - *rhs;
181			}
182		}
183
184		impl MulAssign<Self> for $name {
185			fn mul_assign(&mut self, rhs: Self) {
186				*self = *self * rhs;
187			}
188		}
189
190		impl MulAssign<&Self> for $name {
191			fn mul_assign(&mut self, rhs: &Self) {
192				*self = *self * rhs;
193			}
194		}
195
196		impl Sum<Self> for $name {
197			fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
198				iter.fold(Self::ZERO, |acc, x| acc + x)
199			}
200		}
201
202		impl<'a> Sum<&'a Self> for $name {
203			fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
204				iter.fold(Self::ZERO, |acc, x| acc + x)
205			}
206		}
207
208		impl Product<Self> for $name {
209			fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
210				iter.fold(Self::ONE, |acc, x| acc * x)
211			}
212		}
213
214		impl<'a> Product<&'a Self> for $name {
215			fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
216				iter.fold(Self::ONE, |acc, x| acc * x)
217			}
218		}
219
220
221		impl crate::arithmetic_traits::Square for $name {
222			fn square(self) -> Self {
223				TowerFieldArithmetic::square(self)
224			}
225		}
226
227		impl Field for $name {
228			const ZERO: Self = $name(<$typ as $crate::underlier::UnderlierType>::ZERO);
229			const ONE: Self = $name(<$typ as $crate::underlier::UnderlierType>::ONE);
230			const CHARACTERISTIC: usize = 2;
231			const ORDER_EXPONENT: usize = <$typ as $crate::underlier::UnderlierType>::BITS;
232			const MULTIPLICATIVE_GENERATOR: $name = $name($gen);
233
234			fn double(&self) -> Self {
235				Self::ZERO
236			}
237		}
238
239		// A field element divides into exactly one element of itself. This makes the field a
240		// degenerate packed field of width one (see the blanket `PackedField for Field` impl).
241		impl $crate::Divisible<$name> for $name {
242			const LOG_N: usize = 0;
243
244			#[inline]
245			fn value_iter(value: Self) -> impl ExactSizeIterator<Item = $name> + Send + Clone {
246				std::iter::once(value)
247			}
248
249			#[inline]
250			fn ref_iter(value: &Self) -> impl ExactSizeIterator<Item = $name> + Send + Clone + '_ {
251				std::iter::once(*value)
252			}
253
254			#[inline]
255			fn slice_iter(slice: &[Self]) -> impl ExactSizeIterator<Item = $name> + Send + Clone + '_ {
256				slice.iter().copied()
257			}
258
259			#[inline]
260			unsafe fn get_unchecked(&self, _index: usize) -> $name {
261				*self
262			}
263
264			#[inline]
265			unsafe fn set_unchecked(&mut self, _index: usize, val: $name) {
266				*self = val;
267			}
268
269			#[inline]
270			fn broadcast(val: $name) -> Self {
271				val
272			}
273
274			#[inline]
275			fn from_iter(mut iter: impl Iterator<Item = $name>) -> Self {
276				iter.next().unwrap_or(Self::ZERO)
277			}
278		}
279
280		// As a width-one packed field, a field element is masked by its single selector: kept
281		// when selected, otherwise zeroed. Uses the same underlier bitmask strategy as
282		// PackedPrimitiveType so the mask type and AND operation are consistent.
283		impl $crate::Maskable<$name> for $name {
284			type Mask = $typ;
285
286			#[inline]
287			fn make_mask(mut selectors: impl Iterator<Item = bool>) -> $typ {
288				<$typ as $crate::underlier::UnderlierType>::fill_with_bit(
289					u8::from(selectors.next().unwrap_or(false)),
290				)
291			}
292
293			#[inline]
294			fn select(&self, mask: &$typ) -> Self {
295				Self(self.0 & *mask)
296			}
297		}
298
299		impl ::rand::distr::Distribution<$name> for ::rand::distr::StandardUniform {
300			fn sample<R: ::rand::Rng + ?Sized>(&self, rng: &mut R) -> $name {
301				$name(::rand::distr::StandardUniform.sample(rng))
302			}
303		}
304
305		impl Display for $name {
306			fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
307				write!(f, "0x{repr:0>width$x}", repr=self.val(), width=Self::N_BITS.max(4) / 4)
308			}
309		}
310
311		impl Debug for $name {
312			fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
313				let structure_name = std::any::type_name::<$name>().split("::").last().expect("exist");
314
315				write!(f, "{}({})",structure_name, self)
316			}
317		}
318
319		impl BinaryField for $name {}
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
335pub(crate) use binary_field;
336
337macro_rules! mul_by_binary_field_1b {
338	($name:ident) => {
339		impl Mul<BinaryField1b> for $name {
340			type Output = Self;
341
342			#[inline]
343			#[allow(clippy::suspicious_arithmetic_impl)]
344			fn mul(self, rhs: BinaryField1b) -> Self::Output {
345				use $crate::underlier::{UnderlierType, WithUnderlier};
346
347				$crate::tracing::trace_multiplication!(BinaryField128b, BinaryField1b);
348
349				Self(self.0 & <$name as WithUnderlier>::Underlier::fill_with_bit(u8::from(rhs.0)))
350			}
351		}
352	};
353}
354
355pub(crate) use mul_by_binary_field_1b;
356
357macro_rules! impl_field_extension {
358	($subfield_name:ident($subfield_typ:ty) < @$log_degree:expr => $name:ident($typ:ty)) => {
359		impl TryFrom<$name> for $subfield_name {
360			type Error = ();
361
362			#[inline]
363			fn try_from(elem: $name) -> Result<Self, Self::Error> {
364				use $crate::underlier::NumCast;
365
366				if elem.0 >> $subfield_name::N_BITS
367					== <$typ as $crate::underlier::UnderlierType>::ZERO
368				{
369					Ok($subfield_name(<$subfield_typ>::num_cast_from(elem.val())))
370				} else {
371					Err(())
372				}
373			}
374		}
375
376		impl From<$subfield_name> for $name {
377			#[inline]
378			fn from(elem: $subfield_name) -> Self {
379				$name(<$typ>::from(elem.val()))
380			}
381		}
382
383		impl Add<$subfield_name> for $name {
384			type Output = Self;
385
386			#[inline]
387			fn add(self, rhs: $subfield_name) -> Self::Output {
388				self + Self::from(rhs)
389			}
390		}
391
392		impl Sub<$subfield_name> for $name {
393			type Output = Self;
394
395			#[inline]
396			fn sub(self, rhs: $subfield_name) -> Self::Output {
397				self - Self::from(rhs)
398			}
399		}
400
401		impl AddAssign<$subfield_name> for $name {
402			#[inline]
403			fn add_assign(&mut self, rhs: $subfield_name) {
404				*self = *self + rhs;
405			}
406		}
407
408		impl SubAssign<$subfield_name> for $name {
409			#[inline]
410			fn sub_assign(&mut self, rhs: $subfield_name) {
411				*self = *self - rhs;
412			}
413		}
414
415		impl MulAssign<$subfield_name> for $name {
416			#[inline]
417			fn mul_assign(&mut self, rhs: $subfield_name) {
418				*self = *self * rhs;
419			}
420		}
421
422		impl Add<$name> for $subfield_name {
423			type Output = $name;
424
425			#[inline]
426			fn add(self, rhs: $name) -> Self::Output {
427				rhs + self
428			}
429		}
430
431		impl Sub<$name> for $subfield_name {
432			type Output = $name;
433
434			#[allow(clippy::suspicious_arithmetic_impl)]
435			#[inline]
436			fn sub(self, rhs: $name) -> Self::Output {
437				rhs + self
438			}
439		}
440
441		impl Mul<$name> for $subfield_name {
442			type Output = $name;
443
444			#[inline]
445			fn mul(self, rhs: $name) -> Self::Output {
446				rhs * self
447			}
448		}
449
450		impl ExtensionField<$subfield_name> for $name {
451			const LOG_DEGREE: usize = $log_degree;
452
453			#[inline]
454			fn basis(i: usize) -> Self {
455				use $crate::underlier::UnderlierType;
456
457				assert!(
458					i < 1 << $log_degree,
459					"index {} out of range for degree {}",
460					i,
461					1 << $log_degree
462				);
463				Self(<$typ>::ONE << (i * $subfield_name::N_BITS))
464			}
465
466			#[inline]
467			fn from_bases_sparse(
468				base_elems: impl IntoIterator<Item = $subfield_name>,
469				log_stride: usize,
470			) -> Self {
471				use $crate::underlier::UnderlierType;
472
473				debug_assert!($name::N_BITS.is_power_of_two());
474				let shift_step = ($subfield_name::N_BITS << log_stride) & ($name::N_BITS - 1);
475				let mut value = <$typ>::ZERO;
476				let mut shift = 0;
477
478				for elem in base_elems.into_iter() {
479					assert!(shift < $name::N_BITS, "too many base elements for extension degree");
480					value |= <$typ>::from(elem.val()) << shift;
481					shift += shift_step;
482				}
483
484				Self(value)
485			}
486
487			#[inline]
488			fn iter_bases(&self) -> impl Iterator<Item = $subfield_name> {
489				use binius_utils::iter::IterExtensions;
490				use $crate::underlier::{Divisible, WithUnderlier};
491
492				Divisible::<<$subfield_name as WithUnderlier>::Underlier>::ref_iter(&self.0)
493					.map_skippable($subfield_name::from)
494			}
495
496			#[inline]
497			fn into_iter_bases(self) -> impl Iterator<Item = $subfield_name> {
498				use binius_utils::iter::IterExtensions;
499				use $crate::underlier::{Divisible, WithUnderlier};
500
501				Divisible::<<$subfield_name as WithUnderlier>::Underlier>::value_iter(self.0)
502					.map_skippable($subfield_name::from)
503			}
504
505			#[inline]
506			unsafe fn get_base_unchecked(&self, i: usize) -> $subfield_name {
507				use $crate::underlier::{UnderlierType, WithUnderlier};
508				unsafe { $subfield_name::from_underlier(self.to_underlier().get_subvalue(i)) }
509			}
510
511			#[inline]
512			fn square_transpose(values: &mut [Self]) {
513				crate::transpose::square_transforms_extension_field::<$subfield_name, Self>(values)
514			}
515		}
516	};
517}
518
519pub(crate) use impl_field_extension;
520
521binary_field!(pub BinaryField1b(U1), U1::new(0x1));
522
523crate::arithmetic_traits::impl_trivial_wide_mul!(BinaryField1b);
524
525macro_rules! serialize_deserialize {
526	($bin_type:ty) => {
527		impl SerializeBytes for $bin_type {
528			fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError> {
529				self.0.serialize(write_buf)
530			}
531		}
532
533		impl DeserializeBytes for $bin_type {
534			fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError> {
535				Ok(Self(DeserializeBytes::deserialize(read_buf)?))
536			}
537		}
538	};
539}
540
541serialize_deserialize!(BinaryField1b);
542
543impl FixedSizeSerializeBytes for BinaryField1b {
544	const BYTE_SIZE: usize = 1;
545}
546
547impl BinaryField1b {
548	pub const fn new(value: U1) -> Self {
549		Self(value)
550	}
551
552	/// Creates value without checking that it is within valid range (0 or 1)
553	///
554	/// # Safety
555	/// Value should not exceed 1
556	#[inline]
557	pub unsafe fn new_unchecked(val: u8) -> Self {
558		debug_assert!(val < 2, "val has to be less than 2, but it's {val}");
559
560		Self::new(U1::new_unchecked(val))
561	}
562}
563
564impl From<u8> for BinaryField1b {
565	#[inline]
566	fn from(val: u8) -> Self {
567		Self::new(U1::new(val))
568	}
569}
570
571impl From<BinaryField1b> for u8 {
572	#[inline]
573	fn from(value: BinaryField1b) -> Self {
574		value.val().into()
575	}
576}
577
578impl From<bool> for BinaryField1b {
579	#[inline]
580	fn from(value: bool) -> Self {
581		Self::from(U1::new_unchecked(value.into()))
582	}
583}
584
585#[cfg(test)]
586pub(crate) mod tests {
587	use binius_utils::{DeserializeBytes, SerializeBytes, bytes::BytesMut};
588	use proptest::prelude::*;
589
590	use super::BinaryField1b as BF1;
591	use crate::{AESTowerField8b, BinaryField, BinaryField1b, BinaryField128bGhash, Field};
592
593	#[test]
594	fn test_gf2_add() {
595		assert_eq!(BF1::from(0) + BF1::from(0), BF1::from(0));
596		assert_eq!(BF1::from(0) + BF1::from(1), BF1::from(1));
597		assert_eq!(BF1::from(1) + BF1::from(0), BF1::from(1));
598		assert_eq!(BF1::from(1) + BF1::from(1), BF1::from(0));
599	}
600
601	#[test]
602	fn test_gf2_sub() {
603		assert_eq!(BF1::from(0) - BF1::from(0), BF1::from(0));
604		assert_eq!(BF1::from(0) - BF1::from(1), BF1::from(1));
605		assert_eq!(BF1::from(1) - BF1::from(0), BF1::from(1));
606		assert_eq!(BF1::from(1) - BF1::from(1), BF1::from(0));
607	}
608
609	#[test]
610	fn test_gf2_mul() {
611		assert_eq!(BF1::from(0) * BF1::from(0), BF1::from(0));
612		assert_eq!(BF1::from(0) * BF1::from(1), BF1::from(0));
613		assert_eq!(BF1::from(1) * BF1::from(0), BF1::from(0));
614		assert_eq!(BF1::from(1) * BF1::from(1), BF1::from(1));
615	}
616
617	pub(crate) fn is_binary_field_valid_generator<F: BinaryField>() -> bool {
618		// Binary fields should contain a multiplicative subgroup of size 2^n - 1
619		let mut order = if F::N_BITS == 128 {
620			u128::MAX
621		} else {
622			(1 << F::N_BITS) - 1
623		};
624
625		// Naive factorization of group order - represented as a multiset of prime factors
626		let mut factorization = Vec::new();
627
628		let mut prime = 2;
629		while prime * prime <= order {
630			while order.is_multiple_of(prime) {
631				order /= prime;
632				factorization.push(prime);
633			}
634
635			prime += if prime > 2 { 2 } else { 1 };
636		}
637
638		if order > 1 {
639			factorization.push(order);
640		}
641
642		// Iterate over all divisors (some may be tested several times if order is non-square-free)
643		for mask in 0..(1 << factorization.len()) {
644			let mut divisor = 1;
645
646			for (bit_index, &prime) in factorization.iter().enumerate() {
647				if (1 << bit_index) & mask != 0 {
648					divisor *= prime;
649				}
650			}
651
652			// Compute pow(generator, divisor) in log time
653			divisor = divisor.reverse_bits();
654
655			let mut pow_divisor = F::ONE;
656			while divisor > 0 {
657				pow_divisor *= pow_divisor;
658
659				if divisor & 1 != 0 {
660					pow_divisor *= F::MULTIPLICATIVE_GENERATOR;
661				}
662
663				divisor >>= 1;
664			}
665
666			// Generator invariant
667			let is_root_of_unity = pow_divisor == F::ONE;
668			let is_full_group = mask + 1 == 1 << factorization.len();
669
670			if is_root_of_unity && !is_full_group || !is_root_of_unity && is_full_group {
671				return false;
672			}
673		}
674
675		true
676	}
677
678	#[test]
679	fn test_multiplicative_generators() {
680		assert!(is_binary_field_valid_generator::<BinaryField1b>());
681		assert!(is_binary_field_valid_generator::<AESTowerField8b>());
682		assert!(is_binary_field_valid_generator::<BinaryField128bGhash>());
683	}
684
685	#[test]
686	fn test_field_degrees() {
687		assert_eq!(BinaryField1b::N_BITS, 1);
688		assert_eq!(AESTowerField8b::N_BITS, 8);
689		assert_eq!(BinaryField128bGhash::N_BITS, 128);
690	}
691
692	#[test]
693	fn test_field_formatting() {
694		assert_eq!(format!("{}", BinaryField1b::from(1)), "0x1");
695		assert_eq!(format!("{}", AESTowerField8b::from(3)), "0x03");
696		assert_eq!(
697			format!("{}", BinaryField128bGhash::new(5)),
698			"0x00000000000000000000000000000005"
699		);
700	}
701
702	#[test]
703	fn test_inverse_on_zero() {
704		assert!(BinaryField1b::ZERO.invert().is_none());
705		assert!(AESTowerField8b::ZERO.invert().is_none());
706		assert!(BinaryField128bGhash::ZERO.invert().is_none());
707	}
708
709	proptest! {
710		#[test]
711		fn test_inverse_8b(val in 1u8..) {
712			let x = AESTowerField8b::new(val);
713			let x_inverse = x.invert().unwrap();
714			assert_eq!(x * x_inverse, AESTowerField8b::ONE);
715		}
716
717		#[test]
718		fn test_inverse_128b(val in 1u128..) {
719			let x = BinaryField128bGhash::from(val);
720			let x_inverse = x.invert().unwrap();
721			assert_eq!(x * x_inverse, BinaryField128bGhash::ONE);
722		}
723	}
724
725	#[test]
726	fn test_serialization() {
727		let mut buffer = BytesMut::new();
728		let b1 = BinaryField1b::from(0x1);
729		let b8 = AESTowerField8b::new(0x12);
730		let b128 = BinaryField128bGhash::new(0x147AD0369CF258BE8899AABBCCDDEEFF);
731
732		b1.serialize(&mut buffer).unwrap();
733		b8.serialize(&mut buffer).unwrap();
734		b128.serialize(&mut buffer).unwrap();
735
736		let mut read_buffer = buffer.freeze();
737
738		assert_eq!(BinaryField1b::deserialize(&mut read_buffer).unwrap(), b1);
739		assert_eq!(AESTowerField8b::deserialize(&mut read_buffer).unwrap(), b8);
740		assert_eq!(BinaryField128bGhash::deserialize(&mut read_buffer).unwrap(), b128);
741	}
742
743	#[test]
744	fn test_gf2_new_unchecked() {
745		for i in 0..2 {
746			assert_eq!(unsafe { BF1::new_unchecked(i) }, BF1::from(i));
747		}
748	}
749}