binius_field/
binary_field.rs

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