binius_field/
binary_field_arithmetic.rs1use super::{arithmetic_traits::InvertOrZero, binary_field::*};
4use crate::{PackedField, arithmetic_traits::MulAlpha};
5
6pub(crate) trait TowerFieldArithmetic: TowerField {
7 fn multiply(self, rhs: Self) -> Self;
8
9 fn multiply_alpha(self) -> Self;
10
11 fn square(self) -> Self;
12}
13
14macro_rules! impl_arithmetic_using_packed {
15 ($name:ident) => {
16 impl InvertOrZero for $name {
17 #[inline]
18 fn invert_or_zero(self) -> Self {
19 use $crate::as_packed_field::AsPackedField;
20
21 $crate::binary_field_arithmetic::invert_or_zero_using_packed::<
22 <Self as AsPackedField<$name>>::Packed,
23 >(self)
24 }
25 }
26
27 impl TowerFieldArithmetic for $name {
28 #[inline]
29 fn multiply(self, rhs: Self) -> Self {
30 use $crate::as_packed_field::AsPackedField;
31
32 $crate::binary_field_arithmetic::multiple_using_packed::<
33 <Self as AsPackedField<$name>>::Packed,
34 >(self, rhs)
35 }
36
37 #[inline]
38 fn multiply_alpha(self) -> Self {
39 use $crate::as_packed_field::AsPackedField;
40
41 $crate::binary_field_arithmetic::mul_alpha_using_packed::<
42 <Self as AsPackedField<$name>>::Packed,
43 >(self)
44 }
45
46 #[inline]
47 fn square(self) -> Self {
48 use $crate::as_packed_field::AsPackedField;
49
50 $crate::binary_field_arithmetic::square_using_packed::<
51 <Self as AsPackedField<$name>>::Packed,
52 >(self)
53 }
54 }
55 };
56}
57
58pub(crate) use impl_arithmetic_using_packed;
59
60impl TowerField for BinaryField1b {
62 fn min_tower_level(self) -> usize {
63 0
64 }
65
66 #[inline]
67 fn mul_primitive(self, _: usize) -> Result<Self, crate::Error> {
68 Err(crate::Error::ExtensionDegreeMismatch)
69 }
70}
71
72impl InvertOrZero for BinaryField1b {
73 #[inline]
74 fn invert_or_zero(self) -> Self {
75 self
76 }
77}
78
79impl TowerFieldArithmetic for BinaryField1b {
80 #[inline]
81 fn multiply(self, rhs: Self) -> Self {
82 Self(self.0 & rhs.0)
83 }
84
85 #[inline]
86 fn multiply_alpha(self) -> Self {
87 self
88 }
89
90 #[inline]
91 fn square(self) -> Self {
92 self
93 }
94}
95
96#[inline]
99pub(super) fn multiple_using_packed<P: PackedField>(lhs: P::Scalar, rhs: P::Scalar) -> P::Scalar {
100 (P::set_single(lhs) * P::set_single(rhs)).get(0)
101}
102
103#[inline]
104pub(super) fn square_using_packed<P: PackedField>(value: P::Scalar) -> P::Scalar {
105 P::set_single(value).square().get(0)
106}
107
108#[inline]
109pub(super) fn invert_or_zero_using_packed<P: PackedField>(value: P::Scalar) -> P::Scalar {
110 P::set_single(value).invert_or_zero().get(0)
111}
112
113#[inline]
114pub(super) fn mul_alpha_using_packed<P: PackedField + MulAlpha>(value: P::Scalar) -> P::Scalar {
115 P::set_single(value).mul_alpha().get(0)
116}