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::{
17 UnderlierType, WithUnderlier, binary_field_arithmetic::TowerFieldArithmetic,
18 extension::ExtensionField,
19};
20use crate::{Field, underlier::U1};
21
22pub trait BinaryField:
24 ExtensionField<BinaryField1b> + WithUnderlier<Underlier: UnderlierType>
25{
26 const N_BITS: usize = Self::ORDER_EXPONENT;
27}
28
29pub trait TowerField: BinaryField {
37 const TOWER_LEVEL: usize = Self::N_BITS.ilog2() as usize;
39
40 fn min_tower_level(self) -> usize;
46
47 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#[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
78macro_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 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 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 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 #[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 let mut order = if F::N_BITS == 128 {
620 u128::MAX
621 } else {
622 (1 << F::N_BITS) - 1
623 };
624
625 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 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 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 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}