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