binius_field/
binary_field_arithmetic.rs1use super::{arithmetic_traits::InvertOrZero, binary_field::*};
4use crate::{arithmetic_traits::MulAlpha, PackedField};
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 type Canonical = Self;
63
64 fn min_tower_level(self) -> usize {
65 0
66 }
67
68 #[inline]
69 fn mul_primitive(self, _: usize) -> Result<Self, crate::Error> {
70 Err(crate::Error::ExtensionDegreeMismatch)
71 }
72}
73
74impl InvertOrZero for BinaryField1b {
75 #[inline]
76 fn invert_or_zero(self) -> Self {
77 self
78 }
79}
80
81impl TowerFieldArithmetic for BinaryField1b {
82 #[inline]
83 fn multiply(self, rhs: Self) -> Self {
84 Self(self.0 & rhs.0)
85 }
86
87 #[inline]
88 fn multiply_alpha(self) -> Self {
89 self
90 }
91
92 #[inline]
93 fn square(self) -> Self {
94 self
95 }
96}
97
98impl_arithmetic_using_packed!(BinaryField2b);
99impl_arithmetic_using_packed!(BinaryField4b);
100impl_arithmetic_using_packed!(BinaryField8b);
101impl_arithmetic_using_packed!(BinaryField16b);
102impl_arithmetic_using_packed!(BinaryField32b);
103impl_arithmetic_using_packed!(BinaryField64b);
104impl_arithmetic_using_packed!(BinaryField128b);
105
106#[inline]
109pub(super) fn multiple_using_packed<P: PackedField>(lhs: P::Scalar, rhs: P::Scalar) -> P::Scalar {
110 (P::set_single(lhs) * P::set_single(rhs)).get(0)
111}
112
113#[inline]
114pub(super) fn square_using_packed<P: PackedField>(value: P::Scalar) -> P::Scalar {
115 P::set_single(value).square().get(0)
116}
117
118#[inline]
119pub(super) fn invert_or_zero_using_packed<P: PackedField>(value: P::Scalar) -> P::Scalar {
120 P::set_single(value).invert_or_zero().get(0)
121}
122
123#[inline]
124pub(super) fn mul_alpha_using_packed<P: PackedField + MulAlpha>(value: P::Scalar) -> P::Scalar {
125 P::set_single(value).mul_alpha().get(0)
126}
127
128macro_rules! mul_alpha_as_repacked {
132 ($val:ident, $source_type:ty, $smaller_type:ty) => {{
133 use $crate::as_packed_field::AsPackedField;
134
135 let repacked_value = <$source_type as AsPackedField<$smaller_type>>::to_packed($val);
136 <$source_type as AsPackedField<$smaller_type>>::from_packed(
137 $crate::arithmetic_traits::MulAlpha::mul_alpha(repacked_value),
138 )
139 }};
140}
141
142pub(super) use mul_alpha_as_repacked;
143
144macro_rules! impl_mul_primitive {
145 ($name:ty, $(mul_by $height_0:literal => $expr:expr,)* $(repack $height_1:literal => $subtype:ty,)*) => {
146 impl $crate::binary_field::MulPrimitive for $name {
147 #[inline]
148 fn mul_primitive(self, iota: usize) -> Result<Self, $crate::Error> {
149 match iota {
150 $($height_0 => Ok(self * $expr),)*
151 $($height_1 => {
152 let result = $crate::binary_field_arithmetic::mul_alpha_as_repacked!(self, $name, $subtype);
153 Ok(result)
154 },)*
155 _ => Err($crate::Error::ExtensionDegreeMismatch),
156 }
157 }
158 }
159 };
160}
161
162pub(super) use impl_mul_primitive;
163
164impl_mul_primitive!(BinaryField2b,
165 repack 0 => BinaryField2b,
166);
167impl_mul_primitive!(BinaryField4b,
168 repack 0 => BinaryField2b,
169 repack 1 => BinaryField4b,
170);
171impl_mul_primitive!(BinaryField8b,
172 repack 0 => BinaryField2b,
173 repack 1 => BinaryField4b,
174 repack 2 => BinaryField8b,
175);
176impl_mul_primitive!(BinaryField16b,
177 repack 0 => BinaryField2b,
178 repack 1 => BinaryField4b,
179 repack 2 => BinaryField8b,
180 repack 3 => BinaryField16b,
181);
182impl_mul_primitive!(BinaryField32b,
183 repack 0 => BinaryField2b,
184 repack 1 => BinaryField4b,
185 repack 2 => BinaryField8b,
186 repack 3 => BinaryField16b,
187 repack 4 => BinaryField32b,
188);
189impl_mul_primitive!(BinaryField64b,
190 repack 0 => BinaryField2b,
191 repack 1 => BinaryField4b,
192 repack 2 => BinaryField8b,
193 repack 3 => BinaryField16b,
194 repack 4 => BinaryField32b,
195 repack 5 => BinaryField64b,
196);
197impl_mul_primitive!(BinaryField128b,
198 repack 0 => BinaryField2b,
199 repack 1 => BinaryField4b,
200 repack 2 => BinaryField8b,
201 repack 3 => BinaryField16b,
202 repack 4 => BinaryField32b,
203 repack 5 => BinaryField64b,
204 repack 6 => BinaryField128b,
205);