halo2curves/bls12381/
fq12.rs

1use super::{fq::Fq, fq2::Fq2, fq6::Fq6};
2use crate::ff_ext::{
3    quadratic::{QuadExtField, QuadExtFieldArith, QuadSparseMul},
4    ExtField,
5};
6
7pub type Fq12 = QuadExtField<Fq6>;
8
9impl QuadExtFieldArith for Fq12 {
10    type Base = Fq6;
11}
12
13impl QuadSparseMul for Fq12 {
14    type Base = Fq2;
15}
16
17impl ExtField for Fq12 {
18    const NON_RESIDUE: Self = Fq12::zero(); // no needs
19
20    fn frobenius_map(&mut self, power: usize) {
21        self.c0.frobenius_map(power);
22        self.c1.frobenius_map(power);
23        self.c1.c0.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
24        self.c1.c1.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
25        self.c1.c2.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
26    }
27}
28
29crate::impl_binops_additive!(Fq12, Fq12);
30crate::impl_binops_multiplicative!(Fq12, Fq12);
31crate::impl_binops_calls!(Fq12);
32crate::impl_sum_prod!(Fq12);
33crate::impl_cyclotomic_square!(Fq2, Fq12);
34
35pub const FROBENIUS_COEFF_FQ12_C1: [Fq2; 12] = [
36    // z = u + 1
37    // z ^ ((p ^ 0 - 1) / 6)
38    Fq2 {
39        c0: Fq([
40            0x760900000002fffd,
41            0xebf4000bc40c0002,
42            0x5f48985753c758ba,
43            0x77ce585370525745,
44            0x5c071a97a256ec6d,
45            0x15f65ec3fa80e493,
46        ]),
47        c1: Fq([
48            0x0000000000000000,
49            0x0000000000000000,
50            0x0000000000000000,
51            0x0000000000000000,
52            0x0000000000000000,
53            0x0000000000000000,
54        ]),
55    },
56    // z ^ ((p ^ 1 - 1) / 6)
57    Fq2 {
58        c0: Fq([
59            0x07089552b319d465,
60            0xc6695f92b50a8313,
61            0x97e83cccd117228f,
62            0xa35baecab2dc29ee,
63            0x1ce393ea5daace4d,
64            0x08f2220fb0fb66eb,
65        ]),
66        c1: Fq([
67            0xb2f66aad4ce5d646,
68            0x5842a06bfc497cec,
69            0xcf4895d42599d394,
70            0xc11b9cba40a8e8d0,
71            0x2e3813cbe5a0de89,
72            0x110eefda88847faf,
73        ]),
74    },
75    // z ^ ((p ^ 2 - 1) / 6)
76    Fq2 {
77        c0: Fq([
78            0xecfb361b798dba3a,
79            0xc100ddb891865a2c,
80            0x0ec08ff1232bda8e,
81            0xd5c13cc6f1ca4721,
82            0x47222a47bf7b5c04,
83            0x0110f184e51c5f59,
84        ]),
85        c1: Fq([
86            0x0000000000000000,
87            0x0000000000000000,
88            0x0000000000000000,
89            0x0000000000000000,
90            0x0000000000000000,
91            0x0000000000000000,
92        ]),
93    },
94    // z ^ ((p ^ 3 - 1) / 6)
95    Fq2 {
96        c0: Fq([
97            0x3e2f585da55c9ad1,
98            0x4294213d86c18183,
99            0x382844c88b623732,
100            0x92ad2afd19103e18,
101            0x1d794e4fac7cf0b9,
102            0x0bd592fc7d825ec8,
103        ]),
104        c1: Fq([
105            0x7bcfa7a25aa30fda,
106            0xdc17dec12a927e7c,
107            0x2f088dd86b4ebef1,
108            0xd1ca2087da74d4a7,
109            0x2da2596696cebc1d,
110            0x0e2b7eedbbfd87d2,
111        ]),
112    },
113    // z ^ ((p ^ 4 - 1) / 6)
114    Fq2 {
115        c0: Fq([
116            0x30f1361b798a64e8,
117            0xf3b8ddab7ece5a2a,
118            0x16a8ca3ac61577f7,
119            0xc26a2ff874fd029b,
120            0x3636b76660701c6e,
121            0x051ba4ab241b6160,
122        ]),
123        c1: Fq([
124            0x0000000000000000,
125            0x0000000000000000,
126            0x0000000000000000,
127            0x0000000000000000,
128            0x0000000000000000,
129            0x0000000000000000,
130        ]),
131    },
132    // z ^ ((p ^ 5 - 1) / 6)
133    Fq2 {
134        c0: Fq([
135            0x3726c30af242c66c,
136            0x7c2ac1aad1b6fe70,
137            0xa04007fbba4b14a2,
138            0xef517c3266341429,
139            0x0095ba654ed2226b,
140            0x02e370eccc86f7dd,
141        ]),
142        c1: Fq([
143            0x82d83cf50dbce43f,
144            0xa2813e53df9d018f,
145            0xc6f0caa53c65e181,
146            0x7525cf528d50fe95,
147            0x4a85ed50f4798a6b,
148            0x171da0fd6cf8eebd,
149        ]),
150    },
151    // z ^ ((p ^ 6 - 1) / 6)
152    Fq2 {
153        c0: Fq([
154            0x43f5fffffffcaaae,
155            0x32b7fff2ed47fffd,
156            0x07e83a49a2e99d69,
157            0xeca8f3318332bb7a,
158            0xef148d1ea0f4c069,
159            0x040ab3263eff0206,
160        ]),
161        c1: Fq([
162            0x0000000000000000,
163            0x0000000000000000,
164            0x0000000000000000,
165            0x0000000000000000,
166            0x0000000000000000,
167            0x0000000000000000,
168        ]),
169    },
170    // z ^ ((p ^ 7 - 1) / 6)
171    Fq2 {
172        c0: Fq([
173            0xb2f66aad4ce5d646,
174            0x5842a06bfc497cec,
175            0xcf4895d42599d394,
176            0xc11b9cba40a8e8d0,
177            0x2e3813cbe5a0de89,
178            0x110eefda88847faf,
179        ]),
180        c1: Fq([
181            0x07089552b319d465,
182            0xc6695f92b50a8313,
183            0x97e83cccd117228f,
184            0xa35baecab2dc29ee,
185            0x1ce393ea5daace4d,
186            0x08f2220fb0fb66eb,
187        ]),
188    },
189    // z ^ ((p ^ 8 - 1) / 6)
190    Fq2 {
191        c0: Fq([
192            0xcd03c9e48671f071,
193            0x5dab22461fcda5d2,
194            0x587042afd3851b95,
195            0x8eb60ebe01bacb9e,
196            0x03f97d6e83d050d2,
197            0x18f0206554638741,
198        ]),
199        c1: Fq([
200            0x0000000000000000,
201            0x0000000000000000,
202            0x0000000000000000,
203            0x0000000000000000,
204            0x0000000000000000,
205            0x0000000000000000,
206        ]),
207    },
208    // z ^ ((p ^ 9 - 1) / 6)
209    Fq2 {
210        c0: Fq([
211            0x7bcfa7a25aa30fda,
212            0xdc17dec12a927e7c,
213            0x2f088dd86b4ebef1,
214            0xd1ca2087da74d4a7,
215            0x2da2596696cebc1d,
216            0x0e2b7eedbbfd87d2,
217        ]),
218        c1: Fq([
219            0x3e2f585da55c9ad1,
220            0x4294213d86c18183,
221            0x382844c88b623732,
222            0x92ad2afd19103e18,
223            0x1d794e4fac7cf0b9,
224            0x0bd592fc7d825ec8,
225        ]),
226    },
227    // z ^ ((p ^ 10 - 1) / 6)
228    Fq2 {
229        c0: Fq([
230            0x890dc9e4867545c3,
231            0x2af322533285a5d5,
232            0x50880866309b7e2c,
233            0xa20d1b8c7e881024,
234            0x14e4f04fe2db9068,
235            0x14e56d3f1564853a,
236        ]),
237        c1: Fq([
238            0x0000000000000000,
239            0x0000000000000000,
240            0x0000000000000000,
241            0x0000000000000000,
242            0x0000000000000000,
243            0x0000000000000000,
244        ]),
245    },
246    // z ^ ((p ^ 11 - 1) / 6)
247    Fq2 {
248        c0: Fq([
249            0x82d83cf50dbce43f,
250            0xa2813e53df9d018f,
251            0xc6f0caa53c65e181,
252            0x7525cf528d50fe95,
253            0x4a85ed50f4798a6b,
254            0x171da0fd6cf8eebd,
255        ]),
256        c1: Fq([
257            0x3726c30af242c66c,
258            0x7c2ac1aad1b6fe70,
259            0xa04007fbba4b14a2,
260            0xef517c3266341429,
261            0x0095ba654ed2226b,
262            0x02e370eccc86f7dd,
263        ]),
264    },
265];
266
267#[cfg(test)]
268mod test {
269    macro_rules! test_fq12 {
270        ($test:ident, $size: expr) => {
271            paste::paste! {
272            #[test]
273            fn [< $test test >]() {
274                use rand::SeedableRng;
275                use rand_xorshift::XorShiftRng;
276                let mut rng = XorShiftRng::from_seed(crate::tests::SEED);
277                crate::bls12381::fq12::test::$test(&mut rng, $size);
278            }
279            }
280        };
281    }
282    use ff::Field;
283    use rand::RngCore;
284
285    use super::*;
286    use crate::{arith_test, frobenius_test, setup_f12_test_funcs, test};
287
288    arith_test!(Fq12);
289    // TODO Compile problems with derive_serde feature
290    // serde_test!(fq12);
291
292    // F12 specific
293    setup_f12_test_funcs!(Fq12, Fq6, Fq2);
294    test_fq12!(f12_mul_by_014_, 500);
295    test_fq12!(f12_mul_by_034_, 500);
296    frobenius_test!(Fq12, Fq, 8);
297}