1use 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 UnderlierWithBitOps, WithUnderlier, binary_field_arithmetic::TowerFieldArithmetic,
17 extension::ExtensionField,
18};
19use crate::{Field, underlier::U1};
20
21pub trait BinaryField:
23 ExtensionField<BinaryField1b> + WithUnderlier<Underlier: UnderlierWithBitOps>
24{
25 const N_BITS: usize = Self::ORDER_EXPONENT;
26}
27
28pub trait TowerField: BinaryField {
36 const TOWER_LEVEL: usize = Self::N_BITS.ilog2() as usize;
38
39 fn min_tower_level(self) -> usize;
45
46 fn basis(iota: usize, i: usize) -> Self {
54 assert!(iota <= Self::TOWER_LEVEL, "iota {iota} exceeds tower level {}", Self::TOWER_LEVEL);
55 let n_basis_elts = 1 << (Self::TOWER_LEVEL - iota);
56 assert!(i < n_basis_elts, "index {i} out of range for {n_basis_elts} basis elements");
57 <Self as ExtensionField<BinaryField1b>>::basis(i << iota)
58 }
59}
60
61#[inline]
69pub fn ext_basis<FExt, FSub>(i: usize) -> FExt
70where
71 FSub: Field,
72 FExt: ExtensionField<FSub>,
73{
74 <FExt as ExtensionField<FSub>>::basis(i)
75}
76
77macro_rules! binary_field {
79 ($vis:vis $name:ident($typ:ty), $gen:expr) => {
80 #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Zeroable, bytemuck::TransparentWrapper)]
81 #[repr(transparent)]
82 $vis struct $name(pub(crate) $typ);
83
84 impl $name {
85 pub const fn new(value: $typ) -> Self {
86 Self(value)
87 }
88
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::new(<$typ as $crate::underlier::UnderlierWithBitOps>::ZERO);
229 const ONE: Self = $name::new(<$typ as $crate::underlier::UnderlierWithBitOps>::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 ::rand::distr::Distribution<$name> for ::rand::distr::StandardUniform {
240 fn sample<R: ::rand::Rng + ?Sized>(&self, rng: &mut R) -> $name {
241 $name(rng.random())
242 }
243 }
244
245 impl Display for $name {
246 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
247 write!(f, "0x{repr:0>width$x}", repr=self.val(), width=Self::N_BITS.max(4) / 4)
248 }
249 }
250
251 impl Debug for $name {
252 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
253 let structure_name = std::any::type_name::<$name>().split("::").last().expect("exist");
254
255 write!(f, "{}({})",structure_name, self)
256 }
257 }
258
259 impl BinaryField for $name {}
260
261 impl From<$typ> for $name {
262 fn from(val: $typ) -> Self {
263 return Self(val)
264 }
265 }
266
267 impl From<$name> for $typ {
268 fn from(val: $name) -> Self {
269 return val.0
270 }
271 }
272 }
273}
274
275pub(crate) use binary_field;
276
277macro_rules! mul_by_binary_field_1b {
278 ($name:ident) => {
279 impl Mul<BinaryField1b> for $name {
280 type Output = Self;
281
282 #[inline]
283 #[allow(clippy::suspicious_arithmetic_impl)]
284 fn mul(self, rhs: BinaryField1b) -> Self::Output {
285 use $crate::underlier::{UnderlierWithBitOps, WithUnderlier};
286
287 $crate::tracing::trace_multiplication!(BinaryField128b, BinaryField1b);
288
289 Self(self.0 & <$name as WithUnderlier>::Underlier::fill_with_bit(u8::from(rhs.0)))
290 }
291 }
292 };
293}
294
295pub(crate) use mul_by_binary_field_1b;
296
297macro_rules! impl_field_extension {
298 ($subfield_name:ident($subfield_typ:ty) < @$log_degree:expr => $name:ident($typ:ty)) => {
299 impl TryFrom<$name> for $subfield_name {
300 type Error = ();
301
302 #[inline]
303 fn try_from(elem: $name) -> Result<Self, Self::Error> {
304 use $crate::underlier::NumCast;
305
306 if elem.0 >> $subfield_name::N_BITS
307 == <$typ as $crate::underlier::UnderlierWithBitOps>::ZERO
308 {
309 Ok($subfield_name::new(<$subfield_typ>::num_cast_from(elem.val())))
310 } else {
311 Err(())
312 }
313 }
314 }
315
316 impl From<$subfield_name> for $name {
317 #[inline]
318 fn from(elem: $subfield_name) -> Self {
319 $name::new(<$typ>::from(elem.val()))
320 }
321 }
322
323 impl Add<$subfield_name> for $name {
324 type Output = Self;
325
326 #[inline]
327 fn add(self, rhs: $subfield_name) -> Self::Output {
328 self + Self::from(rhs)
329 }
330 }
331
332 impl Sub<$subfield_name> for $name {
333 type Output = Self;
334
335 #[inline]
336 fn sub(self, rhs: $subfield_name) -> Self::Output {
337 self - Self::from(rhs)
338 }
339 }
340
341 impl AddAssign<$subfield_name> for $name {
342 #[inline]
343 fn add_assign(&mut self, rhs: $subfield_name) {
344 *self = *self + rhs;
345 }
346 }
347
348 impl SubAssign<$subfield_name> for $name {
349 #[inline]
350 fn sub_assign(&mut self, rhs: $subfield_name) {
351 *self = *self - rhs;
352 }
353 }
354
355 impl MulAssign<$subfield_name> for $name {
356 #[inline]
357 fn mul_assign(&mut self, rhs: $subfield_name) {
358 *self = *self * rhs;
359 }
360 }
361
362 impl Add<$name> for $subfield_name {
363 type Output = $name;
364
365 #[inline]
366 fn add(self, rhs: $name) -> Self::Output {
367 rhs + self
368 }
369 }
370
371 impl Sub<$name> for $subfield_name {
372 type Output = $name;
373
374 #[allow(clippy::suspicious_arithmetic_impl)]
375 #[inline]
376 fn sub(self, rhs: $name) -> Self::Output {
377 rhs + self
378 }
379 }
380
381 impl Mul<$name> for $subfield_name {
382 type Output = $name;
383
384 #[inline]
385 fn mul(self, rhs: $name) -> Self::Output {
386 rhs * self
387 }
388 }
389
390 impl ExtensionField<$subfield_name> for $name {
391 const LOG_DEGREE: usize = $log_degree;
392
393 #[inline]
394 fn basis(i: usize) -> Self {
395 use $crate::underlier::UnderlierWithBitOps;
396
397 assert!(
398 i < 1 << $log_degree,
399 "index {} out of range for degree {}",
400 i,
401 1 << $log_degree
402 );
403 Self::new(<$typ>::ONE << (i * $subfield_name::N_BITS))
404 }
405
406 #[inline]
407 fn from_bases_sparse(
408 base_elems: impl IntoIterator<Item = $subfield_name>,
409 log_stride: usize,
410 ) -> Self {
411 use $crate::underlier::UnderlierWithBitOps;
412
413 debug_assert!($name::N_BITS.is_power_of_two());
414 let shift_step = ($subfield_name::N_BITS << log_stride) & ($name::N_BITS - 1);
415 let mut value = <$typ>::ZERO;
416 let mut shift = 0;
417
418 for elem in base_elems.into_iter() {
419 assert!(shift < $name::N_BITS, "too many base elements for extension degree");
420 value |= <$typ>::from(elem.val()) << shift;
421 shift += shift_step;
422 }
423
424 Self::new(value)
425 }
426
427 #[inline]
428 fn iter_bases(&self) -> impl Iterator<Item = $subfield_name> {
429 use binius_utils::iter::IterExtensions;
430 use $crate::underlier::{Divisible, WithUnderlier};
431
432 Divisible::<<$subfield_name as WithUnderlier>::Underlier>::ref_iter(&self.0)
433 .map_skippable($subfield_name::from)
434 }
435
436 #[inline]
437 fn into_iter_bases(self) -> impl Iterator<Item = $subfield_name> {
438 use binius_utils::iter::IterExtensions;
439 use $crate::underlier::{Divisible, WithUnderlier};
440
441 Divisible::<<$subfield_name as WithUnderlier>::Underlier>::value_iter(self.0)
442 .map_skippable($subfield_name::from)
443 }
444
445 #[inline]
446 unsafe fn get_base_unchecked(&self, i: usize) -> $subfield_name {
447 use $crate::underlier::{UnderlierWithBitOps, WithUnderlier};
448 unsafe { $subfield_name::from_underlier(self.to_underlier().get_subvalue(i)) }
449 }
450
451 #[inline]
452 fn square_transpose(values: &mut [Self]) {
453 crate::transpose::square_transforms_extension_field::<$subfield_name, Self>(values)
454 }
455 }
456 };
457}
458
459pub(crate) use impl_field_extension;
460
461binary_field!(pub BinaryField1b(U1), U1::new(0x1));
462
463macro_rules! serialize_deserialize {
464 ($bin_type:ty) => {
465 impl SerializeBytes for $bin_type {
466 fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError> {
467 self.0.serialize(write_buf)
468 }
469 }
470
471 impl DeserializeBytes for $bin_type {
472 fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError> {
473 Ok(Self(DeserializeBytes::deserialize(read_buf)?))
474 }
475 }
476 };
477}
478
479serialize_deserialize!(BinaryField1b);
480
481impl BinaryField1b {
482 #[inline]
487 pub unsafe fn new_unchecked(val: u8) -> Self {
488 debug_assert!(val < 2, "val has to be less than 2, but it's {val}");
489
490 Self::new(U1::new_unchecked(val))
491 }
492}
493
494impl From<u8> for BinaryField1b {
495 #[inline]
496 fn from(val: u8) -> Self {
497 Self::new(U1::new(val))
498 }
499}
500
501impl From<BinaryField1b> for u8 {
502 #[inline]
503 fn from(value: BinaryField1b) -> Self {
504 value.val().into()
505 }
506}
507
508impl From<bool> for BinaryField1b {
509 #[inline]
510 fn from(value: bool) -> Self {
511 Self::from(U1::new_unchecked(value.into()))
512 }
513}
514
515#[cfg(test)]
516pub(crate) mod tests {
517 use binius_utils::{DeserializeBytes, SerializeBytes, bytes::BytesMut};
518 use proptest::prelude::*;
519
520 use super::BinaryField1b as BF1;
521 use crate::{AESTowerField8b, BinaryField, BinaryField1b, BinaryField128bGhash, Field};
522
523 #[test]
524 fn test_gf2_add() {
525 assert_eq!(BF1::from(0) + BF1::from(0), BF1::from(0));
526 assert_eq!(BF1::from(0) + BF1::from(1), BF1::from(1));
527 assert_eq!(BF1::from(1) + BF1::from(0), BF1::from(1));
528 assert_eq!(BF1::from(1) + BF1::from(1), BF1::from(0));
529 }
530
531 #[test]
532 fn test_gf2_sub() {
533 assert_eq!(BF1::from(0) - BF1::from(0), BF1::from(0));
534 assert_eq!(BF1::from(0) - BF1::from(1), BF1::from(1));
535 assert_eq!(BF1::from(1) - BF1::from(0), BF1::from(1));
536 assert_eq!(BF1::from(1) - BF1::from(1), BF1::from(0));
537 }
538
539 #[test]
540 fn test_gf2_mul() {
541 assert_eq!(BF1::from(0) * BF1::from(0), BF1::from(0));
542 assert_eq!(BF1::from(0) * BF1::from(1), BF1::from(0));
543 assert_eq!(BF1::from(1) * BF1::from(0), BF1::from(0));
544 assert_eq!(BF1::from(1) * BF1::from(1), BF1::from(1));
545 }
546
547 pub(crate) fn is_binary_field_valid_generator<F: BinaryField>() -> bool {
548 let mut order = if F::N_BITS == 128 {
550 u128::MAX
551 } else {
552 (1 << F::N_BITS) - 1
553 };
554
555 let mut factorization = Vec::new();
557
558 let mut prime = 2;
559 while prime * prime <= order {
560 while order.is_multiple_of(prime) {
561 order /= prime;
562 factorization.push(prime);
563 }
564
565 prime += if prime > 2 { 2 } else { 1 };
566 }
567
568 if order > 1 {
569 factorization.push(order);
570 }
571
572 for mask in 0..(1 << factorization.len()) {
574 let mut divisor = 1;
575
576 for (bit_index, &prime) in factorization.iter().enumerate() {
577 if (1 << bit_index) & mask != 0 {
578 divisor *= prime;
579 }
580 }
581
582 divisor = divisor.reverse_bits();
584
585 let mut pow_divisor = F::ONE;
586 while divisor > 0 {
587 pow_divisor *= pow_divisor;
588
589 if divisor & 1 != 0 {
590 pow_divisor *= F::MULTIPLICATIVE_GENERATOR;
591 }
592
593 divisor >>= 1;
594 }
595
596 let is_root_of_unity = pow_divisor == F::ONE;
598 let is_full_group = mask + 1 == 1 << factorization.len();
599
600 if is_root_of_unity && !is_full_group || !is_root_of_unity && is_full_group {
601 return false;
602 }
603 }
604
605 true
606 }
607
608 #[test]
609 fn test_multiplicative_generators() {
610 assert!(is_binary_field_valid_generator::<BinaryField1b>());
611 assert!(is_binary_field_valid_generator::<AESTowerField8b>());
612 assert!(is_binary_field_valid_generator::<BinaryField128bGhash>());
613 }
614
615 #[test]
616 fn test_field_degrees() {
617 assert_eq!(BinaryField1b::N_BITS, 1);
618 assert_eq!(AESTowerField8b::N_BITS, 8);
619 assert_eq!(BinaryField128bGhash::N_BITS, 128);
620 }
621
622 #[test]
623 fn test_field_formatting() {
624 assert_eq!(format!("{}", BinaryField1b::from(1)), "0x1");
625 assert_eq!(format!("{}", AESTowerField8b::from(3)), "0x03");
626 assert_eq!(
627 format!("{}", BinaryField128bGhash::from(5)),
628 "0x00000000000000000000000000000005"
629 );
630 }
631
632 #[test]
633 fn test_inverse_on_zero() {
634 assert!(BinaryField1b::ZERO.invert().is_none());
635 assert!(AESTowerField8b::ZERO.invert().is_none());
636 assert!(BinaryField128bGhash::ZERO.invert().is_none());
637 }
638
639 proptest! {
640 #[test]
641 fn test_inverse_8b(val in 1u8..) {
642 let x = AESTowerField8b::new(val);
643 let x_inverse = x.invert().unwrap();
644 assert_eq!(x * x_inverse, AESTowerField8b::ONE);
645 }
646
647 #[test]
648 fn test_inverse_128b(val in 1u128..) {
649 let x = BinaryField128bGhash::new(val);
650 let x_inverse = x.invert().unwrap();
651 assert_eq!(x * x_inverse, BinaryField128bGhash::ONE);
652 }
653 }
654
655 #[test]
656 fn test_serialization() {
657 let mut buffer = BytesMut::new();
658 let b1 = BinaryField1b::from(0x1);
659 let b8 = AESTowerField8b::new(0x12);
660 let b128 = BinaryField128bGhash::new(0x147AD0369CF258BE8899AABBCCDDEEFF);
661
662 b1.serialize(&mut buffer).unwrap();
663 b8.serialize(&mut buffer).unwrap();
664 b128.serialize(&mut buffer).unwrap();
665
666 let mut read_buffer = buffer.freeze();
667
668 assert_eq!(BinaryField1b::deserialize(&mut read_buffer).unwrap(), b1);
669 assert_eq!(AESTowerField8b::deserialize(&mut read_buffer).unwrap(), b8);
670 assert_eq!(BinaryField128bGhash::deserialize(&mut read_buffer).unwrap(), b128);
671 }
672
673 #[test]
674 fn test_gf2_new_unchecked() {
675 for i in 0..2 {
676 assert_eq!(unsafe { BF1::new_unchecked(i) }, BF1::from(i));
677 }
678 }
679}