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