1use p3_field::extension::{
2 Binomial, BinomiallyExtendable, CubicTrinomial, CubicTrinomialExtendable, ExtensionAlgebra,
3 HasTwoAdicBinomialExtension, HasTwoAdicCubicExtension, binomial_mul, cubic_square,
4 trinomial_cubic_mul,
5};
6use p3_field::{PrimeCharacteristicRing, TwoAdicField, field_to_array};
7
8use crate::Goldilocks;
9
10impl ExtensionAlgebra<Self, 2, Binomial<Self>> for Goldilocks {
11 #[inline]
12 fn ext_mul(a: &[Self; 2], b: &[Self; 2], res: &mut [Self; 2]) {
13 binomial_mul::<Self, Self, Self, 2>(a, b, res, <Self as BinomiallyExtendable<2>>::W);
14 }
15}
16
17impl BinomiallyExtendable<2> for Goldilocks {
18 const W: Self = Self::new(7);
21
22 const DTH_ROOT: Self = Self::new(18446744069414584320);
24
25 const EXT_GENERATOR: [Self; 2] = [
26 Self::new(18081566051660590251),
27 Self::new(16121475356294670766),
28 ];
29}
30
31impl HasTwoAdicBinomialExtension<2> for Goldilocks {
32 const EXT_TWO_ADICITY: usize = 33;
33
34 fn ext_two_adic_generator(bits: usize) -> [Self; 2] {
35 assert!(bits <= 33);
36
37 if bits == 33 {
38 [Self::ZERO, Self::new(15659105665374529263)]
39 } else {
40 [Self::two_adic_generator(bits), Self::ZERO]
41 }
42 }
43}
44
45impl ExtensionAlgebra<Self, 3, CubicTrinomial> for Goldilocks {
46 #[inline]
47 fn ext_mul(a: &[Self; 3], b: &[Self; 3], res: &mut [Self; 3]) {
48 trinomial_cubic_mul::<Self>(a, b, res);
49 }
50
51 #[inline]
52 fn ext_square(a: &[Self; 3], res: &mut [Self; 3]) {
53 cubic_square::<Self>(a, res);
54 }
55}
56
57impl CubicTrinomialExtendable for Goldilocks {
58 const FROBENIUS_MATRIX: [[Self; 3]; 3] = [
65 [
66 Self::ONE,
67 Self::new(10615703402128488253),
68 Self::new(6700183068485440220),
69 ],
70 [
71 Self::ZERO,
72 Self::new(10050274602728160328),
73 Self::new(14531223735771536287),
74 ],
75 [
76 Self::ZERO,
77 Self::new(11746561000929144102),
78 Self::new(8396469466686423992),
79 ],
80 ];
81
82 const EXT_GENERATOR: [Self; 3] = [Self::TWO, Self::ONE, Self::ZERO];
93}
94
95impl HasTwoAdicCubicExtension for Goldilocks {
96 const EXT_TWO_ADICITY: usize = 32;
97
98 fn ext_two_adic_generator(bits: usize) -> [Self; 3] {
99 assert!(bits <= 32);
100
101 field_to_array(Self::two_adic_generator(bits))
102 }
103}
104
105impl ExtensionAlgebra<Self, 5, Binomial<Self>> for Goldilocks {
106 #[inline]
107 fn ext_mul(a: &[Self; 5], b: &[Self; 5], res: &mut [Self; 5]) {
108 binomial_mul::<Self, Self, Self, 5>(a, b, res, <Self as BinomiallyExtendable<5>>::W);
109 }
110}
111
112impl BinomiallyExtendable<5> for Goldilocks {
113 const W: Self = Self::new(3);
126
127 const DTH_ROOT: Self = Self::new(1041288259238279555);
129
130 const EXT_GENERATOR: [Self; 5] = [Self::TWO, Self::ONE, Self::ZERO, Self::ZERO, Self::ZERO];
134}
135
136impl HasTwoAdicBinomialExtension<5> for Goldilocks {
137 const EXT_TWO_ADICITY: usize = 32;
138
139 fn ext_two_adic_generator(bits: usize) -> [Self; 5] {
140 assert!(bits <= 32);
141
142 field_to_array(Self::two_adic_generator(bits))
143 }
144}
145
146#[cfg(test)]
147mod test_quadratic_extension {
148
149 use num_bigint::BigUint;
150 use p3_field::extension::BinomialExtensionField;
151 use p3_field::{ExtensionField, PrimeCharacteristicRing};
152 use p3_field_testing::{
153 test_extension_field, test_field, test_packed_extension_field,
154 test_two_adic_extension_field,
155 };
156
157 use crate::Goldilocks;
158
159 type F = Goldilocks;
160 type EF = BinomialExtensionField<F, 2>;
161
162 const ZEROS: [EF; 1] = [EF::ZERO];
165 const ONES: [EF; 1] = [EF::ONE];
166
167 fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 9] {
170 [
171 (BigUint::from(2u8), 33),
172 (BigUint::from(3u8), 1),
173 (BigUint::from(5u8), 1),
174 (BigUint::from(7u8), 1),
175 (BigUint::from(17u8), 1),
176 (BigUint::from(179u8), 1),
177 (BigUint::from(257u16), 1),
178 (BigUint::from(65537u32), 1),
179 (BigUint::from(7361031152998637u64), 1),
180 ]
181 }
182
183 test_field!(
184 super::EF,
185 &super::ZEROS,
186 &super::ONES,
187 &super::multiplicative_group_prime_factorization()
188 );
189
190 test_extension_field!(super::F, super::EF);
191 test_two_adic_extension_field!(super::F, super::EF);
192
193 type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
194 const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
195 const PACKED_ONES: [Pef; 1] = [Pef::ONE];
196 test_packed_extension_field!(
197 super::F,
198 super::EF,
199 super::Pef,
200 &super::PACKED_ZEROS,
201 &super::PACKED_ONES
202 );
203 p3_field_testing::test_packed_binomial_extension_division!(F, 2);
204}
205
206#[cfg(test)]
207mod test_cubic_trinomial_extension {
208
209 use num_bigint::BigUint;
210 use p3_field::extension::CubicTrinomialExtensionField;
211 use p3_field::{ExtensionField, PrimeCharacteristicRing};
212 use p3_field_testing::{
213 test_extension_field, test_field, test_frobenius, test_packed_extension_field,
214 test_two_adic_extension_field,
215 };
216
217 use crate::Goldilocks;
218
219 type F = Goldilocks;
220 type EF = CubicTrinomialExtensionField<F>;
221
222 const ZEROS: [EF; 1] = [EF::ZERO];
223 const ONES: [EF; 1] = [EF::ONE];
224
225 fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 9] {
226 [
227 (BigUint::from(2u8), 32),
228 (BigUint::from(3u8), 2),
229 (BigUint::from(5u8), 1),
230 (BigUint::from(17u8), 1),
231 (BigUint::from(257u16), 1),
232 (BigUint::from(937u16), 1),
233 (BigUint::from(65537u32), 1),
234 (BigUint::from(724723u32), 1),
235 (BigUint::from(167034643597991036904547663171u128), 1),
236 ]
237 }
238
239 #[test]
241 fn test_defining_relation() {
242 let x = EF::new([F::ZERO, F::ONE, F::ZERO]);
243 let x_cubed = x * x * x;
244 let x_plus_one = x + EF::ONE;
245 assert_eq!(x_cubed, x_plus_one, "X^3 should equal X + 1");
246 }
247
248 test_field!(
249 super::EF,
250 &super::ZEROS,
251 &super::ONES,
252 &super::multiplicative_group_prime_factorization()
253 );
254
255 test_extension_field!(super::F, super::EF);
256 test_two_adic_extension_field!(super::F, super::EF);
257 test_frobenius!(super::F, super::EF);
258
259 type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
260 const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
261 const PACKED_ONES: [Pef; 1] = [Pef::ONE];
262 test_packed_extension_field!(
263 super::F,
264 super::EF,
265 super::Pef,
266 &super::PACKED_ZEROS,
267 &super::PACKED_ONES
268 );
269}
270
271#[cfg(test)]
272mod test_quintic_extension {
273
274 use num_bigint::BigUint;
275 use p3_field::extension::BinomialExtensionField;
276 use p3_field::{ExtensionField, PrimeCharacteristicRing};
277 use p3_field_testing::{
278 test_extension_field, test_field, test_packed_extension_field,
279 test_two_adic_extension_field,
280 };
281
282 use crate::Goldilocks;
283
284 type F = Goldilocks;
285 type EF = BinomialExtensionField<F, 5>;
286
287 const ZEROS: [EF; 1] = [EF::ZERO];
290 const ONES: [EF; 1] = [EF::ONE];
291
292 fn multiplicative_group_prime_factorization() -> [(num_bigint::BigUint, u32); 10] {
295 [
296 (BigUint::from(2u8), 32),
297 (BigUint::from(3u8), 1),
298 (BigUint::from(5u8), 2),
299 (BigUint::from(17u8), 1),
300 (BigUint::from(257u16), 1),
301 (BigUint::from(45971u16), 1),
302 (BigUint::from(65537u32), 1),
303 (BigUint::from(255006435240067831u64), 1),
304 (BigUint::from(280083648770327405561u128), 1),
305 (BigUint::from(7053197395277272939628824863222181u128), 1),
306 ]
307 }
308
309 test_field!(
310 super::EF,
311 &super::ZEROS,
312 &super::ONES,
313 &super::multiplicative_group_prime_factorization()
314 );
315
316 test_extension_field!(super::F, super::EF);
317 test_two_adic_extension_field!(super::F, super::EF);
318
319 type Pef = <EF as ExtensionField<F>>::ExtensionPacking;
320 const PACKED_ZEROS: [Pef; 1] = [Pef::ZERO];
321 const PACKED_ONES: [Pef; 1] = [Pef::ONE];
322 test_packed_extension_field!(
323 super::F,
324 super::EF,
325 super::Pef,
326 &super::PACKED_ZEROS,
327 &super::PACKED_ONES
328 );
329 p3_field_testing::test_packed_binomial_extension_division!(F, 5);
330}