Skip to main content

p3_mersenne_31/
extension.rs

1use p3_field::extension::{
2    Binomial, BinomiallyExtendable, Complex, ExtensionAlgebra, HasComplexBinomialExtension,
3    HasTwoAdicComplexBinomialExtension, binomial_mul,
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
16impl BinomiallyExtendable<3> for Mersenne31 {
17    // ```sage
18    // p = 2^31 - 1
19    // F = GF(p)
20    // R.<x> = F[]
21    // assert (x^3 - 5).is_irreducible()
22    // ```
23    const W: Self = Self::new(5);
24
25    // ```sage
26    // F(5)^((p-1)/3)
27    // ```
28    const DTH_ROOT: Self = Self::new(1513477735);
29
30    // ```sage
31    // F.extension(x^3 - 5, 'u').multiplicative_generator()
32    // ```
33    const EXT_GENERATOR: [Self; 3] = [Self::new(10), Self::ONE, Self::ZERO];
34}
35
36impl HasComplexBinomialExtension<2> for Mersenne31 {
37    // Verifiable in Sage with
38    // ```sage
39    // p = 2**31 - 1  # Mersenne31
40    // F = GF(p)  # The base field GF(p)
41    // R.<x> = F[]  # The polynomial ring over F
42    // K.<i> = F.extension(x^2 + 1)  # The complex extension field
43    // R2.<y> = K[]
44    // f2 = y^2 - i - 2
45    // assert f2.is_irreducible()
46    // ```
47    const W: Complex<Self> = Complex::new_complex(Self::TWO, Self::ONE);
48
49    // DTH_ROOT = W^((p^2 - 1)/2).
50    const DTH_ROOT: Complex<Self> = Complex::new_real(Self::new(2147483646));
51
52    // Verifiable in Sage with
53    // ```sage
54    // K2.<j> = K.extension(f2)
55    //  g = j + 6
56    // for f in factor(p^4 - 1):
57    //   assert g^((p^4-1) // f) != 1
58    // ```
59    const EXT_GENERATOR: [Complex<Self>; 2] = [Complex::new_real(Self::new(6)), Complex::ONE];
60}
61
62impl HasTwoAdicComplexBinomialExtension<2> for Mersenne31 {
63    const COMPLEX_EXT_TWO_ADICITY: usize = 33;
64
65    fn complex_ext_two_adic_generator(bits: usize) -> [Complex<Self>; 2] {
66        assert!(bits <= 33);
67        if bits == 33 {
68            [
69                Complex::ZERO,
70                Complex::new_complex(Self::new_reduced(1437746044), Self::new_reduced(946469285)),
71            ]
72        } else {
73            [Complex::two_adic_generator(bits), Complex::ZERO]
74        }
75    }
76}
77
78impl HasComplexBinomialExtension<3> for Mersenne31 {
79    // Verifiable in Sage with
80    // ```sage
81    // p = 2**31 - 1  # Mersenne31
82    // F = GF(p)  # The base field GF(p)
83    // R.<x> = F[]  # The polynomial ring over F
84    // K.<i> = F.extension(x^2 + 1)  # The complex extension field
85    // R2.<y> = K[]
86    // f2 = y^3 - 5*i
87    // assert f2.is_irreducible()
88    // ```
89    const W: Complex<Self> = Complex::new_imag(Self::new(5));
90
91    // DTH_ROOT = W^((p^2 - 1)/2).
92    const DTH_ROOT: Complex<Self> = Complex::new_real(Self::new(634005911));
93
94    // Verifiable in Sage with
95    // ```sage
96    // K2.<j> = K.extension(f2)
97    //  g = j + 5
98    // for f in factor(p^6 - 1):
99    //   assert g^((p^6-1) // f) != 1
100    // ```
101    const EXT_GENERATOR: [Complex<Self>; 3] = [
102        Complex::new_real(Self::new(5)),
103        Complex::new_real(Self::ONE),
104        Complex::ZERO,
105    ];
106}
107
108impl HasTwoAdicComplexBinomialExtension<3> for Mersenne31 {
109    const COMPLEX_EXT_TWO_ADICITY: usize = 32;
110
111    fn complex_ext_two_adic_generator(bits: usize) -> [Complex<Self>; 3] {
112        field_to_array(Complex::two_adic_generator(bits))
113    }
114}
115
116#[cfg(test)]
117mod test_cubic_extension {
118    use num_bigint::BigUint;
119    use p3_field::extension::BinomialExtensionField;
120    use p3_field::{ExtensionField, PrimeCharacteristicRing};
121    use p3_field_testing::{test_extension_field, test_field, test_packed_extension_field};
122
123    use crate::Mersenne31;
124
125    type F = Mersenne31;
126    type EF = BinomialExtensionField<F, 3>;
127
128    // There is a redundant representation of zero but we already tested it
129    // when testing the base field.
130    const ZEROS: [EF; 1] = [EF::ZERO];
131    const ONES: [EF; 1] = [EF::ONE];
132
133    // Get the prime factorization of the order of the multiplicative group.
134    // i.e. the prime factorization of P^3 - 1.
135    fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 9] {
136        [
137            (BigUint::from(2u8), 1),
138            (BigUint::from(3u8), 3),
139            (BigUint::from(7u8), 1),
140            (BigUint::from(11u8), 1),
141            (BigUint::from(31u8), 1),
142            (BigUint::from(151u8), 1),
143            (BigUint::from(331u16), 1),
144            (BigUint::from(529510939u32), 1),
145            (BigUint::from(2903110321u32), 1),
146        ]
147    }
148
149    test_extension_field!(super::F, super::EF);
150
151    test_field!(
152        super::EF,
153        &super::ZEROS,
154        &super::ONES,
155        &super::multiplicative_group_prime_factorization()
156    );
157
158    type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
159    const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
160    const PACKED_ONES: [Pef; 1] = [Pef::ONE];
161    test_packed_extension_field!(
162        super::F,
163        super::EF,
164        super::Pef,
165        &super::PACKED_ZEROS,
166        &super::PACKED_ONES
167    );
168    p3_field_testing::test_packed_binomial_extension_division!(F, 3);
169}
170
171#[cfg(test)]
172mod test_cubic_complex_extension {
173    use num_bigint::BigUint;
174    use p3_field::extension::{BinomialExtensionField, Complex};
175    use p3_field::{ExtensionField, PrimeCharacteristicRing};
176    use p3_field_testing::{
177        test_extension_field, test_field, test_packed_extension_field,
178        test_two_adic_extension_field,
179    };
180
181    use crate::Mersenne31;
182
183    type F = Complex<Mersenne31>;
184    type EF = BinomialExtensionField<F, 3>;
185
186    // There is a redundant representation of zero but we already tested it
187    // when testing the base field.
188    const ZEROS: [EF; 1] = [EF::ZERO];
189    const ONES: [EF; 1] = [EF::ONE];
190
191    // Get the prime factorization of the order of the multiplicative group.
192    // i.e. the prime factorization of P^6 - 1.
193    fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 14] {
194        [
195            (BigUint::from(2u8), 32),
196            (BigUint::from(3u8), 3),
197            (BigUint::from(7u8), 1),
198            (BigUint::from(11u8), 1),
199            (BigUint::from(13u8), 1),
200            (BigUint::from(31u8), 1),
201            (BigUint::from(43u8), 2),
202            (BigUint::from(79u8), 1),
203            (BigUint::from(151u8), 1),
204            (BigUint::from(331u16), 1),
205            (BigUint::from(1381u16), 1),
206            (BigUint::from(529510939u32), 1),
207            (BigUint::from(1758566101u32), 1),
208            (BigUint::from(2903110321u32), 1),
209        ]
210    }
211
212    test_field!(
213        super::EF,
214        &super::ZEROS,
215        &super::ONES,
216        &super::multiplicative_group_prime_factorization()
217    );
218
219    test_extension_field!(super::F, super::EF);
220
221    test_two_adic_extension_field!(super::F, super::EF);
222
223    type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
224    const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
225    const PACKED_ONES: [Pef; 1] = [Pef::ONE];
226    test_packed_extension_field!(
227        super::F,
228        super::EF,
229        super::Pef,
230        &super::PACKED_ZEROS,
231        &super::PACKED_ONES
232    );
233    p3_field_testing::test_packed_binomial_extension_division!(F, 3);
234}
235
236#[cfg(test)]
237mod test_quadratic_complex_extension {
238
239    use num_bigint::BigUint;
240    use p3_field::extension::{BinomialExtensionField, Complex};
241    use p3_field::{ExtensionField, PrimeCharacteristicRing};
242    use p3_field_testing::{
243        test_extension_field, test_field, test_packed_extension_field,
244        test_two_adic_extension_field,
245    };
246
247    use crate::Mersenne31;
248
249    type F = Complex<Mersenne31>;
250    type EF = BinomialExtensionField<F, 2>;
251
252    // There is a redundant representation of zero but we already tested it
253    // when testing the base field.
254    const ZEROS: [EF; 1] = [EF::ZERO];
255    const ONES: [EF; 1] = [EF::ONE];
256
257    // Get the prime factorization of the order of the multiplicative group.
258    // i.e. the prime factorization of P^4 - 1.
259    fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 11] {
260        [
261            (BigUint::from(2u8), 33),
262            (BigUint::from(3u8), 2),
263            (BigUint::from(5u8), 1),
264            (BigUint::from(7u8), 1),
265            (BigUint::from(11u8), 1),
266            (BigUint::from(31u8), 1),
267            (BigUint::from(151u8), 1),
268            (BigUint::from(331u16), 1),
269            (BigUint::from(733u16), 1),
270            (BigUint::from(1709u16), 1),
271            (BigUint::from(368140581013u64), 1),
272        ]
273    }
274
275    test_field!(
276        super::EF,
277        &super::ZEROS,
278        &super::ONES,
279        &super::multiplicative_group_prime_factorization()
280    );
281
282    test_extension_field!(super::F, super::EF);
283
284    test_two_adic_extension_field!(super::F, super::EF);
285
286    type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
287    const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
288    const PACKED_ONES: [Pef; 1] = [Pef::ONE];
289    test_packed_extension_field!(
290        super::F,
291        super::EF,
292        super::Pef,
293        &super::PACKED_ZEROS,
294        &super::PACKED_ONES
295    );
296    p3_field_testing::test_packed_binomial_extension_division!(F, 2);
297}