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 binary_field_arithmetic::TowerFieldArithmetic, error::Error, extension::ExtensionField,
17};
18use crate::{Field, underlier::U1};
19
20pub trait BinaryField: ExtensionField<BinaryField1b> {
22 const N_BITS: usize = Self::DEGREE;
23 const MULTIPLICATIVE_GENERATOR: Self;
24}
25
26pub trait TowerField: BinaryField {
34 const TOWER_LEVEL: usize = Self::N_BITS.ilog2() as usize;
36
37 fn min_tower_level(self) -> usize;
43
44 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 fn mul_primitive(self, iota: usize) -> Result<Self, Error> {
71 Ok(self * <Self as ExtensionField<BinaryField1b>>::basis_checked(1 << iota)?)
72 }
73}
74
75#[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
100macro_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 #[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 let mut order = if F::N_BITS == 128 {
615 u128::MAX
616 } else {
617 (1 << F::N_BITS) - 1
618 };
619
620 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 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 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 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}