1use p3_field::extension::{
2 Binomial, BinomiallyExtendable, Complex, ExtensionAlgebra, HasComplexBinomialExtension,
3 HasTwoAdicComplexBinomialExtension, binomial_mul, binomial_square,
4};
5use p3_field::{PrimeCharacteristicRing, TwoAdicField, field_to_array};
6
7use crate::Mersenne31;
8
9impl ExtensionAlgebra<Self, 3, Binomial<Self>> for Mersenne31 {
10 #[inline]
11 fn ext_mul(a: &[Self; 3], b: &[Self; 3], res: &mut [Self; 3]) {
12 binomial_mul::<Self, Self, Self, 3>(a, b, res, <Self as BinomiallyExtendable<3>>::W);
13 }
14
15 #[inline]
16 fn ext_square(a: &[Self; 3], res: &mut [Self; 3]) {
17 binomial_square::<Self, Self, 3>(a, res, <Self as BinomiallyExtendable<3>>::W);
18 }
19}
20
21impl BinomiallyExtendable<3> for Mersenne31 {
22 const W: Self = Self::new(5);
29
30 const DTH_ROOT: Self = Self::new(1513477735);
34
35 const EXT_GENERATOR: [Self; 3] = [Self::new(10), Self::ONE, Self::ZERO];
39}
40
41impl HasComplexBinomialExtension<2> for Mersenne31 {
42 const W: Complex<Self> = Complex::new_complex(Self::TWO, Self::ONE);
53
54 const DTH_ROOT: Complex<Self> = Complex::new_real(Self::new(2147483646));
56
57 const EXT_GENERATOR: [Complex<Self>; 2] = [Complex::new_real(Self::new(6)), Complex::ONE];
65
66 #[inline(always)]
69 fn mul_by_w(z: Complex<Self>) -> Complex<Self> {
70 let re = z.real();
71 let im = z.imag();
72 Complex::new_complex(re + re - im, re + im + im)
73 }
74}
75
76impl HasTwoAdicComplexBinomialExtension<2> for Mersenne31 {
77 const COMPLEX_EXT_TWO_ADICITY: usize = 33;
78
79 fn complex_ext_two_adic_generator(bits: usize) -> [Complex<Self>; 2] {
80 assert!(bits <= 33);
81 if bits == 33 {
82 [
83 Complex::ZERO,
84 Complex::new_complex(Self::new_reduced(1437746044), Self::new_reduced(946469285)),
85 ]
86 } else {
87 [Complex::two_adic_generator(bits), Complex::ZERO]
88 }
89 }
90}
91
92impl HasComplexBinomialExtension<3> for Mersenne31 {
93 const W: Complex<Self> = Complex::new_imag(Self::new(5));
104
105 const DTH_ROOT: Complex<Self> = Complex::new_real(Self::new(634005911));
107
108 const EXT_GENERATOR: [Complex<Self>; 3] = [
116 Complex::new_real(Self::new(5)),
117 Complex::new_real(Self::ONE),
118 Complex::ZERO,
119 ];
120}
121
122impl HasTwoAdicComplexBinomialExtension<3> for Mersenne31 {
123 const COMPLEX_EXT_TWO_ADICITY: usize = 32;
124
125 fn complex_ext_two_adic_generator(bits: usize) -> [Complex<Self>; 3] {
126 field_to_array(Complex::two_adic_generator(bits))
127 }
128}
129
130#[cfg(test)]
131mod test_cubic_extension {
132 use num_bigint::BigUint;
133 use p3_field::extension::BinomialExtensionField;
134 use p3_field::{ExtensionField, PrimeCharacteristicRing};
135 use p3_field_testing::{test_extension_field, test_field, test_packed_extension_field};
136
137 use crate::Mersenne31;
138
139 type F = Mersenne31;
140 type EF = BinomialExtensionField<F, 3>;
141
142 const ZEROS: [EF; 1] = [EF::ZERO];
145 const ONES: [EF; 1] = [EF::ONE];
146
147 fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 9] {
150 [
151 (BigUint::from(2u8), 1),
152 (BigUint::from(3u8), 3),
153 (BigUint::from(7u8), 1),
154 (BigUint::from(11u8), 1),
155 (BigUint::from(31u8), 1),
156 (BigUint::from(151u8), 1),
157 (BigUint::from(331u16), 1),
158 (BigUint::from(529510939u32), 1),
159 (BigUint::from(2903110321u32), 1),
160 ]
161 }
162
163 test_extension_field!(super::F, super::EF);
164
165 test_field!(
166 super::EF,
167 &super::ZEROS,
168 &super::ONES,
169 &super::multiplicative_group_prime_factorization()
170 );
171
172 type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
173 const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
174 const PACKED_ONES: [Pef; 1] = [Pef::ONE];
175 test_packed_extension_field!(
176 super::F,
177 super::EF,
178 super::Pef,
179 &super::PACKED_ZEROS,
180 &super::PACKED_ONES
181 );
182 p3_field_testing::test_packed_binomial_extension_division!(F, 3);
183}
184
185#[cfg(test)]
186mod test_cubic_complex_extension {
187 use num_bigint::BigUint;
188 use p3_field::extension::{BinomialExtensionField, Complex};
189 use p3_field::{ExtensionField, PrimeCharacteristicRing};
190 use p3_field_testing::{
191 test_extension_field, test_field, test_packed_extension_field,
192 test_two_adic_extension_field,
193 };
194
195 use crate::Mersenne31;
196
197 type F = Complex<Mersenne31>;
198 type EF = BinomialExtensionField<F, 3>;
199
200 const ZEROS: [EF; 1] = [EF::ZERO];
203 const ONES: [EF; 1] = [EF::ONE];
204
205 fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 14] {
208 [
209 (BigUint::from(2u8), 32),
210 (BigUint::from(3u8), 3),
211 (BigUint::from(7u8), 1),
212 (BigUint::from(11u8), 1),
213 (BigUint::from(13u8), 1),
214 (BigUint::from(31u8), 1),
215 (BigUint::from(43u8), 2),
216 (BigUint::from(79u8), 1),
217 (BigUint::from(151u8), 1),
218 (BigUint::from(331u16), 1),
219 (BigUint::from(1381u16), 1),
220 (BigUint::from(529510939u32), 1),
221 (BigUint::from(1758566101u32), 1),
222 (BigUint::from(2903110321u32), 1),
223 ]
224 }
225
226 test_field!(
227 super::EF,
228 &super::ZEROS,
229 &super::ONES,
230 &super::multiplicative_group_prime_factorization()
231 );
232
233 test_extension_field!(super::F, super::EF);
234
235 test_two_adic_extension_field!(super::F, super::EF);
236
237 type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
238 const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
239 const PACKED_ONES: [Pef; 1] = [Pef::ONE];
240 test_packed_extension_field!(
241 super::F,
242 super::EF,
243 super::Pef,
244 &super::PACKED_ZEROS,
245 &super::PACKED_ONES
246 );
247 p3_field_testing::test_packed_binomial_extension_division!(F, 3);
248}
249
250#[cfg(test)]
251mod test_quadratic_complex_extension {
252
253 use num_bigint::BigUint;
254 use p3_field::extension::{BinomialExtensionField, Complex};
255 use p3_field::{ExtensionField, PrimeCharacteristicRing};
256 use p3_field_testing::{
257 test_extension_field, test_field, test_packed_extension_field,
258 test_two_adic_extension_field,
259 };
260
261 use crate::Mersenne31;
262
263 type F = Complex<Mersenne31>;
264 type EF = BinomialExtensionField<F, 2>;
265
266 const ZEROS: [EF; 1] = [EF::ZERO];
269 const ONES: [EF; 1] = [EF::ONE];
270
271 fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 11] {
274 [
275 (BigUint::from(2u8), 33),
276 (BigUint::from(3u8), 2),
277 (BigUint::from(5u8), 1),
278 (BigUint::from(7u8), 1),
279 (BigUint::from(11u8), 1),
280 (BigUint::from(31u8), 1),
281 (BigUint::from(151u8), 1),
282 (BigUint::from(331u16), 1),
283 (BigUint::from(733u16), 1),
284 (BigUint::from(1709u16), 1),
285 (BigUint::from(368140581013u64), 1),
286 ]
287 }
288
289 test_field!(
290 super::EF,
291 &super::ZEROS,
292 &super::ONES,
293 &super::multiplicative_group_prime_factorization()
294 );
295
296 test_extension_field!(super::F, super::EF);
297
298 test_two_adic_extension_field!(super::F, super::EF);
299
300 type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
301 const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
302 const PACKED_ONES: [Pef; 1] = [Pef::ONE];
303 test_packed_extension_field!(
304 super::F,
305 super::EF,
306 super::Pef,
307 &super::PACKED_ZEROS,
308 &super::PACKED_ONES
309 );
310 p3_field_testing::test_packed_binomial_extension_division!(F, 2);
311}