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(); 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 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 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 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 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 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 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 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 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 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 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 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 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 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}