1 use std::ops::{Add, Sub, Mul};
2 use std::cmp::{Eq, PartialEq,min};
3 use util::{fixed_time_eq};
4 use step_by::RangeExt;
5 
6 /*
7 fe means field element.
8 Here the field is \Z/(2^255-19).
9 An element t, entries t[0]...t[9], represents the integer
10 t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
11 Bounds on each t[i] vary depending on context.
12 */
13 
14 #[derive(Clone, Copy)]
15 pub struct Fe(pub [i32; 10]);
16 
17 impl PartialEq for Fe {
eq(&self, other: &Fe) -> bool18     fn eq(&self, other: &Fe) -> bool {
19         let &Fe(self_elems) = self;
20         let &Fe(other_elems) = other;
21         self_elems.to_vec() == other_elems.to_vec()
22     }
23 }
24 impl Eq for Fe { }
25 
26 static FE_ZERO : Fe = Fe([0,0,0,0,0,0,0,0,0,0]);
27 static FE_ONE : Fe = Fe([1,0,0,0,0,0,0,0,0,0]);
28 static FE_SQRTM1 : Fe = Fe([-32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482]);
29 static FE_D : Fe = Fe([-10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116]);
30 static FE_D2 : Fe = Fe([-21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199]);
31 
32 
load_4u(s: &[u8]) -> u6433 fn load_4u(s: &[u8]) -> u64 {
34     (s[0] as u64)
35         | ((s[1] as u64)<<8)
36         | ((s[2] as u64)<<16)
37         | ((s[3] as u64)<<24)
38 }
load_4i(s: &[u8]) -> i6439 fn load_4i(s: &[u8]) -> i64 {
40     load_4u(s) as i64
41 }
load_3u(s: &[u8]) -> u6442 fn load_3u(s: &[u8]) -> u64 {
43     (s[0] as u64)
44         | ((s[1] as u64)<<8)
45         | ((s[2] as u64)<<16)
46 }
load_3i(s: &[u8]) -> i6447 fn load_3i(s: &[u8]) -> i64 {
48     load_3u(s) as i64
49 }
50 
51 impl Add for Fe {
52     type Output = Fe;
53 
54     /*
55     h = f + g
56     Can overlap h with f or g.
57 
58     Preconditions:
59        |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
60        |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
61 
62     Postconditions:
63        |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
64     */
add(self, _rhs: Fe) -> Fe65     fn add(self, _rhs: Fe) -> Fe {
66         let Fe(f) = self;
67         let Fe(g) = _rhs;
68 
69         let f0 = f[0];
70         let f1 = f[1];
71         let f2 = f[2];
72         let f3 = f[3];
73         let f4 = f[4];
74         let f5 = f[5];
75         let f6 = f[6];
76         let f7 = f[7];
77         let f8 = f[8];
78         let f9 = f[9];
79         let g0 = g[0];
80         let g1 = g[1];
81         let g2 = g[2];
82         let g3 = g[3];
83         let g4 = g[4];
84         let g5 = g[5];
85         let g6 = g[6];
86         let g7 = g[7];
87         let g8 = g[8];
88         let g9 = g[9];
89         let h0 = f0 + g0;
90         let h1 = f1 + g1;
91         let h2 = f2 + g2;
92         let h3 = f3 + g3;
93         let h4 = f4 + g4;
94         let h5 = f5 + g5;
95         let h6 = f6 + g6;
96         let h7 = f7 + g7;
97         let h8 = f8 + g8;
98         let h9 = f9 + g9;
99         Fe([h0, h1, h2, h3, h4, h5, h6, h7, h8, h9])
100     }
101 }
102 
103 impl Sub for Fe {
104     type Output = Fe;
105 
106     /*
107     h = f - g
108     Can overlap h with f or g.
109 
110     Preconditions:
111        |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
112        |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
113 
114     Postconditions:
115        |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
116     */
sub(self, _rhs: Fe) -> Fe117     fn sub(self, _rhs: Fe) -> Fe {
118         let Fe(f) = self;
119         let Fe(g) = _rhs;
120 
121         let f0 = f[0];
122         let f1 = f[1];
123         let f2 = f[2];
124         let f3 = f[3];
125         let f4 = f[4];
126         let f5 = f[5];
127         let f6 = f[6];
128         let f7 = f[7];
129         let f8 = f[8];
130         let f9 = f[9];
131         let g0 = g[0];
132         let g1 = g[1];
133         let g2 = g[2];
134         let g3 = g[3];
135         let g4 = g[4];
136         let g5 = g[5];
137         let g6 = g[6];
138         let g7 = g[7];
139         let g8 = g[8];
140         let g9 = g[9];
141         let h0 = f0 - g0;
142         let h1 = f1 - g1;
143         let h2 = f2 - g2;
144         let h3 = f3 - g3;
145         let h4 = f4 - g4;
146         let h5 = f5 - g5;
147         let h6 = f6 - g6;
148         let h7 = f7 - g7;
149         let h8 = f8 - g8;
150         let h9 = f9 - g9;
151         Fe([h0, h1, h2, h3, h4, h5, h6, h7, h8, h9])
152     }
153 }
154 
155 impl Mul for Fe {
156     type Output = Fe;
157 
158     /*
159     h = f * g
160     Can overlap h with f or g.
161 
162     Preconditions:
163        |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
164        |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
165 
166     Postconditions:
167        |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
168     */
169 
170     /*
171     Notes on implementation strategy:
172 
173     Using schoolbook multiplication.
174     Karatsuba would save a little in some cost models.
175 
176     Most multiplications by 2 and 19 are 32-bit precomputations;
177     cheaper than 64-bit postcomputations.
178 
179     There is one remaining multiplication by 19 in the carry chain;
180     one *19 precomputation can be merged into this,
181     but the resulting data flow is considerably less clean.
182 
183     There are 12 carries below.
184     10 of them are 2-way parallelizable and vectorizable.
185     Can get away with 11 carries, but then data flow is much deeper.
186 
187     With tighter constraints on inputs can squeeze carries into int32.
188     */
189 
mul(self, _rhs: Fe) -> Fe190     fn mul(self, _rhs: Fe) -> Fe {
191         let Fe(f) = self;
192         let Fe(g) = _rhs;
193         let f0 = f[0];
194         let f1 = f[1];
195         let f2 = f[2];
196         let f3 = f[3];
197         let f4 = f[4];
198         let f5 = f[5];
199         let f6 = f[6];
200         let f7 = f[7];
201         let f8 = f[8];
202         let f9 = f[9];
203         let g0 = g[0];
204         let g1 = g[1];
205         let g2 = g[2];
206         let g3 = g[3];
207         let g4 = g[4];
208         let g5 = g[5];
209         let g6 = g[6];
210         let g7 = g[7];
211         let g8 = g[8];
212         let g9 = g[9];
213         let g1_19 = 19 * g1; /* 1.4*2^29 */
214         let g2_19 = 19 * g2; /* 1.4*2^30; still ok */
215         let g3_19 = 19 * g3;
216         let g4_19 = 19 * g4;
217         let g5_19 = 19 * g5;
218         let g6_19 = 19 * g6;
219         let g7_19 = 19 * g7;
220         let g8_19 = 19 * g8;
221         let g9_19 = 19 * g9;
222         let f1_2 = 2 * f1;
223         let f3_2 = 2 * f3;
224         let f5_2 = 2 * f5;
225         let f7_2 = 2 * f7;
226         let f9_2 = 2 * f9;
227         let f0g0    = (f0   as i64) * (g0 as i64);
228         let f0g1    = (f0   as i64) * (g1 as i64);
229         let f0g2    = (f0   as i64) * (g2 as i64);
230         let f0g3    = (f0   as i64) * (g3 as i64);
231         let f0g4    = (f0   as i64) * (g4 as i64);
232         let f0g5    = (f0   as i64) * (g5 as i64);
233         let f0g6    = (f0   as i64) * (g6 as i64);
234         let f0g7    = (f0   as i64) * (g7 as i64);
235         let f0g8    = (f0   as i64) * (g8 as i64);
236         let f0g9    = (f0   as i64) * (g9 as i64);
237         let f1g0    = (f1   as i64) * (g0 as i64);
238         let f1g1_2  = (f1_2 as i64) * (g1 as i64);
239         let f1g2    = (f1   as i64) * (g2 as i64);
240         let f1g3_2  = (f1_2 as i64) * (g3 as i64);
241         let f1g4    = (f1   as i64) * (g4 as i64);
242         let f1g5_2  = (f1_2 as i64) * (g5 as i64);
243         let f1g6    = (f1   as i64) * (g6 as i64);
244         let f1g7_2  = (f1_2 as i64) * (g7 as i64);
245         let f1g8    = (f1   as i64) * (g8 as i64);
246         let f1g9_38 = (f1_2 as i64) * (g9_19 as i64);
247         let f2g0    = (f2   as i64) * (g0 as i64);
248         let f2g1    = (f2   as i64) * (g1 as i64);
249         let f2g2    = (f2   as i64) * (g2 as i64);
250         let f2g3    = (f2   as i64) * (g3 as i64);
251         let f2g4    = (f2   as i64) * (g4 as i64);
252         let f2g5    = (f2   as i64) * (g5 as i64);
253         let f2g6    = (f2   as i64) * (g6 as i64);
254         let f2g7    = (f2   as i64) * (g7 as i64);
255         let f2g8_19 = (f2   as i64) * (g8_19 as i64);
256         let f2g9_19 = (f2   as i64) * (g9_19 as i64);
257         let f3g0    = (f3   as i64) * (g0 as i64);
258         let f3g1_2  = (f3_2 as i64) * (g1 as i64);
259         let f3g2    = (f3   as i64) * (g2 as i64);
260         let f3g3_2  = (f3_2 as i64) * (g3 as i64);
261         let f3g4    = (f3   as i64) * (g4 as i64);
262         let f3g5_2  = (f3_2 as i64) * (g5 as i64);
263         let f3g6    = (f3   as i64) * (g6 as i64);
264         let f3g7_38 = (f3_2 as i64) * (g7_19 as i64);
265         let f3g8_19 = (f3   as i64) * (g8_19 as i64);
266         let f3g9_38 = (f3_2 as i64) * (g9_19 as i64);
267         let f4g0    = (f4   as i64) * (g0 as i64);
268         let f4g1    = (f4   as i64) * (g1 as i64);
269         let f4g2    = (f4   as i64) * (g2 as i64);
270         let f4g3    = (f4   as i64) * (g3 as i64);
271         let f4g4    = (f4   as i64) * (g4 as i64);
272         let f4g5    = (f4   as i64) * (g5 as i64);
273         let f4g6_19 = (f4   as i64) * (g6_19 as i64);
274         let f4g7_19 = (f4   as i64) * (g7_19 as i64);
275         let f4g8_19 = (f4   as i64) * (g8_19 as i64);
276         let f4g9_19 = (f4   as i64) * (g9_19 as i64);
277         let f5g0    = (f5   as i64) * (g0 as i64);
278         let f5g1_2  = (f5_2 as i64) * (g1 as i64);
279         let f5g2    = (f5   as i64) * (g2 as i64);
280         let f5g3_2  = (f5_2 as i64) * (g3 as i64);
281         let f5g4    = (f5   as i64) * (g4 as i64);
282         let f5g5_38 = (f5_2 as i64) * (g5_19 as i64);
283         let f5g6_19 = (f5   as i64) * (g6_19 as i64);
284         let f5g7_38 = (f5_2 as i64) * (g7_19 as i64);
285         let f5g8_19 = (f5   as i64) * (g8_19 as i64);
286         let f5g9_38 = (f5_2 as i64) * (g9_19 as i64);
287         let f6g0    = (f6   as i64) * (g0 as i64);
288         let f6g1    = (f6   as i64) * (g1 as i64);
289         let f6g2    = (f6   as i64) * (g2 as i64);
290         let f6g3    = (f6   as i64) * (g3 as i64);
291         let f6g4_19 = (f6   as i64) * (g4_19 as i64);
292         let f6g5_19 = (f6   as i64) * (g5_19 as i64);
293         let f6g6_19 = (f6   as i64) * (g6_19 as i64);
294         let f6g7_19 = (f6   as i64) * (g7_19 as i64);
295         let f6g8_19 = (f6   as i64) * (g8_19 as i64);
296         let f6g9_19 = (f6   as i64) * (g9_19 as i64);
297         let f7g0    = (f7   as i64) * (g0 as i64);
298         let f7g1_2  = (f7_2 as i64) * (g1 as i64);
299         let f7g2    = (f7   as i64) * (g2 as i64);
300         let f7g3_38 = (f7_2 as i64) * (g3_19 as i64);
301         let f7g4_19 = (f7   as i64) * (g4_19 as i64);
302         let f7g5_38 = (f7_2 as i64) * (g5_19 as i64);
303         let f7g6_19 = (f7   as i64) * (g6_19 as i64);
304         let f7g7_38 = (f7_2 as i64) * (g7_19 as i64);
305         let f7g8_19 = (f7   as i64) * (g8_19 as i64);
306         let f7g9_38 = (f7_2 as i64) * (g9_19 as i64);
307         let f8g0    = (f8   as i64) * (g0 as i64);
308         let f8g1    = (f8   as i64) * (g1 as i64);
309         let f8g2_19 = (f8   as i64) * (g2_19 as i64);
310         let f8g3_19 = (f8   as i64) * (g3_19 as i64);
311         let f8g4_19 = (f8   as i64) * (g4_19 as i64);
312         let f8g5_19 = (f8   as i64) * (g5_19 as i64);
313         let f8g6_19 = (f8   as i64) * (g6_19 as i64);
314         let f8g7_19 = (f8   as i64) * (g7_19 as i64);
315         let f8g8_19 = (f8   as i64) * (g8_19 as i64);
316         let f8g9_19 = (f8   as i64) * (g9_19 as i64);
317         let f9g0    = (f9   as i64) * (g0 as i64);
318         let f9g1_38 = (f9_2 as i64) * (g1_19 as i64);
319         let f9g2_19 = (f9   as i64) * (g2_19 as i64);
320         let f9g3_38 = (f9_2 as i64) * (g3_19 as i64);
321         let f9g4_19 = (f9   as i64) * (g4_19 as i64);
322         let f9g5_38 = (f9_2 as i64) * (g5_19 as i64);
323         let f9g6_19 = (f9   as i64) * (g6_19 as i64);
324         let f9g7_38 = (f9_2 as i64) * (g7_19 as i64);
325         let f9g8_19 = (f9   as i64) * (g8_19 as i64);
326         let f9g9_38 = (f9_2 as i64) * (g9_19 as i64);
327         let mut h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
328         let mut h1 = f0g1+f1g0   +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
329         let mut h2 = f0g2+f1g1_2 +f2g0   +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
330         let mut h3 = f0g3+f1g2   +f2g1   +f3g0   +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
331         let mut h4 = f0g4+f1g3_2 +f2g2   +f3g1_2 +f4g0   +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
332         let mut h5 = f0g5+f1g4   +f2g3   +f3g2   +f4g1   +f5g0   +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
333         let mut h6 = f0g6+f1g5_2 +f2g4   +f3g3_2 +f4g2   +f5g1_2 +f6g0   +f7g9_38+f8g8_19+f9g7_38;
334         let mut h7 = f0g7+f1g6   +f2g5   +f3g4   +f4g3   +f5g2   +f6g1   +f7g0   +f8g9_19+f9g8_19;
335         let mut h8 = f0g8+f1g7_2 +f2g6   +f3g5_2 +f4g4   +f5g3_2 +f6g2   +f7g1_2 +f8g0   +f9g9_38;
336         let mut h9 = f0g9+f1g8   +f2g7   +f3g6   +f4g5   +f5g4   +f6g3   +f7g2   +f8g1   +f9g0   ;
337         let mut carry0;
338         let carry1;
339         let carry2;
340         let carry3;
341         let mut carry4;
342         let carry5;
343         let carry6;
344         let carry7;
345         let carry8;
346         let carry9;
347 
348         /*
349         |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
350           i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
351         |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
352           i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
353         */
354 
355         carry0 = (h0 + (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
356         carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
357         /* |h0| <= 2^25 */
358         /* |h4| <= 2^25 */
359         /* |h1| <= 1.51*2^58 */
360         /* |h5| <= 1.51*2^58 */
361 
362         carry1 = (h1 + (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
363         carry5 = (h5 + (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
364         /* |h1| <= 2^24; from now on fits into int32 */
365         /* |h5| <= 2^24; from now on fits into int32 */
366         /* |h2| <= 1.21*2^59 */
367         /* |h6| <= 1.21*2^59 */
368 
369         carry2 = (h2 + (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
370         carry6 = (h6 + (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
371         /* |h2| <= 2^25; from now on fits into int32 unchanged */
372         /* |h6| <= 2^25; from now on fits into int32 unchanged */
373         /* |h3| <= 1.51*2^58 */
374         /* |h7| <= 1.51*2^58 */
375 
376         carry3 = (h3 + (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
377         carry7 = (h7 + (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
378         /* |h3| <= 2^24; from now on fits into int32 unchanged */
379         /* |h7| <= 2^24; from now on fits into int32 unchanged */
380         /* |h4| <= 1.52*2^33 */
381         /* |h8| <= 1.52*2^33 */
382 
383         carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
384         carry8 = (h8 + (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
385         /* |h4| <= 2^25; from now on fits into int32 unchanged */
386         /* |h8| <= 2^25; from now on fits into int32 unchanged */
387         /* |h5| <= 1.01*2^24 */
388         /* |h9| <= 1.51*2^58 */
389 
390         carry9 = (h9 + (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
391         /* |h9| <= 2^24; from now on fits into int32 unchanged */
392         /* |h0| <= 1.8*2^37 */
393 
394         carry0 = (h0 + (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
395         /* |h0| <= 2^25; from now on fits into int32 unchanged */
396         /* |h1| <= 1.01*2^24 */
397 
398         Fe([h0 as i32, h1 as i32, h2 as i32, h3 as i32, h4 as i32,
399             h5 as i32, h6 as i32, h7 as i32, h8 as i32, h9 as i32])
400     }
401 }
402 
403 impl Fe {
from_bytes(s: &[u8]) -> Fe404     pub fn from_bytes(s: &[u8]) -> Fe {
405         let mut h0 = load_4i(&s[0..4]);
406         let mut h1 = load_3i(&s[4..7]) << 6;
407         let mut h2 = load_3i(&s[7..10]) << 5;
408         let mut h3 = load_3i(&s[10..13]) << 3;
409         let mut h4 = load_3i(&s[13..16]) << 2;
410         let mut h5 = load_4i(&s[16..20]);
411         let mut h6 = load_3i(&s[20..23]) << 7;
412         let mut h7 = load_3i(&s[23..26]) << 5;
413         let mut h8 = load_3i(&s[26..29]) << 4;
414         let mut h9 = (load_3i(&s[29..32]) & 8388607) << 2;
415 
416         let carry9 = (h9 + (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
417         let carry1 = (h1 + (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
418         let carry3 = (h3 + (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
419         let carry5 = (h5 + (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
420         let carry7 = (h7 + (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
421 
422         let carry0 = (h0 + (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
423         let carry2 = (h2 + (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
424         let carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
425         let carry6 = (h6 + (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
426         let carry8 = (h8 + (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
427 
428         Fe([h0 as i32, h1 as i32, h2 as i32, h3 as i32, h4 as i32,
429             h5 as i32, h6 as i32, h7 as i32, h8 as i32, h9 as i32])
430     }
431 
432     /*
433     Preconditions:
434       |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
435 
436     Write p=2^255-19; q=floor(h/p).
437     Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
438 
439     Proof:
440       Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
441       Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
442 
443       Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
444       Then 0<y<1.
445 
446       Write r=h-pq.
447       Have 0<=r<=p-1=2^255-20.
448       Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
449 
450       Write x=r+19(2^-255)r+y.
451       Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
452 
453       Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
454       so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
455     */
456 
to_bytes(&self) -> [u8; 32]457     pub fn to_bytes(&self) -> [u8; 32] {
458         let &Fe(es) = self;
459         let mut h0 = es[0];
460         let mut h1 = es[1];
461         let mut h2 = es[2];
462         let mut h3 = es[3];
463         let mut h4 = es[4];
464         let mut h5 = es[5];
465         let mut h6 = es[6];
466         let mut h7 = es[7];
467         let mut h8 = es[8];
468         let mut h9 = es[9];
469         let mut q;
470 
471         q = (19 * h9 + (1 << 24)) >> 25;
472         q = (h0 + q) >> 26;
473         q = (h1 + q) >> 25;
474         q = (h2 + q) >> 26;
475         q = (h3 + q) >> 25;
476         q = (h4 + q) >> 26;
477         q = (h5 + q) >> 25;
478         q = (h6 + q) >> 26;
479         q = (h7 + q) >> 25;
480         q = (h8 + q) >> 26;
481         q = (h9 + q) >> 25;
482 
483         /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
484         h0 += 19 * q;
485         /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
486 
487         let carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
488         let carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
489         let carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
490         let carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
491         let carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
492         let carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
493         let carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
494         let carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
495         let carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
496         let carry9 = h9 >> 25;               h9 -= carry9 << 25;
497                             /* h10 = carry9 */
498 
499         /*
500         Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
501         Have h0+...+2^230 h9 between 0 and 2^255-1;
502         evidently 2^255 h10-2^255 q = 0.
503         Goal: Output h0+...+2^230 h9.
504         */
505         [
506             (h0 >> 0) as u8,
507             (h0 >> 8) as u8,
508             (h0 >> 16) as u8,
509             ((h0 >> 24) | (h1 << 2)) as u8,
510             (h1 >> 6) as u8,
511             (h1 >> 14) as u8,
512             ((h1 >> 22) | (h2 << 3)) as u8,
513             (h2 >> 5) as u8,
514             (h2 >> 13) as u8,
515             ((h2 >> 21) | (h3 << 5)) as u8,
516             (h3 >> 3) as u8,
517             (h3 >> 11) as u8,
518             ((h3 >> 19) | (h4 << 6)) as u8,
519             (h4 >> 2) as u8,
520             (h4 >> 10) as u8,
521             (h4 >> 18) as u8,
522             (h5 >> 0) as u8,
523             (h5 >> 8) as u8,
524             (h5 >> 16) as u8,
525             ((h5 >> 24) | (h6 << 1)) as u8,
526             (h6 >> 7) as u8,
527             (h6 >> 15) as u8,
528             ((h6 >> 23) | (h7 << 3)) as u8,
529             (h7 >> 5) as u8,
530             (h7 >> 13) as u8,
531             ((h7 >> 21) | (h8 << 4)) as u8,
532             (h8 >> 4) as u8,
533             (h8 >> 12) as u8,
534             ((h8 >> 20) | (h9 << 6)) as u8,
535             (h9 >> 2) as u8,
536             (h9 >> 10) as u8,
537             (h9 >> 18) as u8,
538         ]
539     }
540 
maybe_swap_with(&mut self, other: &mut Fe, do_swap: i32)541     pub fn maybe_swap_with(&mut self, other: &mut Fe, do_swap: i32) {
542         let &mut Fe(f) = self;
543         let &mut Fe(g) = other;
544         let f0 = f[0];
545         let f1 = f[1];
546         let f2 = f[2];
547         let f3 = f[3];
548         let f4 = f[4];
549         let f5 = f[5];
550         let f6 = f[6];
551         let f7 = f[7];
552         let f8 = f[8];
553         let f9 = f[9];
554         let g0 = g[0];
555         let g1 = g[1];
556         let g2 = g[2];
557         let g3 = g[3];
558         let g4 = g[4];
559         let g5 = g[5];
560         let g6 = g[6];
561         let g7 = g[7];
562         let g8 = g[8];
563         let g9 = g[9];
564         let mut x0 = f0 ^ g0;
565         let mut x1 = f1 ^ g1;
566         let mut x2 = f2 ^ g2;
567         let mut x3 = f3 ^ g3;
568         let mut x4 = f4 ^ g4;
569         let mut x5 = f5 ^ g5;
570         let mut x6 = f6 ^ g6;
571         let mut x7 = f7 ^ g7;
572         let mut x8 = f8 ^ g8;
573         let mut x9 = f9 ^ g9;
574         let b = -do_swap;
575         x0 &= b;
576         x1 &= b;
577         x2 &= b;
578         x3 &= b;
579         x4 &= b;
580         x5 &= b;
581         x6 &= b;
582         x7 &= b;
583         x8 &= b;
584         x9 &= b;
585         *self  = Fe([f0^x0, f1^x1, f2^x2, f3^x3, f4^x4,
586                      f5^x5, f6^x6, f7^x7, f8^x8, f9^x9]);
587         *other = Fe([g0^x0, g1^x1, g2^x2, g3^x3, g4^x4,
588                      g5^x5, g6^x6, g7^x7, g8^x8, g9^x9]);
589     }
590 
maybe_set(&mut self, other: &Fe, do_swap: i32)591     pub fn maybe_set(&mut self, other: &Fe, do_swap: i32) {
592         let &mut Fe(f) = self;
593         let &Fe(g) = other;
594         let f0 = f[0];
595         let f1 = f[1];
596         let f2 = f[2];
597         let f3 = f[3];
598         let f4 = f[4];
599         let f5 = f[5];
600         let f6 = f[6];
601         let f7 = f[7];
602         let f8 = f[8];
603         let f9 = f[9];
604         let g0 = g[0];
605         let g1 = g[1];
606         let g2 = g[2];
607         let g3 = g[3];
608         let g4 = g[4];
609         let g5 = g[5];
610         let g6 = g[6];
611         let g7 = g[7];
612         let g8 = g[8];
613         let g9 = g[9];
614         let mut x0 = f0 ^ g0;
615         let mut x1 = f1 ^ g1;
616         let mut x2 = f2 ^ g2;
617         let mut x3 = f3 ^ g3;
618         let mut x4 = f4 ^ g4;
619         let mut x5 = f5 ^ g5;
620         let mut x6 = f6 ^ g6;
621         let mut x7 = f7 ^ g7;
622         let mut x8 = f8 ^ g8;
623         let mut x9 = f9 ^ g9;
624         let b = -do_swap;
625         x0 &= b;
626         x1 &= b;
627         x2 &= b;
628         x3 &= b;
629         x4 &= b;
630         x5 &= b;
631         x6 &= b;
632         x7 &= b;
633         x8 &= b;
634         x9 &= b;
635         *self  = Fe([f0^x0, f1^x1, f2^x2, f3^x3, f4^x4,
636                      f5^x5, f6^x6, f7^x7, f8^x8, f9^x9]);
637     }
638 
639     /*
640     h = f * 121666
641     Can overlap h with f.
642 
643     Preconditions:
644        |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
645 
646     Postconditions:
647        |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
648     */
649 
mul_121666(&self) -> Fe650     fn mul_121666(&self) -> Fe {
651         let &Fe(f) = self;
652 
653         let mut h0 = (f[0] as i64) * 121666;
654         let mut h1 = (f[1] as i64) * 121666;
655         let mut h2 = (f[2] as i64) * 121666;
656         let mut h3 = (f[3] as i64) * 121666;
657         let mut h4 = (f[4] as i64) * 121666;
658         let mut h5 = (f[5] as i64) * 121666;
659         let mut h6 = (f[6] as i64) * 121666;
660         let mut h7 = (f[7] as i64) * 121666;
661         let mut h8 = (f[8] as i64) * 121666;
662         let mut h9 = (f[9] as i64) * 121666;
663 
664         let carry9 = (h9 + (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
665         let carry1 = (h1 + (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
666         let carry3 = (h3 + (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
667         let carry5 = (h5 + (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
668         let carry7 = (h7 + (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
669 
670         let carry0 = (h0 + (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
671         let carry2 = (h2 + (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
672         let carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
673         let carry6 = (h6 + (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
674         let carry8 = (h8 + (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
675 
676         Fe([h0 as i32, h1 as i32, h2 as i32, h3 as i32, h4 as i32,
677             h5 as i32, h6 as i32, h7 as i32, h8 as i32, h9 as i32])
678     }
679 
680 
681     /*
682     h = f * f
683     Can overlap h with f.
684 
685     Preconditions:
686        |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
687 
688     Postconditions:
689        |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
690     */
691 
692     /*
693     See fe_mul.c for discussion of implementation strategy.
694     */
square(&self) -> Fe695     fn square(&self) -> Fe {
696         let &Fe(f) = self;
697 
698         let f0 = f[0];
699         let f1 = f[1];
700         let f2 = f[2];
701         let f3 = f[3];
702         let f4 = f[4];
703         let f5 = f[5];
704         let f6 = f[6];
705         let f7 = f[7];
706         let f8 = f[8];
707         let f9 = f[9];
708         let f0_2 = 2 * f0;
709         let f1_2 = 2 * f1;
710         let f2_2 = 2 * f2;
711         let f3_2 = 2 * f3;
712         let f4_2 = 2 * f4;
713         let f5_2 = 2 * f5;
714         let f6_2 = 2 * f6;
715         let f7_2 = 2 * f7;
716         let f5_38 = 38 * f5; /* 1.31*2^30 */
717         let f6_19 = 19 * f6; /* 1.31*2^30 */
718         let f7_38 = 38 * f7; /* 1.31*2^30 */
719         let f8_19 = 19 * f8; /* 1.31*2^30 */
720         let f9_38 = 38 * f9; /* 1.31*2^30 */
721         let f0f0    = (f0   as i64) * (f0 as i64);
722         let f0f1_2  = (f0_2 as i64) * (f1 as i64);
723         let f0f2_2  = (f0_2 as i64) * (f2 as i64);
724         let f0f3_2  = (f0_2 as i64) * (f3 as i64);
725         let f0f4_2  = (f0_2 as i64) * (f4 as i64);
726         let f0f5_2  = (f0_2 as i64) * (f5 as i64);
727         let f0f6_2  = (f0_2 as i64) * (f6 as i64);
728         let f0f7_2  = (f0_2 as i64) * (f7 as i64);
729         let f0f8_2  = (f0_2 as i64) * (f8 as i64);
730         let f0f9_2  = (f0_2 as i64) * (f9 as i64);
731         let f1f1_2  = (f1_2 as i64) * (f1 as i64);
732         let f1f2_2  = (f1_2 as i64) * (f2 as i64);
733         let f1f3_4  = (f1_2 as i64) * (f3_2 as i64);
734         let f1f4_2  = (f1_2 as i64) * (f4 as i64);
735         let f1f5_4  = (f1_2 as i64) * (f5_2 as i64);
736         let f1f6_2  = (f1_2 as i64) * (f6 as i64);
737         let f1f7_4  = (f1_2 as i64) * (f7_2 as i64);
738         let f1f8_2  = (f1_2 as i64) * (f8 as i64);
739         let f1f9_76 = (f1_2 as i64) * (f9_38 as i64);
740         let f2f2    = (f2   as i64) * (f2 as i64);
741         let f2f3_2  = (f2_2 as i64) * (f3 as i64);
742         let f2f4_2  = (f2_2 as i64) * (f4 as i64);
743         let f2f5_2  = (f2_2 as i64) * (f5 as i64);
744         let f2f6_2  = (f2_2 as i64) * (f6 as i64);
745         let f2f7_2  = (f2_2 as i64) * (f7 as i64);
746         let f2f8_38 = (f2_2 as i64) * (f8_19 as i64);
747         let f2f9_38 = (f2   as i64) * (f9_38 as i64);
748         let f3f3_2  = (f3_2 as i64) * (f3 as i64);
749         let f3f4_2  = (f3_2 as i64) * (f4 as i64);
750         let f3f5_4  = (f3_2 as i64) * (f5_2 as i64);
751         let f3f6_2  = (f3_2 as i64) * (f6 as i64);
752         let f3f7_76 = (f3_2 as i64) * (f7_38 as i64);
753         let f3f8_38 = (f3_2 as i64) * (f8_19 as i64);
754         let f3f9_76 = (f3_2 as i64) * (f9_38 as i64);
755         let f4f4    = (f4   as i64) * (f4 as i64);
756         let f4f5_2  = (f4_2 as i64) * (f5 as i64);
757         let f4f6_38 = (f4_2 as i64) * (f6_19 as i64);
758         let f4f7_38 = (f4   as i64) * (f7_38 as i64);
759         let f4f8_38 = (f4_2 as i64) * (f8_19 as i64);
760         let f4f9_38 = (f4   as i64) * (f9_38 as i64);
761         let f5f5_38 = (f5   as i64) * (f5_38 as i64);
762         let f5f6_38 = (f5_2 as i64) * (f6_19 as i64);
763         let f5f7_76 = (f5_2 as i64) * (f7_38 as i64);
764         let f5f8_38 = (f5_2 as i64) * (f8_19 as i64);
765         let f5f9_76 = (f5_2 as i64) * (f9_38 as i64);
766         let f6f6_19 = (f6   as i64) * (f6_19 as i64);
767         let f6f7_38 = (f6   as i64) * (f7_38 as i64);
768         let f6f8_38 = (f6_2 as i64) * (f8_19 as i64);
769         let f6f9_38 = (f6   as i64) * (f9_38 as i64);
770         let f7f7_38 = (f7   as i64) * (f7_38 as i64);
771         let f7f8_38 = (f7_2 as i64) * (f8_19 as i64);
772         let f7f9_76 = (f7_2 as i64) * (f9_38 as i64);
773         let f8f8_19 = (f8   as i64) * (f8_19 as i64);
774         let f8f9_38 = (f8   as i64) * (f9_38 as i64);
775         let f9f9_38 = (f9   as i64) * (f9_38 as i64);
776         let mut h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
777         let mut h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
778         let mut h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
779         let mut h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
780         let mut h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
781         let mut h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
782         let mut h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
783         let mut h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
784         let mut h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
785         let mut h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
786 
787         let carry0 = (h0 + (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
788         let carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
789 
790         let carry1 = (h1 + (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
791         let carry5 = (h5 + (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
792 
793         let carry2 = (h2 + (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
794         let carry6 = (h6 + (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
795 
796         let carry3 = (h3 + (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
797         let carry7 = (h7 + (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
798 
799         let carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
800         let carry8 = (h8 + (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
801 
802         let carry9 = (h9 + (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
803 
804         let carrya = (h0 + (1<<25)) >> 26; h1 += carrya; h0 -= carrya << 26;
805 
806         Fe([h0 as i32, h1 as i32, h2 as i32, h3 as i32, h4 as i32,
807             h5 as i32, h6 as i32, h7 as i32, h8 as i32, h9 as i32])
808     }
809 
square_and_double(&self) -> Fe810     fn square_and_double(&self) -> Fe {
811         let &Fe(f) = self;
812 
813         let f0 = f[0];
814         let f1 = f[1];
815         let f2 = f[2];
816         let f3 = f[3];
817         let f4 = f[4];
818         let f5 = f[5];
819         let f6 = f[6];
820         let f7 = f[7];
821         let f8 = f[8];
822         let f9 = f[9];
823         let f0_2 = 2 * f0;
824         let f1_2 = 2 * f1;
825         let f2_2 = 2 * f2;
826         let f3_2 = 2 * f3;
827         let f4_2 = 2 * f4;
828         let f5_2 = 2 * f5;
829         let f6_2 = 2 * f6;
830         let f7_2 = 2 * f7;
831         let f5_38 = 38 * f5; /* 1.959375*2^30 */
832         let f6_19 = 19 * f6; /* 1.959375*2^30 */
833         let f7_38 = 38 * f7; /* 1.959375*2^30 */
834         let f8_19 = 19 * f8; /* 1.959375*2^30 */
835         let f9_38 = 38 * f9; /* 1.959375*2^30 */
836         let f0f0    = (f0    as i64) * (f0 as i64);
837         let f0f1_2  = (f0_2  as i64) * (f1 as i64);
838         let f0f2_2  = (f0_2  as i64) * (f2 as i64);
839         let f0f3_2  = (f0_2  as i64) * (f3 as i64);
840         let f0f4_2  = (f0_2  as i64) * (f4 as i64);
841         let f0f5_2  = (f0_2  as i64) * (f5 as i64);
842         let f0f6_2  = (f0_2  as i64) * (f6 as i64);
843         let f0f7_2  = (f0_2  as i64) * (f7 as i64);
844         let f0f8_2  = (f0_2  as i64) * (f8 as i64);
845         let f0f9_2  = (f0_2  as i64) * (f9 as i64);
846         let f1f1_2  = (f1_2  as i64) * (f1 as i64);
847         let f1f2_2  = (f1_2  as i64) * (f2 as i64);
848         let f1f3_4  = (f1_2  as i64) * (f3_2 as i64);
849         let f1f4_2  = (f1_2  as i64) * (f4 as i64);
850         let f1f5_4  = (f1_2  as i64) * (f5_2 as i64);
851         let f1f6_2  = (f1_2  as i64) * (f6 as i64);
852         let f1f7_4  = (f1_2  as i64) * (f7_2 as i64);
853         let f1f8_2  = (f1_2  as i64) * (f8 as i64);
854         let f1f9_76 = (f1_2  as i64) * (f9_38 as i64);
855         let f2f2    = (f2    as i64) * (f2 as i64);
856         let f2f3_2  = (f2_2  as i64) * (f3 as i64);
857         let f2f4_2  = (f2_2  as i64) * (f4 as i64);
858         let f2f5_2  = (f2_2  as i64) * (f5 as i64);
859         let f2f6_2  = (f2_2  as i64) * (f6 as i64);
860         let f2f7_2  = (f2_2  as i64) * (f7 as i64);
861         let f2f8_38 = (f2_2  as i64) * (f8_19 as i64);
862         let f2f9_38 = (f2    as i64) * (f9_38 as i64);
863         let f3f3_2  = (f3_2  as i64) * (f3 as i64);
864         let f3f4_2  = (f3_2  as i64) * (f4 as i64);
865         let f3f5_4  = (f3_2  as i64) * (f5_2 as i64);
866         let f3f6_2  = (f3_2  as i64) * (f6 as i64);
867         let f3f7_76 = (f3_2  as i64) * (f7_38 as i64);
868         let f3f8_38 = (f3_2  as i64) * (f8_19 as i64);
869         let f3f9_76 = (f3_2  as i64) * (f9_38 as i64);
870         let f4f4    = (f4    as i64) * (f4 as i64);
871         let f4f5_2  = (f4_2  as i64) * (f5 as i64);
872         let f4f6_38 = (f4_2  as i64) * (f6_19 as i64);
873         let f4f7_38 = (f4    as i64) * (f7_38 as i64);
874         let f4f8_38 = (f4_2  as i64) * (f8_19 as i64);
875         let f4f9_38 = (f4    as i64) * (f9_38 as i64);
876         let f5f5_38 = (f5    as i64) * (f5_38 as i64);
877         let f5f6_38 = (f5_2  as i64) * (f6_19 as i64);
878         let f5f7_76 = (f5_2  as i64) * (f7_38 as i64);
879         let f5f8_38 = (f5_2  as i64) * (f8_19 as i64);
880         let f5f9_76 = (f5_2  as i64) * (f9_38 as i64);
881         let f6f6_19 = (f6    as i64) * (f6_19 as i64);
882         let f6f7_38 = (f6    as i64) * (f7_38 as i64);
883         let f6f8_38 = (f6_2  as i64) * (f8_19 as i64);
884         let f6f9_38 = (f6    as i64) * (f9_38 as i64);
885         let f7f7_38 = (f7    as i64) * (f7_38 as i64);
886         let f7f8_38 = (f7_2  as i64) * (f8_19 as i64);
887         let f7f9_76 = (f7_2  as i64) * (f9_38 as i64);
888         let f8f8_19 = (f8    as i64) * (f8_19 as i64);
889         let f8f9_38 = (f8    as i64) * (f9_38 as i64);
890         let f9f9_38 = (f9    as i64) * (f9_38 as i64);
891         let mut h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
892         let mut h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
893         let mut h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
894         let mut h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
895         let mut h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
896         let mut h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
897         let mut h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
898         let mut h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
899         let mut h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
900         let mut h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
901         let mut carry0: i64;
902         let carry1: i64;
903         let carry2: i64;
904         let carry3: i64;
905         let mut carry4: i64;
906         let carry5: i64;
907         let carry6: i64;
908         let carry7: i64;
909         let carry8: i64;
910         let carry9: i64;
911 
912         h0 += h0;
913         h1 += h1;
914         h2 += h2;
915         h3 += h3;
916         h4 += h4;
917         h5 += h5;
918         h6 += h6;
919         h7 += h7;
920         h8 += h8;
921         h9 += h9;
922 
923         carry0 = (h0 + (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
924         carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
925 
926         carry1 = (h1 + (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
927         carry5 = (h5 + (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
928 
929         carry2 = (h2 + (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
930         carry6 = (h6 + (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
931 
932         carry3 = (h3 + (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
933         carry7 = (h7 + (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
934 
935         carry4 = (h4 + (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
936         carry8 = (h8 + (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
937 
938         carry9 = (h9 + (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
939 
940         carry0 = (h0 + (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
941 
942         Fe([h0 as i32, h1 as i32, h2 as i32, h3 as i32, h4 as i32,
943             h5 as i32, h6 as i32, h7 as i32, h8 as i32, h9 as i32])
944     }
945 
invert(&self) -> Fe946     pub fn invert(&self) -> Fe {
947         let z1 = *self;
948 
949         /* qhasm: z2 = z1^2^1 */
950         let z2 = z1.square();
951         /* qhasm: z8 = z2^2^2 */
952         let z8 = z2.square().square();
953         /* qhasm: z9 = z1*z8 */
954         let z9 = z1*z8;
955 
956         /* qhasm: z11 = z2*z9 */
957         let z11 = z2*z9;
958 
959         /* qhasm: z22 = z11^2^1 */
960         let z22 = z11.square();
961 
962         /* qhasm: z_5_0 = z9*z22 */
963         let z_5_0 = z9*z22;
964 
965         /* qhasm: z_10_5 = z_5_0^2^5 */
966         let z_10_5 = (0..5).fold(z_5_0, |z_5_n, _| z_5_n.square());
967 
968         /* qhasm: z_10_0 = z_10_5*z_5_0 */
969         let z_10_0 = z_10_5*z_5_0;
970 
971         /* qhasm: z_20_10 = z_10_0^2^10 */
972         let z_20_10 = (0..10).fold(z_10_0, |x, _| x.square());
973 
974         /* qhasm: z_20_0 = z_20_10*z_10_0 */
975         let z_20_0 = z_20_10*z_10_0;
976 
977         /* qhasm: z_40_20 = z_20_0^2^20 */
978         let z_40_20 = (0..20).fold(z_20_0, |x, _| x.square());
979 
980         /* qhasm: z_40_0 = z_40_20*z_20_0 */
981         let z_40_0 = z_40_20*z_20_0;
982 
983         /* qhasm: z_50_10 = z_40_0^2^10 */
984         let z_50_10 = (0..10).fold(z_40_0, |x, _| x.square());
985 
986         /* qhasm: z_50_0 = z_50_10*z_10_0 */
987         let z_50_0 = z_50_10*z_10_0;
988 
989         /* qhasm: z_100_50 = z_50_0^2^50 */
990         let z_100_50 = (0..50).fold(z_50_0, |x, _| x.square());
991 
992         /* qhasm: z_100_0 = z_100_50*z_50_0 */
993         let z_100_0 = z_100_50*z_50_0;
994 
995         /* qhasm: z_200_100 = z_100_0^2^100 */
996         let z_200_100 = (0..100).fold(z_100_0, |x, _| x.square());
997 
998         /* qhasm: z_200_0 = z_200_100*z_100_0 */
999         /* asm 1: fe_mul(>z_200_0=fe#3,<z_200_100=fe#4,<z_100_0=fe#3); */
1000         /* asm 2: fe_mul(>z_200_0=t2,<z_200_100=t3,<z_100_0=t2); */
1001         let z_200_0 = z_200_100*z_100_0;
1002 
1003         /* qhasm: z_250_50 = z_200_0^2^50 */
1004         let z_250_50 = (0..50).fold(z_200_0, |x, _| x.square());
1005 
1006         /* qhasm: z_250_0 = z_250_50*z_50_0 */
1007         let z_250_0 = z_250_50*z_50_0;
1008 
1009         /* qhasm: z_255_5 = z_250_0^2^5 */
1010         let z_255_5 = (0..5).fold(z_250_0, |x, _| x.square());
1011 
1012         /* qhasm: z_255_21 = z_255_5*z11 */
1013         /* asm 1: fe_mul(>z_255_21=fe#12,<z_255_5=fe#2,<z11=fe#1); */
1014         /* asm 2: fe_mul(>z_255_21=out,<z_255_5=t1,<z11=t0); */
1015         let z_255_21 = z_255_5*z11;
1016 
1017         z_255_21
1018     }
1019 
1020 
is_nonzero(&self) -> bool1021     fn is_nonzero(&self) -> bool {
1022         let bs = self.to_bytes();
1023         let zero = [0; 32];
1024         !fixed_time_eq(bs.as_ref(), zero.as_ref())
1025     }
1026 
is_negative(&self) -> bool1027     fn is_negative(&self) -> bool {
1028         (self.to_bytes()[0] & 1) != 0
1029     }
1030 
neg(&self) -> Fe1031     fn neg(&self) -> Fe {
1032         let &Fe(f) = self;
1033         Fe([-f[0], -f[1], -f[2], -f[3], -f[4],
1034             -f[5], -f[6], -f[7], -f[8], -f[9]])
1035     }
1036 
pow25523(&self) -> Fe1037     fn pow25523(&self) -> Fe {
1038         let z2 = self.square();
1039         let z8 = (0..2).fold(z2, |x, _| x.square());
1040         let z9 = *self * z8;
1041         let z11 = z2 * z9;
1042         let z22 = z11.square();
1043         let z_5_0 = z9 * z22;
1044         let z_10_5 = (0..5).fold(z_5_0, |x, _| x.square());
1045         let z_10_0 = z_10_5 * z_5_0;
1046         let z_20_10 = (0..10).fold(z_10_0, |x, _| x.square());
1047         let z_20_0 = z_20_10 * z_10_0;
1048         let z_40_20 = (0..20).fold(z_20_0, |x, _| x.square());
1049         let z_40_0 = z_40_20 * z_20_0;
1050         let z_50_10 = (0..10).fold(z_40_0, |x, _| x.square());
1051         let z_50_0 = z_50_10 * z_10_0;
1052         let z_100_50 = (0..50).fold(z_50_0, |x, _| x.square());
1053         let z_100_0 = z_100_50 * z_50_0;
1054         let z_200_100 = (0..100).fold(z_100_0, |x, _| x.square());
1055         let z_200_0 = z_200_100 * z_100_0;
1056         let z_250_50 = (0..50).fold(z_200_0, |x, _| x.square());
1057         let z_250_0 = z_250_50 * z_50_0;
1058         let z_252_2 = (0..2).fold(z_250_0, |x, _| x.square());
1059         let z_252_3 = z_252_2 * *self;
1060 
1061         z_252_3
1062     }
1063 }
1064 
1065 #[derive(Clone, Copy)]
1066 pub struct GeP2 {
1067     x: Fe,
1068     y: Fe,
1069     z: Fe,
1070 }
1071 
1072 #[derive(Clone, Copy)]
1073 pub struct GeP3 {
1074     x: Fe,
1075     y: Fe,
1076     z: Fe,
1077     t: Fe,
1078 }
1079 
1080 #[derive(Clone, Copy)]
1081 pub struct GeP1P1 {
1082     x: Fe,
1083     y: Fe,
1084     z: Fe,
1085     t: Fe,
1086 }
1087 
1088 #[derive(Clone, Copy)]
1089 pub struct GePrecomp {
1090     y_plus_x: Fe,
1091     y_minus_x: Fe,
1092     xy2d: Fe,
1093 }
1094 
1095 #[derive(Clone, Copy)]
1096 pub struct GeCached {
1097     y_plus_x: Fe,
1098     y_minus_x: Fe,
1099     z: Fe,
1100     t2d: Fe,
1101 }
1102 
1103 impl GeP1P1 {
to_p2(&self) -> GeP21104     fn to_p2(&self) -> GeP2 {
1105         GeP2 {
1106             x: self.x * self.t,
1107             y: self.y * self.z,
1108             z: self.z * self.t,
1109         }
1110     }
1111 
1112 
to_p3(&self) -> GeP31113     fn to_p3(&self) -> GeP3 {
1114         GeP3 {
1115             x: self.x * self.t,
1116             y: self.y * self.z,
1117             z: self.z * self.t,
1118             t: self.x * self.y,
1119         }
1120     }
1121 
1122 }
1123 
1124 impl GeP2 {
zero() -> GeP21125     fn zero() -> GeP2 {
1126         GeP2 {
1127             x: FE_ZERO,
1128             y: FE_ONE,
1129             z: FE_ONE,
1130         }
1131     }
1132 
to_bytes(&self) -> [u8; 32]1133     pub fn to_bytes(&self) -> [u8; 32] {
1134         let recip = self.z.invert();
1135         let x = self.x * recip;
1136         let y = self.y * recip;
1137         let mut bs = y.to_bytes();
1138         bs[31] ^= (if x.is_negative() { 1 } else { 0 }) << 7;
1139         bs
1140     }
1141 
dbl(&self) -> GeP1P11142     fn dbl(&self) -> GeP1P1 {
1143         let xx = self.x.square();
1144         let yy = self.y.square();
1145         let b = self.z.square_and_double();
1146         let a = self.x + self.y;
1147         let aa = a.square();
1148         let y3 = yy + xx;
1149         let z3 = yy - xx;
1150         let x3 = aa - y3;
1151         let t3 = b - z3;
1152 
1153         GeP1P1 { x: x3, y: y3, z: z3, t: t3 }
1154     }
1155 
slide(a: &[u8]) -> [i8; 256]1156     fn slide(a: &[u8]) -> [i8; 256] {
1157         let mut r = [0i8; 256];
1158         for i in 0..256 {
1159             r[i] = (1 & (a[i >> 3] >> (i & 7))) as i8;
1160         }
1161         for i in 0..256 {
1162             if r[i]!=0 {
1163                 for b in 1..min(7, 256-i) {
1164                     if r[i + b] != 0 {
1165                         if r[i] + (r[i + b] << b) <= 15 {
1166                             r[i] += r[i + b] << b; r[i + b] = 0;
1167                         } else if r[i] - (r[i + b] << b) >= -15 {
1168                             r[i] -= r[i + b] << b;
1169                             for k in i+b..256 {
1170                                 if r[k]==0 {
1171                                     r[k] = 1;
1172                                     break;
1173                                 }
1174                                 r[k] = 0;
1175                             }
1176                         } else {
1177                             break;
1178                         }
1179                     }
1180                 }
1181             }
1182         }
1183 
1184         r
1185     }
1186 
1187     /*
1188     r = a * A + b * B
1189     where a = a[0]+256*a[1]+...+256^31 a[31].
1190     and b = b[0]+256*b[1]+...+256^31 b[31].
1191     B is the Ed25519 base point (x,4/5) with x positive.
1192     */
double_scalarmult_vartime(a_scalar: &[u8], a_point: GeP3, b_scalar: &[u8]) -> GeP21193     pub fn double_scalarmult_vartime(a_scalar: &[u8], a_point: GeP3, b_scalar: &[u8]) -> GeP2 {
1194         let aslide = GeP2::slide(a_scalar);
1195         let bslide = GeP2::slide(b_scalar);
1196 
1197         let mut ai = [GeCached{y_plus_x:FE_ZERO, y_minus_x: FE_ZERO, z: FE_ZERO, t2d: FE_ZERO}; 8]; /* A,3A,5A,7A,9A,11A,13A,15A */
1198         ai[0] = a_point.to_cached();
1199         let a2 = a_point.dbl().to_p3();
1200         ai[1] = (a2 + ai[0]).to_p3().to_cached();
1201         ai[2] = (a2 + ai[1]).to_p3().to_cached();
1202         ai[3] = (a2 + ai[2]).to_p3().to_cached();
1203         ai[4] = (a2 + ai[3]).to_p3().to_cached();
1204         ai[5] = (a2 + ai[4]).to_p3().to_cached();
1205         ai[6] = (a2 + ai[5]).to_p3().to_cached();
1206         ai[7] = (a2 + ai[6]).to_p3().to_cached();
1207 
1208         let mut r = GeP2::zero();
1209 
1210         let mut i: usize = 255;
1211         loop {
1212             if aslide[i]!=0 || bslide[i]!=0 {
1213                 break;
1214             }
1215             if i==0 {
1216                 return r;
1217             }
1218             i -= 1;
1219         }
1220 
1221         loop {
1222             let mut t = r.dbl();
1223             if aslide[i] > 0 {
1224                 t = t.to_p3() + ai[(aslide[i]/2) as usize];
1225             } else if aslide[i] < 0 {
1226                 t = t.to_p3() - ai[(-aslide[i]/2) as usize];
1227             }
1228 
1229             if bslide[i] > 0 {
1230                 t = t.to_p3() + BI[(bslide[i]/2) as usize];
1231             } else if bslide[i] < 0 {
1232                 t = t.to_p3() - BI[(-bslide[i]/2) as usize];
1233             }
1234 
1235             r = t.to_p2();
1236 
1237             if i==0 {
1238                 return r;
1239             }
1240             i -= 1;
1241         }
1242     }
1243 
1244 }
1245 
1246 impl GeP3 {
from_bytes_negate_vartime(s: &[u8]) -> Option<GeP3>1247     pub fn from_bytes_negate_vartime(s: &[u8]) -> Option<GeP3> {
1248         let y = Fe::from_bytes(s);
1249         let z = FE_ONE;
1250         let y_squared = y.square();
1251         let u = y_squared - FE_ONE;
1252         let v = (y_squared * FE_D) + FE_ONE;
1253         let v_raise_3 = v.square() * v;
1254         let v_raise_7 = v_raise_3.square() * v;
1255         let uv7 = v_raise_7 * u;// Is this commutative? u comes second in the code, but not in the notation...
1256 
1257         let mut x = uv7.pow25523() * v_raise_3 * u;
1258 
1259         let vxx = x.square() * v;
1260         let check = vxx - u;
1261         if check.is_nonzero() {
1262             let check2 = vxx + u;
1263             if check2.is_nonzero() {
1264                 return None;
1265             }
1266             x = x * FE_SQRTM1;
1267         }
1268 
1269         if x.is_negative() == ((s[31]>>7)!=0) {
1270             x = x.neg();
1271         }
1272 
1273         let t = x * y;
1274 
1275         Some(GeP3{x: x, y: y, z: z, t: t})
1276     }
1277 
to_p2(&self) -> GeP21278     fn to_p2(&self) -> GeP2 {
1279         GeP2 {
1280             x: self.x,
1281             y: self.y,
1282             z: self.z,
1283         }
1284     }
1285 
to_cached(&self) -> GeCached1286     fn to_cached(&self) -> GeCached {
1287         GeCached {
1288             y_plus_x: self.y + self.x,
1289             y_minus_x: self.y - self.x,
1290             z: self.z,
1291             t2d: self.t * FE_D2
1292         }
1293     }
1294 
zero() -> GeP31295     fn zero() -> GeP3 {
1296         GeP3 {
1297             x: FE_ZERO,
1298             y: FE_ONE,
1299             z: FE_ONE,
1300             t: FE_ZERO,
1301         }
1302     }
1303 
dbl(&self) -> GeP1P11304     fn dbl(&self) -> GeP1P1 {
1305         self.to_p2().dbl()
1306     }
1307 
to_bytes(&self) -> [u8; 32]1308     pub fn to_bytes(&self) -> [u8; 32] {
1309         let recip = self.z.invert();
1310         let x = self.x * recip;
1311         let y = self.y * recip;
1312         let mut bs = y.to_bytes();
1313         bs[31] ^= (if x.is_negative() { 1 } else { 0 }) << 7;
1314         bs
1315     }
1316 
1317 
1318 }
1319 
1320 impl Add<GeCached> for GeP3 {
1321     type Output = GeP1P1;
1322 
add(self, _rhs: GeCached) -> GeP1P11323     fn add(self, _rhs: GeCached) -> GeP1P1 {
1324         let y1_plus_x1 = self.y + self.x;
1325         let y1_minus_x1 = self.y - self.x;
1326         let a = y1_plus_x1 * _rhs.y_plus_x;
1327         let b = y1_minus_x1 * _rhs.y_minus_x;
1328         let c = _rhs.t2d * self.t;
1329         let zz = self.z * _rhs.z;
1330         let d = zz + zz;
1331         let x3 = a - b;
1332         let y3 = a + b;
1333         let z3 = d + c;
1334         let t3 = d - c;
1335 
1336         GeP1P1 { x: x3, y: y3, z: z3, t: t3 }
1337     }
1338 }
1339 
1340 impl Add<GePrecomp> for GeP3 {
1341     type Output = GeP1P1;
1342 
add(self, _rhs: GePrecomp) -> GeP1P11343     fn add(self, _rhs: GePrecomp) -> GeP1P1 {
1344         let y1_plus_x1 = self.y + self.x;
1345         let y1_minus_x1 = self.y - self.x;
1346         let a = y1_plus_x1 * _rhs.y_plus_x;
1347         let b = y1_minus_x1 * _rhs.y_minus_x;
1348         let c = _rhs.xy2d * self.t;
1349         let d = self.z + self.z;
1350         let x3 = a - b;
1351         let y3 = a + b;
1352         let z3 = d + c;
1353         let t3 = d - c;
1354 
1355         GeP1P1 { x: x3, y: y3, z: z3, t: t3 }
1356     }
1357 }
1358 
1359 impl Sub<GeCached> for GeP3 {
1360     type Output = GeP1P1;
1361 
sub(self, _rhs: GeCached) -> GeP1P11362     fn sub(self, _rhs: GeCached) -> GeP1P1 {
1363         let y1_plus_x1 = self.y + self.x;
1364         let y1_minus_x1 = self.y - self.x;
1365         let a = y1_plus_x1 * _rhs.y_minus_x;
1366         let b = y1_minus_x1 * _rhs.y_plus_x;
1367         let c = _rhs.t2d * self.t;
1368         let zz = self.z * _rhs.z;
1369         let d = zz + zz;
1370         let x3 = a - b;
1371         let y3 = a + b;
1372         let z3 = d - c;
1373         let t3 = d + c;
1374 
1375         GeP1P1 { x: x3, y: y3, z: z3, t: t3 }
1376     }
1377 }
1378 
1379 impl Sub<GePrecomp> for GeP3 {
1380     type Output = GeP1P1;
1381 
sub(self, _rhs: GePrecomp) -> GeP1P11382     fn sub(self, _rhs: GePrecomp) -> GeP1P1 {
1383         let y1_plus_x1 = self.y + self.x;
1384         let y1_minus_x1 = self.y - self.x;
1385         let a = y1_plus_x1 * _rhs.y_minus_x;
1386         let b = y1_minus_x1 * _rhs.y_plus_x;
1387         let c = _rhs.xy2d * self.t;
1388         let d = self.z + self.z;
1389         let x3 = a - b;
1390         let y3 = a + b;
1391         let z3 = d - c;
1392         let t3 = d + c;
1393 
1394         GeP1P1 { x: x3, y: y3, z: z3, t: t3 }
1395     }
1396 }
1397 
equal(b: u8, c: u8) -> i321398 fn equal(b: u8, c: u8) -> i32 {
1399     let x = b ^ c; /* 0: yes; 1..255: no */
1400     let mut y = x as u32; /* 0: yes; 1..255: no */
1401     y = y.wrapping_sub(1); /* 4294967295: yes; 0..254: no */
1402     y >>= 31; /* 1: yes; 0: no */
1403     y as i32
1404 }
1405 
1406 
1407 
1408 impl GePrecomp {
zero() -> GePrecomp1409     fn zero() -> GePrecomp {
1410         GePrecomp {
1411             y_plus_x: FE_ONE,
1412             y_minus_x: FE_ONE,
1413             xy2d: FE_ZERO,
1414         }
1415     }
1416 
maybe_set(&mut self, other: &GePrecomp, do_swap: i32)1417     pub fn maybe_set(&mut self, other: &GePrecomp, do_swap: i32) {
1418         self.y_plus_x.maybe_set(&other.y_plus_x, do_swap);
1419         self.y_minus_x.maybe_set(&other.y_minus_x, do_swap);
1420         self.xy2d.maybe_set(&other.xy2d, do_swap);
1421     }
1422 
select(pos: usize, b: i8) -> GePrecomp1423     pub fn select(pos: usize, b: i8) -> GePrecomp {
1424        let bnegative = (b as u8) >> 7;
1425        let babs: u8 = (b - (((-(bnegative as i8)) & b) << 1)) as u8;
1426        let mut t = GePrecomp::zero();
1427        t.maybe_set(&GE_PRECOMP_BASE[pos][0], equal(babs, 1));
1428        t.maybe_set(&GE_PRECOMP_BASE[pos][1], equal(babs, 2));
1429        t.maybe_set(&GE_PRECOMP_BASE[pos][2], equal(babs, 3));
1430        t.maybe_set(&GE_PRECOMP_BASE[pos][3], equal(babs, 4));
1431        t.maybe_set(&GE_PRECOMP_BASE[pos][4], equal(babs, 5));
1432        t.maybe_set(&GE_PRECOMP_BASE[pos][5], equal(babs, 6));
1433        t.maybe_set(&GE_PRECOMP_BASE[pos][6], equal(babs, 7));
1434        t.maybe_set(&GE_PRECOMP_BASE[pos][7], equal(babs, 8));
1435        let minus_t = GePrecomp {
1436            y_plus_x: t.y_minus_x,
1437            y_minus_x: t.y_plus_x,
1438            xy2d: t.xy2d.neg(),
1439        };
1440        t.maybe_set(&minus_t, bnegative as i32);
1441        t
1442     }
1443 }
1444 
1445 /*
1446 h = a * B
1447 where a = a[0]+256*a[1]+...+256^31 a[31]
1448 B is the Ed25519 base point (x,4/5) with x positive.
1449 
1450 Preconditions:
1451   a[31] <= 127
1452 */
ge_scalarmult_base(a: &[u8]) -> GeP31453 pub fn ge_scalarmult_base(a: &[u8]) -> GeP3 {
1454     let mut es: [i8; 64] = [0; 64];
1455     let mut r: GeP1P1;
1456     let mut s: GeP2;
1457     let mut t: GePrecomp;
1458 
1459     for i in 0..32 {
1460         es[2 * i + 0] = ((a[i] >> 0) & 15) as i8;
1461         es[2 * i + 1] = ((a[i] >> 4) & 15) as i8;
1462     }
1463     /* each es[i] is between 0 and 15 */
1464     /* es[63] is between 0 and 7 */
1465 
1466     let mut carry: i8 = 0;
1467     for i in 0..63 {
1468         es[i] += carry;
1469         carry = es[i] + 8;
1470         carry >>= 4;
1471         es[i] -= carry << 4;
1472     }
1473     es[63] += carry;
1474     /* each es[i] is between -8 and 8 */
1475 
1476     let mut h = GeP3::zero();
1477     for i in (1..64).step_up(2) {
1478         t = GePrecomp::select(i/2, es[i]);
1479         r = h + t;
1480         h = r.to_p3();
1481     }
1482 
1483     r = h.dbl(); s = r.to_p2();
1484     r = s.dbl(); s = r.to_p2();
1485     r = s.dbl(); s = r.to_p2();
1486     r = s.dbl(); h = r.to_p3();
1487 
1488     for i in (0..64).step_up(2) {
1489         t = GePrecomp::select(i/2, es[i]);
1490         r = h + t;
1491         h = r.to_p3();
1492     }
1493 
1494     h
1495 }
1496 /*
1497 Input:
1498     s[0]+256*s[1]+...+256^63*s[63] = s
1499 
1500 Output:
1501     s[0]+256*s[1]+...+256^31*s[31] = s mod l
1502     where l = 2^252 + 27742317777372353535851937790883648493.
1503     Overwrites s in place.
1504 */
sc_reduce(s: &mut [u8])1505 pub fn sc_reduce(s: &mut [u8]) {
1506     let mut s0: i64 = 2097151 & load_3i(s);
1507     let mut s1: i64 = 2097151 & (load_4i(&s[2..6]) >> 5);
1508     let mut s2: i64 = 2097151 & (load_3i(&s[5..8]) >> 2);
1509     let mut s3: i64 = 2097151 & (load_4i(&s[7..11]) >> 7);
1510     let mut s4: i64 = 2097151 & (load_4i(&s[10..14]) >> 4);
1511     let mut s5: i64 = 2097151 & (load_3i(&s[13..16]) >> 1);
1512     let mut s6: i64 = 2097151 & (load_4i(&s[15..19]) >> 6);
1513     let mut s7: i64 = 2097151 & (load_3i(&s[18..21]) >> 3);
1514     let mut s8: i64 = 2097151 & load_3i(&s[21..24]);
1515     let mut s9: i64 = 2097151 & (load_4i(&s[23..27]) >> 5);
1516     let mut s10: i64 = 2097151 & (load_3i(&s[26..29]) >> 2);
1517     let mut s11: i64 = 2097151 & (load_4i(&s[28..32]) >> 7);
1518     let mut s12: i64 = 2097151 & (load_4i(&s[31..35]) >> 4);
1519     let mut s13: i64 = 2097151 & (load_3i(&s[34..37]) >> 1);
1520     let mut s14: i64 = 2097151 & (load_4i(&s[36..40]) >> 6);
1521     let mut s15: i64 = 2097151 & (load_3i(&s[39..42]) >> 3);
1522     let mut s16: i64 = 2097151 & load_3i(&s[42..45]);
1523     let mut s17: i64 = 2097151 & (load_4i(&s[44..48]) >> 5);
1524     let s18: i64 = 2097151 & (load_3i(&s[47..50]) >> 2);
1525     let s19: i64 = 2097151 & (load_4i(&s[49..53]) >> 7);
1526     let s20: i64 = 2097151 & (load_4i(&s[52..56]) >> 4);
1527     let s21: i64 = 2097151 & (load_3i(&s[55..58]) >> 1);
1528     let s22: i64 = 2097151 & (load_4i(&s[57..61]) >> 6);
1529     let s23: i64 = load_4i(&s[60..64]) >> 3;
1530     let mut carry0: i64;
1531     let mut carry1: i64;
1532     let mut carry2: i64;
1533     let mut carry3: i64;
1534     let mut carry4: i64;
1535     let mut carry5: i64;
1536     let mut carry6: i64;
1537     let mut carry7: i64;
1538     let mut carry8: i64;
1539     let mut carry9: i64;
1540     let mut carry10: i64;
1541     let mut carry11: i64;
1542     let carry12: i64;
1543     let carry13: i64;
1544     let carry14: i64;
1545     let carry15: i64;
1546     let carry16: i64;
1547 
1548     s11 += s23 * 666643;
1549     s12 += s23 * 470296;
1550     s13 += s23 * 654183;
1551     s14 -= s23 * 997805;
1552     s15 += s23 * 136657;
1553     s16 -= s23 * 683901;
1554 
1555 
1556     s10 += s22 * 666643;
1557     s11 += s22 * 470296;
1558     s12 += s22 * 654183;
1559     s13 -= s22 * 997805;
1560     s14 += s22 * 136657;
1561     s15 -= s22 * 683901;
1562 
1563 
1564     s9 += s21 * 666643;
1565     s10 += s21 * 470296;
1566     s11 += s21 * 654183;
1567     s12 -= s21 * 997805;
1568     s13 += s21 * 136657;
1569     s14 -= s21 * 683901;
1570 
1571 
1572     s8 += s20 * 666643;
1573     s9 += s20 * 470296;
1574     s10 += s20 * 654183;
1575     s11 -= s20 * 997805;
1576     s12 += s20 * 136657;
1577     s13 -= s20 * 683901;
1578 
1579 
1580     s7 += s19 * 666643;
1581     s8 += s19 * 470296;
1582     s9 += s19 * 654183;
1583     s10 -= s19 * 997805;
1584     s11 += s19 * 136657;
1585     s12 -= s19 * 683901;
1586 
1587 
1588     s6 += s18 * 666643;
1589     s7 += s18 * 470296;
1590     s8 += s18 * 654183;
1591     s9 -= s18 * 997805;
1592     s10 += s18 * 136657;
1593     s11 -= s18 * 683901;
1594 
1595 
1596     carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
1597     carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
1598     carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
1599     carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
1600     carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
1601     carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
1602 
1603     carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
1604     carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
1605     carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
1606     carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
1607     carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
1608 
1609     s5 += s17 * 666643;
1610     s6 += s17 * 470296;
1611     s7 += s17 * 654183;
1612     s8 -= s17 * 997805;
1613     s9 += s17 * 136657;
1614     s10 -= s17 * 683901;
1615 
1616 
1617     s4 += s16 * 666643;
1618     s5 += s16 * 470296;
1619     s6 += s16 * 654183;
1620     s7 -= s16 * 997805;
1621     s8 += s16 * 136657;
1622     s9 -= s16 * 683901;
1623 
1624 
1625     s3 += s15 * 666643;
1626     s4 += s15 * 470296;
1627     s5 += s15 * 654183;
1628     s6 -= s15 * 997805;
1629     s7 += s15 * 136657;
1630     s8 -= s15 * 683901;
1631 
1632 
1633     s2 += s14 * 666643;
1634     s3 += s14 * 470296;
1635     s4 += s14 * 654183;
1636     s5 -= s14 * 997805;
1637     s6 += s14 * 136657;
1638     s7 -= s14 * 683901;
1639 
1640 
1641     s1 += s13 * 666643;
1642     s2 += s13 * 470296;
1643     s3 += s13 * 654183;
1644     s4 -= s13 * 997805;
1645     s5 += s13 * 136657;
1646     s6 -= s13 * 683901;
1647 
1648 
1649     s0 += s12 * 666643;
1650     s1 += s12 * 470296;
1651     s2 += s12 * 654183;
1652     s3 -= s12 * 997805;
1653     s4 += s12 * 136657;
1654     s5 -= s12 * 683901;
1655     s12 = 0;
1656 
1657     carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
1658     carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
1659     carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
1660     carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
1661     carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
1662     carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
1663 
1664     carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
1665     carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
1666     carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
1667     carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
1668     carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
1669     carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
1670 
1671     s0 += s12 * 666643;
1672     s1 += s12 * 470296;
1673     s2 += s12 * 654183;
1674     s3 -= s12 * 997805;
1675     s4 += s12 * 136657;
1676     s5 -= s12 * 683901;
1677     s12 = 0;
1678 
1679     carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
1680     carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
1681     carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
1682     carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
1683     carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
1684     carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
1685     carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
1686     carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
1687     carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
1688     carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
1689     carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
1690     carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
1691 
1692     s0 += s12 * 666643;
1693     s1 += s12 * 470296;
1694     s2 += s12 * 654183;
1695     s3 -= s12 * 997805;
1696     s4 += s12 * 136657;
1697     s5 -= s12 * 683901;
1698 
1699 
1700     carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
1701     carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
1702     carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
1703     carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
1704     carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
1705     carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
1706     carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
1707     carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
1708     carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
1709     carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
1710     carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
1711 
1712     s[0] = (s0 >> 0) as u8;
1713     s[1] = (s0 >> 8) as u8;
1714     s[2] = ((s0 >> 16) | (s1 << 5)) as u8;
1715     s[3] = (s1 >> 3) as u8;
1716     s[4] = (s1 >> 11) as u8;
1717     s[5] = ((s1 >> 19) | (s2 << 2)) as u8;
1718     s[6] = (s2 >> 6) as u8;
1719     s[7] = ((s2 >> 14) | (s3 << 7)) as u8;
1720     s[8] = (s3 >> 1) as u8;
1721     s[9] = (s3 >> 9) as u8;
1722     s[10] = ((s3 >> 17) | (s4 << 4)) as u8;
1723     s[11] = (s4 >> 4) as u8;
1724     s[12] = (s4 >> 12) as u8;
1725     s[13] = ((s4 >> 20) | (s5 << 1)) as u8;
1726     s[14] = (s5 >> 7) as u8;
1727     s[15] = ((s5 >> 15) | (s6 << 6)) as u8;
1728     s[16] = (s6 >> 2) as u8;
1729     s[17] = (s6 >> 10) as u8;
1730     s[18] = ((s6 >> 18) | (s7 << 3)) as u8;
1731     s[19] = (s7 >> 5) as u8;
1732     s[20] = (s7 >> 13) as u8;
1733     s[21] = (s8 >> 0) as u8;
1734     s[22] = (s8 >> 8) as u8;
1735     s[23] = ((s8 >> 16) | (s9 << 5)) as u8;
1736     s[24] = (s9 >> 3) as u8;
1737     s[25] = (s9 >> 11) as u8;
1738     s[26] = ((s9 >> 19) | (s10 << 2)) as u8;
1739     s[27] = (s10 >> 6) as u8;
1740     s[28] = ((s10 >> 14) | (s11 << 7)) as u8;
1741     s[29] = (s11 >> 1) as u8;
1742     s[30] = (s11 >> 9) as u8;
1743     s[31] = (s11 >> 17) as u8;
1744 }
1745 
1746 
1747 /*
1748 Input:
1749     a[0]+256*a[1]+...+256^31*a[31] = a
1750     b[0]+256*b[1]+...+256^31*b[31] = b
1751     c[0]+256*c[1]+...+256^31*c[31] = c
1752 
1753 Output:
1754     s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
1755     where l = 2^252 + 27742317777372353535851937790883648493.
1756 */
sc_muladd(s: &mut[u8], a: &[u8], b: &[u8], c: &[u8])1757 pub fn sc_muladd(s: &mut[u8], a: &[u8], b: &[u8], c: &[u8]) {
1758     let a0 = 2097151 & load_3i(&a[0..3]);
1759     let a1 = 2097151 & (load_4i(&a[2..6]) >> 5);
1760     let a2 = 2097151 & (load_3i(&a[5..8]) >> 2);
1761     let a3 = 2097151 & (load_4i(&a[7..11]) >> 7);
1762     let a4 = 2097151 & (load_4i(&a[10..14]) >> 4);
1763     let a5 = 2097151 & (load_3i(&a[13..16]) >> 1);
1764     let a6 = 2097151 & (load_4i(&a[15..19]) >> 6);
1765     let a7 = 2097151 & (load_3i(&a[18..21]) >> 3);
1766     let a8 = 2097151 & load_3i(&a[21..24]);
1767     let a9 = 2097151 & (load_4i(&a[23..27]) >> 5);
1768     let a10 = 2097151 & (load_3i(&a[26..29]) >> 2);
1769     let a11 = load_4i(&a[28..32]) >> 7;
1770     let b0 = 2097151 & load_3i(&b[0..3]);
1771     let b1 = 2097151 & (load_4i(&b[2..6]) >> 5);
1772     let b2 = 2097151 & (load_3i(&b[5..8]) >> 2);
1773     let b3 = 2097151 & (load_4i(&b[7..11]) >> 7);
1774     let b4 = 2097151 & (load_4i(&b[10..14]) >> 4);
1775     let b5 = 2097151 & (load_3i(&b[13..16]) >> 1);
1776     let b6 = 2097151 & (load_4i(&b[15..19]) >> 6);
1777     let b7 = 2097151 & (load_3i(&b[18..21]) >> 3);
1778     let b8 = 2097151 & load_3i(&b[21..24]);
1779     let b9 = 2097151 & (load_4i(&b[23..27]) >> 5);
1780     let b10 = 2097151 & (load_3i(&b[26..29]) >> 2);
1781     let b11 = load_4i(&b[28..32]) >> 7;
1782     let c0 = 2097151 & load_3i(&c[0..3]);
1783     let c1 = 2097151 & (load_4i(&c[2..6]) >> 5);
1784     let c2 = 2097151 & (load_3i(&c[5..8]) >> 2);
1785     let c3 = 2097151 & (load_4i(&c[7..11]) >> 7);
1786     let c4 = 2097151 & (load_4i(&c[10..14]) >> 4);
1787     let c5 = 2097151 & (load_3i(&c[13..16]) >> 1);
1788     let c6 = 2097151 & (load_4i(&c[15..19]) >> 6);
1789     let c7 = 2097151 & (load_3i(&c[18..21]) >> 3);
1790     let c8 = 2097151 & load_3i(&c[21..24]);
1791     let c9 = 2097151 & (load_4i(&c[23..27]) >> 5);
1792     let c10 = 2097151 & (load_3i(&c[26..29]) >> 2);
1793     let c11 = load_4i(&c[28..32]) >> 7;
1794     let mut s0: i64;
1795     let mut s1: i64;
1796     let mut s2: i64;
1797     let mut s3: i64;
1798     let mut s4: i64;
1799     let mut s5: i64;
1800     let mut s6: i64;
1801     let mut s7: i64;
1802     let mut s8: i64;
1803     let mut s9: i64;
1804     let mut s10: i64;
1805     let mut s11: i64;
1806     let mut s12: i64;
1807     let mut s13: i64;
1808     let mut s14: i64;
1809     let mut s15: i64;
1810     let mut s16: i64;
1811     let mut s17: i64;
1812     let mut s18: i64;
1813     let mut s19: i64;
1814     let mut s20: i64;
1815     let mut s21: i64;
1816     let mut s22: i64;
1817     let mut s23: i64;
1818     let mut carry0: i64;
1819     let mut carry1: i64;
1820     let mut carry2: i64;
1821     let mut carry3: i64;
1822     let mut carry4: i64;
1823     let mut carry5: i64;
1824     let mut carry6: i64;
1825     let mut carry7: i64;
1826     let mut carry8: i64;
1827     let mut carry9: i64;
1828     let mut carry10: i64;
1829     let mut carry11: i64;
1830     let mut carry12: i64;
1831     let mut carry13: i64;
1832     let mut carry14: i64;
1833     let mut carry15: i64;
1834     let mut carry16: i64;
1835     let carry17: i64;
1836     let carry18: i64;
1837     let carry19: i64;
1838     let carry20: i64;
1839     let carry21: i64;
1840     let carry22: i64;
1841 
1842     s0 = c0 + a0*b0;
1843     s1 = c1 + a0*b1 + a1*b0;
1844     s2 = c2 + a0*b2 + a1*b1 + a2*b0;
1845     s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0;
1846     s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0;
1847     s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0;
1848     s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0;
1849     s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0;
1850     s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0;
1851     s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0;
1852     s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0;
1853     s11 = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0;
1854     s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1;
1855     s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2;
1856     s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3;
1857     s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4;
1858     s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5;
1859     s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6;
1860     s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7;
1861     s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8;
1862     s20 = a9*b11 + a10*b10 + a11*b9;
1863     s21 = a10*b11 + a11*b10;
1864     s22 = a11*b11;
1865     s23 = 0;
1866 
1867     carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
1868     carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
1869     carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
1870     carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
1871     carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
1872     carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
1873     carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
1874     carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
1875     carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
1876     carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21;
1877     carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21;
1878     carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21;
1879 
1880     carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
1881     carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
1882     carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
1883     carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
1884     carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
1885     carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
1886     carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
1887     carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
1888     carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21;
1889     carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21;
1890     carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21;
1891 
1892     s11 += s23 * 666643;
1893     s12 += s23 * 470296;
1894     s13 += s23 * 654183;
1895     s14 -= s23 * 997805;
1896     s15 += s23 * 136657;
1897     s16 -= s23 * 683901;
1898 
1899 
1900     s10 += s22 * 666643;
1901     s11 += s22 * 470296;
1902     s12 += s22 * 654183;
1903     s13 -= s22 * 997805;
1904     s14 += s22 * 136657;
1905     s15 -= s22 * 683901;
1906 
1907 
1908     s9 += s21 * 666643;
1909     s10 += s21 * 470296;
1910     s11 += s21 * 654183;
1911     s12 -= s21 * 997805;
1912     s13 += s21 * 136657;
1913     s14 -= s21 * 683901;
1914 
1915 
1916     s8 += s20 * 666643;
1917     s9 += s20 * 470296;
1918     s10 += s20 * 654183;
1919     s11 -= s20 * 997805;
1920     s12 += s20 * 136657;
1921     s13 -= s20 * 683901;
1922 
1923 
1924     s7 += s19 * 666643;
1925     s8 += s19 * 470296;
1926     s9 += s19 * 654183;
1927     s10 -= s19 * 997805;
1928     s11 += s19 * 136657;
1929     s12 -= s19 * 683901;
1930 
1931 
1932     s6 += s18 * 666643;
1933     s7 += s18 * 470296;
1934     s8 += s18 * 654183;
1935     s9 -= s18 * 997805;
1936     s10 += s18 * 136657;
1937     s11 -= s18 * 683901;
1938 
1939 
1940     carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
1941     carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
1942     carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
1943     carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
1944     carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
1945     carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
1946 
1947     carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
1948     carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
1949     carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
1950     carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
1951     carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
1952 
1953     s5 += s17 * 666643;
1954     s6 += s17 * 470296;
1955     s7 += s17 * 654183;
1956     s8 -= s17 * 997805;
1957     s9 += s17 * 136657;
1958     s10 -= s17 * 683901;
1959 
1960 
1961     s4 += s16 * 666643;
1962     s5 += s16 * 470296;
1963     s6 += s16 * 654183;
1964     s7 -= s16 * 997805;
1965     s8 += s16 * 136657;
1966     s9 -= s16 * 683901;
1967 
1968 
1969     s3 += s15 * 666643;
1970     s4 += s15 * 470296;
1971     s5 += s15 * 654183;
1972     s6 -= s15 * 997805;
1973     s7 += s15 * 136657;
1974     s8 -= s15 * 683901;
1975 
1976 
1977     s2 += s14 * 666643;
1978     s3 += s14 * 470296;
1979     s4 += s14 * 654183;
1980     s5 -= s14 * 997805;
1981     s6 += s14 * 136657;
1982     s7 -= s14 * 683901;
1983 
1984 
1985     s1 += s13 * 666643;
1986     s2 += s13 * 470296;
1987     s3 += s13 * 654183;
1988     s4 -= s13 * 997805;
1989     s5 += s13 * 136657;
1990     s6 -= s13 * 683901;
1991 
1992 
1993     s0 += s12 * 666643;
1994     s1 += s12 * 470296;
1995     s2 += s12 * 654183;
1996     s3 -= s12 * 997805;
1997     s4 += s12 * 136657;
1998     s5 -= s12 * 683901;
1999     s12 = 0;
2000 
2001     carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
2002     carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
2003     carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
2004     carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
2005     carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
2006     carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
2007 
2008     carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
2009     carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
2010     carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
2011     carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
2012     carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
2013     carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
2014 
2015     s0 += s12 * 666643;
2016     s1 += s12 * 470296;
2017     s2 += s12 * 654183;
2018     s3 -= s12 * 997805;
2019     s4 += s12 * 136657;
2020     s5 -= s12 * 683901;
2021     s12 = 0;
2022 
2023     carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
2024     carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
2025     carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
2026     carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
2027     carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
2028     carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
2029     carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
2030     carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
2031     carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
2032     carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
2033     carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
2034     carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
2035 
2036     s0 += s12 * 666643;
2037     s1 += s12 * 470296;
2038     s2 += s12 * 654183;
2039     s3 -= s12 * 997805;
2040     s4 += s12 * 136657;
2041     s5 -= s12 * 683901;
2042 
2043 
2044     carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
2045     carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
2046     carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
2047     carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
2048     carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
2049     carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
2050     carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
2051     carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
2052     carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
2053     carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
2054     carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
2055 
2056     s[0] = (s0 >> 0) as u8;
2057     s[1] = (s0 >> 8) as u8;
2058     s[2] = ((s0 >> 16) | (s1 << 5)) as u8;
2059     s[3] = (s1 >> 3) as u8;
2060     s[4] = (s1 >> 11) as u8;
2061     s[5] = ((s1 >> 19) | (s2 << 2)) as u8;
2062     s[6] = (s2 >> 6) as u8;
2063     s[7] = ((s2 >> 14) | (s3 << 7)) as u8;
2064     s[8] = (s3 >> 1) as u8;
2065     s[9] = (s3 >> 9) as u8;
2066     s[10] = ((s3 >> 17) | (s4 << 4)) as u8;
2067     s[11] = (s4 >> 4) as u8;
2068     s[12] = (s4 >> 12) as u8;
2069     s[13] = ((s4 >> 20) | (s5 << 1)) as u8;
2070     s[14] = (s5 >> 7) as u8;
2071     s[15] = ((s5 >> 15) | (s6 << 6)) as u8;
2072     s[16] = (s6 >> 2) as u8;
2073     s[17] = (s6 >> 10) as u8;
2074     s[18] = ((s6 >> 18) | (s7 << 3)) as u8;
2075     s[19] = (s7 >> 5) as u8;
2076     s[20] = (s7 >> 13) as u8;
2077     s[21] = (s8 >> 0) as u8;
2078     s[22] = (s8 >> 8) as u8;
2079     s[23] = ((s8 >> 16) | (s9 << 5)) as u8;
2080     s[24] = (s9 >> 3) as u8;
2081     s[25] = (s9 >> 11) as u8;
2082     s[26] = ((s9 >> 19) | (s10 << 2)) as u8;
2083     s[27] = (s10 >> 6) as u8;
2084     s[28] = ((s10 >> 14) | (s11 << 7)) as u8;
2085     s[29] = (s11 >> 1) as u8;
2086     s[30] = (s11 >> 9) as u8;
2087     s[31] = (s11 >> 17) as u8;
2088 }
2089 
2090 
curve25519(n: &[u8], p: &[u8]) -> [u8; 32]2091 pub fn curve25519(n: &[u8], p: &[u8]) -> [u8; 32] {
2092     let mut e = [0u8; 32];
2093     let mut x2;
2094     let mut z2;
2095     let mut x3;
2096     let mut z3;
2097     let mut swap: i32;
2098     let mut b: i32;
2099 
2100     for (d,s) in e.iter_mut().zip(n.iter()) {
2101       *d = *s;
2102     }
2103     e[0] &= 248;
2104     e[31] &= 127;
2105     e[31] |= 64;
2106     let x1 = Fe::from_bytes(p);
2107     x2 = FE_ONE;
2108     z2 = FE_ZERO;
2109     x3 = x1;
2110     z3 = FE_ONE;
2111 
2112     swap = 0;
2113     // pos starts at 254 and goes down to 0
2114     for pos in (0usize..255).rev() {
2115         b = (e[pos / 8] >> (pos & 7)) as i32;
2116         b &= 1;
2117         swap ^= b;
2118         x2.maybe_swap_with(&mut x3, swap);
2119         z2.maybe_swap_with(&mut z3, swap);
2120         swap = b;
2121 
2122         let d = x3 - z3;
2123         let b = x2 - z2;
2124         let a = x2 + z2;
2125         let c = x3 + z3;
2126         let da = d * a;
2127         let cb = c * b;
2128         let bb = b.square();
2129         let aa = a.square();
2130         let t0 = da + cb;
2131         let t1 = da - cb;
2132         let x4 = aa*bb;
2133         let e = aa - bb;
2134         let t2 = t1.square();
2135         let t3 = e.mul_121666();
2136         let x5 = t0.square();
2137         let t4 = bb + t3;
2138         let z5 = x1 * t2;
2139         let z4 = e*t4;
2140 
2141         z2 = z4;
2142         z3 = z5;
2143         x2 = x4;
2144         x3 = x5;
2145     }
2146     x2.maybe_swap_with(&mut x3, swap);
2147     z2.maybe_swap_with(&mut z3, swap);
2148 
2149     (z2.invert() * x2).to_bytes()
2150 }
2151 
curve25519_base(x: &[u8]) -> [u8; 32]2152 pub fn curve25519_base(x: &[u8]) -> [u8; 32] {
2153     let mut base : [u8; 32] = [0; 32];
2154     base[0] = 9;
2155     curve25519(x, base.as_ref())
2156 }
2157 
2158 #[cfg(test)]
2159 mod tests {
2160     use curve25519::{Fe, curve25519_base};
2161 
2162     #[test]
from_to_bytes_preserves()2163     fn from_to_bytes_preserves() {
2164         for i in 0..50 {
2165             let mut e: Vec<u8> = (0u32..32).map(|idx| (idx*(1289+i*761)) as u8).collect();
2166             e[0] &= 248;
2167             e[31] &= 127;
2168             e[31] |= 64;
2169             let fe = Fe::from_bytes(e.as_ref());
2170             let e_preserved = fe.to_bytes();
2171             assert!(e == e_preserved.to_vec());
2172         }
2173     }
2174 
2175     #[test]
swap_test()2176     fn swap_test() {
2177         let mut f = Fe([10,20,30,40,50,60,70,80,90,100]);
2178         let mut g = Fe([11,21,31,41,51,61,71,81,91,101]);
2179         let f_initial = f;
2180         let g_initial = g;
2181         f.maybe_swap_with(&mut g, 0);
2182         assert!(f == f_initial);
2183         assert!(g == g_initial);
2184 
2185         f.maybe_swap_with(&mut g, 1);
2186         assert!(f == g_initial);
2187         assert!(g == f_initial);
2188     }
2189 
2190     struct CurveGen {
2191         which: u32
2192     }
2193     impl CurveGen {
new(seed: u32) -> CurveGen2194         fn new(seed: u32) -> CurveGen {
2195             CurveGen{which: seed}
2196         }
2197     }
2198     impl Iterator for CurveGen {
2199         type Item = Fe;
2200 
next(&mut self) -> Option<Fe>2201         fn next(&mut self) -> Option<Fe> {
2202             let mut e: Vec<u8> = (0..32).map(|idx| (idx*(1289+self.which*761)) as u8).collect();
2203             e[0] &= 248;
2204             e[31] &= 127;
2205             e[31] |= 64;
2206             Some(Fe::from_bytes(e.as_ref()))
2207         }
2208     }
2209 
2210     #[test]
mul_commutes()2211     fn mul_commutes() {
2212        for (x,y) in CurveGen::new(1).zip(CurveGen::new(2)).take(40) {
2213           assert!(x*y == y*x);
2214        };
2215     }
2216 
2217     #[test]
mul_assoc()2218     fn mul_assoc() {
2219        for (x,(y,z)) in CurveGen::new(1).zip(CurveGen::new(2).zip(CurveGen::new(3))).take(40) {
2220           assert!((x*y)*z == x*(y*z));
2221        };
2222     }
2223 
2224     #[test]
invert_inverts()2225     fn invert_inverts() {
2226        for x in CurveGen::new(1).take(40) {
2227           assert!(x.invert().invert() == x);
2228        };
2229     }
2230 
2231     #[test]
square_by_mul()2232     fn square_by_mul() {
2233        for x in CurveGen::new(1).take(40) {
2234           assert!(x*x == x.square());
2235        };
2236     }
2237 
2238     #[test]
base_example()2239     fn base_example() {
2240         let sk : [u8; 32] = [
2241             0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1,
2242             0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0,
2243             0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a ];
2244         let pk = curve25519_base(sk.as_ref());
2245         let correct : [u8; 32] = [
2246              0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
2247             ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
2248             ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
2249             ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a ];
2250         assert_eq!(pk.to_vec(), correct.to_vec());
2251     }
2252 }
2253 
2254 static BI: [GePrecomp; 8] = [
2255     GePrecomp {
2256         y_plus_x: Fe([ 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 ]),
2257         y_minus_x: Fe([ -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 ]),
2258         xy2d: Fe([ -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 ]),
2259     },
2260     GePrecomp {
2261         y_plus_x: Fe([ 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 ]),
2262         y_minus_x: Fe([ 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 ]),
2263         xy2d: Fe([ 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 ]),
2264     },
2265     GePrecomp {
2266         y_plus_x: Fe([ 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 ]),
2267         y_minus_x: Fe([ 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 ]),
2268         xy2d: Fe([ 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 ]),
2269     },
2270     GePrecomp {
2271         y_plus_x: Fe([ 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 ]),
2272         y_minus_x: Fe([ -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 ]),
2273         xy2d: Fe([ 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 ]),
2274     },
2275     GePrecomp {
2276         y_plus_x: Fe([ -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 ]),
2277         y_minus_x: Fe([ -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 ]),
2278         xy2d: Fe([ 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 ]),
2279     },
2280     GePrecomp {
2281         y_plus_x: Fe([ -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 ]),
2282         y_minus_x: Fe([ 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 ]),
2283         xy2d: Fe([ 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 ]),
2284     },
2285     GePrecomp {
2286         y_plus_x: Fe([ -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 ]),
2287         y_minus_x: Fe([ -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 ]),
2288         xy2d: Fe([ -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 ]),
2289     },
2290     GePrecomp {
2291         y_plus_x: Fe([ -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 ]),
2292         y_minus_x: Fe([ -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 ]),
2293         xy2d: Fe([ -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 ]),
2294     },
2295 ];
2296 
2297 static GE_PRECOMP_BASE : [[GePrecomp; 8]; 32] = [
2298 [
2299  GePrecomp {
2300   y_plus_x: Fe([25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605]),
2301   y_minus_x: Fe([-12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378]),
2302   xy2d: Fe([-8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546]),
2303  },
2304  GePrecomp {
2305   y_plus_x: Fe([-12815894,-12976347,-21581243,11784320,-25355658,-2750717,-11717903,-3814571,-358445,-10211303]),
2306   y_minus_x: Fe([-21703237,6903825,27185491,6451973,-29577724,-9554005,-15616551,11189268,-26829678,-5319081]),
2307   xy2d: Fe([26966642,11152617,32442495,15396054,14353839,-12752335,-3128826,-9541118,-15472047,-4166697]),
2308  },
2309  GePrecomp {
2310   y_plus_x: Fe([15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024]),
2311   y_minus_x: Fe([16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574]),
2312   xy2d: Fe([30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357]),
2313  },
2314  GePrecomp {
2315   y_plus_x: Fe([-17036878,13921892,10945806,-6033431,27105052,-16084379,-28926210,15006023,3284568,-6276540]),
2316   y_minus_x: Fe([23599295,-8306047,-11193664,-7687416,13236774,10506355,7464579,9656445,13059162,10374397]),
2317   xy2d: Fe([7798556,16710257,3033922,2874086,28997861,2835604,32406664,-3839045,-641708,-101325]),
2318  },
2319  GePrecomp {
2320   y_plus_x: Fe([10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380]),
2321   y_minus_x: Fe([4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306]),
2322   xy2d: Fe([19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942]),
2323  },
2324  GePrecomp {
2325   y_plus_x: Fe([-15371964,-12862754,32573250,4720197,-26436522,5875511,-19188627,-15224819,-9818940,-12085777]),
2326   y_minus_x: Fe([-8549212,109983,15149363,2178705,22900618,4543417,3044240,-15689887,1762328,14866737]),
2327   xy2d: Fe([-18199695,-15951423,-10473290,1707278,-17185920,3916101,-28236412,3959421,27914454,4383652]),
2328  },
2329  GePrecomp {
2330   y_plus_x: Fe([5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766]),
2331   y_minus_x: Fe([-30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701]),
2332   xy2d: Fe([28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300]),
2333  },
2334  GePrecomp {
2335   y_plus_x: Fe([14499471,-2729599,-33191113,-4254652,28494862,14271267,30290735,10876454,-33154098,2381726]),
2336   y_minus_x: Fe([-7195431,-2655363,-14730155,462251,-27724326,3941372,-6236617,3696005,-32300832,15351955]),
2337   xy2d: Fe([27431194,8222322,16448760,-3907995,-18707002,11938355,-32961401,-2970515,29551813,10109425]),
2338  },
2339 ],
2340 [
2341  GePrecomp {
2342   y_plus_x: Fe([-13657040,-13155431,-31283750,11777098,21447386,6519384,-2378284,-1627556,10092783,-4764171]),
2343   y_minus_x: Fe([27939166,14210322,4677035,16277044,-22964462,-12398139,-32508754,12005538,-17810127,12803510]),
2344   xy2d: Fe([17228999,-15661624,-1233527,300140,-1224870,-11714777,30364213,-9038194,18016357,4397660]),
2345  },
2346  GePrecomp {
2347   y_plus_x: Fe([-10958843,-7690207,4776341,-14954238,27850028,-15602212,-26619106,14544525,-17477504,982639]),
2348   y_minus_x: Fe([29253598,15796703,-2863982,-9908884,10057023,3163536,7332899,-4120128,-21047696,9934963]),
2349   xy2d: Fe([5793303,16271923,-24131614,-10116404,29188560,1206517,-14747930,4559895,-30123922,-10897950]),
2350  },
2351  GePrecomp {
2352   y_plus_x: Fe([-27643952,-11493006,16282657,-11036493,28414021,-15012264,24191034,4541697,-13338309,5500568]),
2353   y_minus_x: Fe([12650548,-1497113,9052871,11355358,-17680037,-8400164,-17430592,12264343,10874051,13524335]),
2354   xy2d: Fe([25556948,-3045990,714651,2510400,23394682,-10415330,33119038,5080568,-22528059,5376628]),
2355  },
2356  GePrecomp {
2357   y_plus_x: Fe([-26088264,-4011052,-17013699,-3537628,-6726793,1920897,-22321305,-9447443,4535768,1569007]),
2358   y_minus_x: Fe([-2255422,14606630,-21692440,-8039818,28430649,8775819,-30494562,3044290,31848280,12543772]),
2359   xy2d: Fe([-22028579,2943893,-31857513,6777306,13784462,-4292203,-27377195,-2062731,7718482,14474653]),
2360  },
2361  GePrecomp {
2362   y_plus_x: Fe([2385315,2454213,-22631320,46603,-4437935,-15680415,656965,-7236665,24316168,-5253567]),
2363   y_minus_x: Fe([13741529,10911568,-33233417,-8603737,-20177830,-1033297,33040651,-13424532,-20729456,8321686]),
2364   xy2d: Fe([21060490,-2212744,15712757,-4336099,1639040,10656336,23845965,-11874838,-9984458,608372]),
2365  },
2366  GePrecomp {
2367   y_plus_x: Fe([-13672732,-15087586,-10889693,-7557059,-6036909,11305547,1123968,-6780577,27229399,23887]),
2368   y_minus_x: Fe([-23244140,-294205,-11744728,14712571,-29465699,-2029617,12797024,-6440308,-1633405,16678954]),
2369   xy2d: Fe([-29500620,4770662,-16054387,14001338,7830047,9564805,-1508144,-4795045,-17169265,4904953]),
2370  },
2371  GePrecomp {
2372   y_plus_x: Fe([24059557,14617003,19037157,-15039908,19766093,-14906429,5169211,16191880,2128236,-4326833]),
2373   y_minus_x: Fe([-16981152,4124966,-8540610,-10653797,30336522,-14105247,-29806336,916033,-6882542,-2986532]),
2374   xy2d: Fe([-22630907,12419372,-7134229,-7473371,-16478904,16739175,285431,2763829,15736322,4143876]),
2375  },
2376  GePrecomp {
2377   y_plus_x: Fe([2379352,11839345,-4110402,-5988665,11274298,794957,212801,-14594663,23527084,-16458268]),
2378   y_minus_x: Fe([33431127,-11130478,-17838966,-15626900,8909499,8376530,-32625340,4087881,-15188911,-14416214]),
2379   xy2d: Fe([1767683,7197987,-13205226,-2022635,-13091350,448826,5799055,4357868,-4774191,-16323038]),
2380  },
2381 ],
2382 [
2383  GePrecomp {
2384   y_plus_x: Fe([6721966,13833823,-23523388,-1551314,26354293,-11863321,23365147,-3949732,7390890,2759800]),
2385   y_minus_x: Fe([4409041,2052381,23373853,10530217,7676779,-12885954,21302353,-4264057,1244380,-12919645]),
2386   xy2d: Fe([-4421239,7169619,4982368,-2957590,30256825,-2777540,14086413,9208236,15886429,16489664]),
2387  },
2388  GePrecomp {
2389   y_plus_x: Fe([1996075,10375649,14346367,13311202,-6874135,-16438411,-13693198,398369,-30606455,-712933]),
2390   y_minus_x: Fe([-25307465,9795880,-2777414,14878809,-33531835,14780363,13348553,12076947,-30836462,5113182]),
2391   xy2d: Fe([-17770784,11797796,31950843,13929123,-25888302,12288344,-30341101,-7336386,13847711,5387222]),
2392  },
2393  GePrecomp {
2394   y_plus_x: Fe([-18582163,-3416217,17824843,-2340966,22744343,-10442611,8763061,3617786,-19600662,10370991]),
2395   y_minus_x: Fe([20246567,-14369378,22358229,-543712,18507283,-10413996,14554437,-8746092,32232924,16763880]),
2396   xy2d: Fe([9648505,10094563,26416693,14745928,-30374318,-6472621,11094161,15689506,3140038,-16510092]),
2397  },
2398  GePrecomp {
2399   y_plus_x: Fe([-16160072,5472695,31895588,4744994,8823515,10365685,-27224800,9448613,-28774454,366295]),
2400   y_minus_x: Fe([19153450,11523972,-11096490,-6503142,-24647631,5420647,28344573,8041113,719605,11671788]),
2401   xy2d: Fe([8678025,2694440,-6808014,2517372,4964326,11152271,-15432916,-15266516,27000813,-10195553]),
2402  },
2403  GePrecomp {
2404   y_plus_x: Fe([-15157904,7134312,8639287,-2814877,-7235688,10421742,564065,5336097,6750977,-14521026]),
2405   y_minus_x: Fe([11836410,-3979488,26297894,16080799,23455045,15735944,1695823,-8819122,8169720,16220347]),
2406   xy2d: Fe([-18115838,8653647,17578566,-6092619,-8025777,-16012763,-11144307,-2627664,-5990708,-14166033]),
2407  },
2408  GePrecomp {
2409   y_plus_x: Fe([-23308498,-10968312,15213228,-10081214,-30853605,-11050004,27884329,2847284,2655861,1738395]),
2410   y_minus_x: Fe([-27537433,-14253021,-25336301,-8002780,-9370762,8129821,21651608,-3239336,-19087449,-11005278]),
2411   xy2d: Fe([1533110,3437855,23735889,459276,29970501,11335377,26030092,5821408,10478196,8544890]),
2412  },
2413  GePrecomp {
2414   y_plus_x: Fe([32173121,-16129311,24896207,3921497,22579056,-3410854,19270449,12217473,17789017,-3395995]),
2415   y_minus_x: Fe([-30552961,-2228401,-15578829,-10147201,13243889,517024,15479401,-3853233,30460520,1052596]),
2416   xy2d: Fe([-11614875,13323618,32618793,8175907,-15230173,12596687,27491595,-4612359,3179268,-9478891]),
2417  },
2418  GePrecomp {
2419   y_plus_x: Fe([31947069,-14366651,-4640583,-15339921,-15125977,-6039709,-14756777,-16411740,19072640,-9511060]),
2420   y_minus_x: Fe([11685058,11822410,3158003,-13952594,33402194,-4165066,5977896,-5215017,473099,5040608]),
2421   xy2d: Fe([-20290863,8198642,-27410132,11602123,1290375,-2799760,28326862,1721092,-19558642,-3131606]),
2422  },
2423 ],
2424 [
2425  GePrecomp {
2426   y_plus_x: Fe([7881532,10687937,7578723,7738378,-18951012,-2553952,21820786,8076149,-27868496,11538389]),
2427   y_minus_x: Fe([-19935666,3899861,18283497,-6801568,-15728660,-11249211,8754525,7446702,-5676054,5797016]),
2428   xy2d: Fe([-11295600,-3793569,-15782110,-7964573,12708869,-8456199,2014099,-9050574,-2369172,-5877341]),
2429  },
2430  GePrecomp {
2431   y_plus_x: Fe([-22472376,-11568741,-27682020,1146375,18956691,16640559,1192730,-3714199,15123619,10811505]),
2432   y_minus_x: Fe([14352098,-3419715,-18942044,10822655,32750596,4699007,-70363,15776356,-28886779,-11974553]),
2433   xy2d: Fe([-28241164,-8072475,-4978962,-5315317,29416931,1847569,-20654173,-16484855,4714547,-9600655]),
2434  },
2435  GePrecomp {
2436   y_plus_x: Fe([15200332,8368572,19679101,15970074,-31872674,1959451,24611599,-4543832,-11745876,12340220]),
2437   y_minus_x: Fe([12876937,-10480056,33134381,6590940,-6307776,14872440,9613953,8241152,15370987,9608631]),
2438   xy2d: Fe([-4143277,-12014408,8446281,-391603,4407738,13629032,-7724868,15866074,-28210621,-8814099]),
2439  },
2440  GePrecomp {
2441   y_plus_x: Fe([26660628,-15677655,8393734,358047,-7401291,992988,-23904233,858697,20571223,8420556]),
2442   y_minus_x: Fe([14620715,13067227,-15447274,8264467,14106269,15080814,33531827,12516406,-21574435,-12476749]),
2443   xy2d: Fe([236881,10476226,57258,-14677024,6472998,2466984,17258519,7256740,8791136,15069930]),
2444  },
2445  GePrecomp {
2446   y_plus_x: Fe([1276410,-9371918,22949635,-16322807,-23493039,-5702186,14711875,4874229,-30663140,-2331391]),
2447   y_minus_x: Fe([5855666,4990204,-13711848,7294284,-7804282,1924647,-1423175,-7912378,-33069337,9234253]),
2448   xy2d: Fe([20590503,-9018988,31529744,-7352666,-2706834,10650548,31559055,-11609587,18979186,13396066]),
2449  },
2450  GePrecomp {
2451   y_plus_x: Fe([24474287,4968103,22267082,4407354,24063882,-8325180,-18816887,13594782,33514650,7021958]),
2452   y_minus_x: Fe([-11566906,-6565505,-21365085,15928892,-26158305,4315421,-25948728,-3916677,-21480480,12868082]),
2453   xy2d: Fe([-28635013,13504661,19988037,-2132761,21078225,6443208,-21446107,2244500,-12455797,-8089383]),
2454  },
2455  GePrecomp {
2456   y_plus_x: Fe([-30595528,13793479,-5852820,319136,-25723172,-6263899,33086546,8957937,-15233648,5540521]),
2457   y_minus_x: Fe([-11630176,-11503902,-8119500,-7643073,2620056,1022908,-23710744,-1568984,-16128528,-14962807]),
2458   xy2d: Fe([23152971,775386,27395463,14006635,-9701118,4649512,1689819,892185,-11513277,-15205948]),
2459  },
2460  GePrecomp {
2461   y_plus_x: Fe([9770129,9586738,26496094,4324120,1556511,-3550024,27453819,4763127,-19179614,5867134]),
2462   y_minus_x: Fe([-32765025,1927590,31726409,-4753295,23962434,-16019500,27846559,5931263,-29749703,-16108455]),
2463   xy2d: Fe([27461885,-2977536,22380810,1815854,-23033753,-3031938,7283490,-15148073,-19526700,7734629]),
2464  },
2465 ],
2466 [
2467  GePrecomp {
2468   y_plus_x: Fe([-8010264,-9590817,-11120403,6196038,29344158,-13430885,7585295,-3176626,18549497,15302069]),
2469   y_minus_x: Fe([-32658337,-6171222,-7672793,-11051681,6258878,13504381,10458790,-6418461,-8872242,8424746]),
2470   xy2d: Fe([24687205,8613276,-30667046,-3233545,1863892,-1830544,19206234,7134917,-11284482,-828919]),
2471  },
2472  GePrecomp {
2473   y_plus_x: Fe([11334899,-9218022,8025293,12707519,17523892,-10476071,10243738,-14685461,-5066034,16498837]),
2474   y_minus_x: Fe([8911542,6887158,-9584260,-6958590,11145641,-9543680,17303925,-14124238,6536641,10543906]),
2475   xy2d: Fe([-28946384,15479763,-17466835,568876,-1497683,11223454,-2669190,-16625574,-27235709,8876771]),
2476  },
2477  GePrecomp {
2478   y_plus_x: Fe([-25742899,-12566864,-15649966,-846607,-33026686,-796288,-33481822,15824474,-604426,-9039817]),
2479   y_minus_x: Fe([10330056,70051,7957388,-9002667,9764902,15609756,27698697,-4890037,1657394,3084098]),
2480   xy2d: Fe([10477963,-7470260,12119566,-13250805,29016247,-5365589,31280319,14396151,-30233575,15272409]),
2481  },
2482  GePrecomp {
2483   y_plus_x: Fe([-12288309,3169463,28813183,16658753,25116432,-5630466,-25173957,-12636138,-25014757,1950504]),
2484   y_minus_x: Fe([-26180358,9489187,11053416,-14746161,-31053720,5825630,-8384306,-8767532,15341279,8373727]),
2485   xy2d: Fe([28685821,7759505,-14378516,-12002860,-31971820,4079242,298136,-10232602,-2878207,15190420]),
2486  },
2487  GePrecomp {
2488   y_plus_x: Fe([-32932876,13806336,-14337485,-15794431,-24004620,10940928,8669718,2742393,-26033313,-6875003]),
2489   y_minus_x: Fe([-1580388,-11729417,-25979658,-11445023,-17411874,-10912854,9291594,-16247779,-12154742,6048605]),
2490   xy2d: Fe([-30305315,14843444,1539301,11864366,20201677,1900163,13934231,5128323,11213262,9168384]),
2491  },
2492  GePrecomp {
2493   y_plus_x: Fe([-26280513,11007847,19408960,-940758,-18592965,-4328580,-5088060,-11105150,20470157,-16398701]),
2494   y_minus_x: Fe([-23136053,9282192,14855179,-15390078,-7362815,-14408560,-22783952,14461608,14042978,5230683]),
2495   xy2d: Fe([29969567,-2741594,-16711867,-8552442,9175486,-2468974,21556951,3506042,-5933891,-12449708]),
2496  },
2497  GePrecomp {
2498   y_plus_x: Fe([-3144746,8744661,19704003,4581278,-20430686,6830683,-21284170,8971513,-28539189,15326563]),
2499   y_minus_x: Fe([-19464629,10110288,-17262528,-3503892,-23500387,1355669,-15523050,15300988,-20514118,9168260]),
2500   xy2d: Fe([-5353335,4488613,-23803248,16314347,7780487,-15638939,-28948358,9601605,33087103,-9011387]),
2501  },
2502  GePrecomp {
2503   y_plus_x: Fe([-19443170,-15512900,-20797467,-12445323,-29824447,10229461,-27444329,-15000531,-5996870,15664672]),
2504   y_minus_x: Fe([23294591,-16632613,-22650781,-8470978,27844204,11461195,13099750,-2460356,18151676,13417686]),
2505   xy2d: Fe([-24722913,-4176517,-31150679,5988919,-26858785,6685065,1661597,-12551441,15271676,-15452665]),
2506  },
2507 ],
2508 [
2509  GePrecomp {
2510   y_plus_x: Fe([11433042,-13228665,8239631,-5279517,-1985436,-725718,-18698764,2167544,-6921301,-13440182]),
2511   y_minus_x: Fe([-31436171,15575146,30436815,12192228,-22463353,9395379,-9917708,-8638997,12215110,12028277]),
2512   xy2d: Fe([14098400,6555944,23007258,5757252,-15427832,-12950502,30123440,4617780,-16900089,-655628]),
2513  },
2514  GePrecomp {
2515   y_plus_x: Fe([-4026201,-15240835,11893168,13718664,-14809462,1847385,-15819999,10154009,23973261,-12684474]),
2516   y_minus_x: Fe([-26531820,-3695990,-1908898,2534301,-31870557,-16550355,18341390,-11419951,32013174,-10103539]),
2517   xy2d: Fe([-25479301,10876443,-11771086,-14625140,-12369567,1838104,21911214,6354752,4425632,-837822]),
2518  },
2519  GePrecomp {
2520   y_plus_x: Fe([-10433389,-14612966,22229858,-3091047,-13191166,776729,-17415375,-12020462,4725005,14044970]),
2521   y_minus_x: Fe([19268650,-7304421,1555349,8692754,-21474059,-9910664,6347390,-1411784,-19522291,-16109756]),
2522   xy2d: Fe([-24864089,12986008,-10898878,-5558584,-11312371,-148526,19541418,8180106,9282262,10282508]),
2523  },
2524  GePrecomp {
2525   y_plus_x: Fe([-26205082,4428547,-8661196,-13194263,4098402,-14165257,15522535,8372215,5542595,-10702683]),
2526   y_minus_x: Fe([-10562541,14895633,26814552,-16673850,-17480754,-2489360,-2781891,6993761,-18093885,10114655]),
2527   xy2d: Fe([-20107055,-929418,31422704,10427861,-7110749,6150669,-29091755,-11529146,25953725,-106158]),
2528  },
2529  GePrecomp {
2530   y_plus_x: Fe([-4234397,-8039292,-9119125,3046000,2101609,-12607294,19390020,6094296,-3315279,12831125]),
2531   y_minus_x: Fe([-15998678,7578152,5310217,14408357,-33548620,-224739,31575954,6326196,7381791,-2421839]),
2532   xy2d: Fe([-20902779,3296811,24736065,-16328389,18374254,7318640,6295303,8082724,-15362489,12339664]),
2533  },
2534  GePrecomp {
2535   y_plus_x: Fe([27724736,2291157,6088201,-14184798,1792727,5857634,13848414,15768922,25091167,14856294]),
2536   y_minus_x: Fe([-18866652,8331043,24373479,8541013,-701998,-9269457,12927300,-12695493,-22182473,-9012899]),
2537   xy2d: Fe([-11423429,-5421590,11632845,3405020,30536730,-11674039,-27260765,13866390,30146206,9142070]),
2538  },
2539  GePrecomp {
2540   y_plus_x: Fe([3924129,-15307516,-13817122,-10054960,12291820,-668366,-27702774,9326384,-8237858,4171294]),
2541   y_minus_x: Fe([-15921940,16037937,6713787,16606682,-21612135,2790944,26396185,3731949,345228,-5462949]),
2542   xy2d: Fe([-21327538,13448259,25284571,1143661,20614966,-8849387,2031539,-12391231,-16253183,-13582083]),
2543  },
2544  GePrecomp {
2545   y_plus_x: Fe([31016211,-16722429,26371392,-14451233,-5027349,14854137,17477601,3842657,28012650,-16405420]),
2546   y_minus_x: Fe([-5075835,9368966,-8562079,-4600902,-15249953,6970560,-9189873,16292057,-8867157,3507940]),
2547   xy2d: Fe([29439664,3537914,23333589,6997794,-17555561,-11018068,-15209202,-15051267,-9164929,6580396]),
2548  },
2549 ],
2550 [
2551  GePrecomp {
2552   y_plus_x: Fe([-12185861,-7679788,16438269,10826160,-8696817,-6235611,17860444,-9273846,-2095802,9304567]),
2553   y_minus_x: Fe([20714564,-4336911,29088195,7406487,11426967,-5095705,14792667,-14608617,5289421,-477127]),
2554   xy2d: Fe([-16665533,-10650790,-6160345,-13305760,9192020,-1802462,17271490,12349094,26939669,-3752294]),
2555  },
2556  GePrecomp {
2557   y_plus_x: Fe([-12889898,9373458,31595848,16374215,21471720,13221525,-27283495,-12348559,-3698806,117887]),
2558   y_minus_x: Fe([22263325,-6560050,3984570,-11174646,-15114008,-566785,28311253,5358056,-23319780,541964]),
2559   xy2d: Fe([16259219,3261970,2309254,-15534474,-16885711,-4581916,24134070,-16705829,-13337066,-13552195]),
2560  },
2561  GePrecomp {
2562   y_plus_x: Fe([9378160,-13140186,-22845982,-12745264,28198281,-7244098,-2399684,-717351,690426,14876244]),
2563   y_minus_x: Fe([24977353,-314384,-8223969,-13465086,28432343,-1176353,-13068804,-12297348,-22380984,6618999]),
2564   xy2d: Fe([-1538174,11685646,12944378,13682314,-24389511,-14413193,8044829,-13817328,32239829,-5652762]),
2565  },
2566  GePrecomp {
2567   y_plus_x: Fe([-18603066,4762990,-926250,8885304,-28412480,-3187315,9781647,-10350059,32779359,5095274]),
2568   y_minus_x: Fe([-33008130,-5214506,-32264887,-3685216,9460461,-9327423,-24601656,14506724,21639561,-2630236]),
2569   xy2d: Fe([-16400943,-13112215,25239338,15531969,3987758,-4499318,-1289502,-6863535,17874574,558605]),
2570  },
2571  GePrecomp {
2572   y_plus_x: Fe([-13600129,10240081,9171883,16131053,-20869254,9599700,33499487,5080151,2085892,5119761]),
2573   y_minus_x: Fe([-22205145,-2519528,-16381601,414691,-25019550,2170430,30634760,-8363614,-31999993,-5759884]),
2574   xy2d: Fe([-6845704,15791202,8550074,-1312654,29928809,-12092256,27534430,-7192145,-22351378,12961482]),
2575  },
2576  GePrecomp {
2577   y_plus_x: Fe([-24492060,-9570771,10368194,11582341,-23397293,-2245287,16533930,8206996,-30194652,-5159638]),
2578   y_minus_x: Fe([-11121496,-3382234,2307366,6362031,-135455,8868177,-16835630,7031275,7589640,8945490]),
2579   xy2d: Fe([-32152748,8917967,6661220,-11677616,-1192060,-15793393,7251489,-11182180,24099109,-14456170]),
2580  },
2581  GePrecomp {
2582   y_plus_x: Fe([5019558,-7907470,4244127,-14714356,-26933272,6453165,-19118182,-13289025,-6231896,-10280736]),
2583   y_minus_x: Fe([10853594,10721687,26480089,5861829,-22995819,1972175,-1866647,-10557898,-3363451,-6441124]),
2584   xy2d: Fe([-17002408,5906790,221599,-6563147,7828208,-13248918,24362661,-2008168,-13866408,7421392]),
2585  },
2586  GePrecomp {
2587   y_plus_x: Fe([8139927,-6546497,32257646,-5890546,30375719,1886181,-21175108,15441252,28826358,-4123029]),
2588   y_minus_x: Fe([6267086,9695052,7709135,-16603597,-32869068,-1886135,14795160,-7840124,13746021,-1742048]),
2589   xy2d: Fe([28584902,7787108,-6732942,-15050729,22846041,-7571236,-3181936,-363524,4771362,-8419958]),
2590  },
2591 ],
2592 [
2593  GePrecomp {
2594   y_plus_x: Fe([24949256,6376279,-27466481,-8174608,-18646154,-9930606,33543569,-12141695,3569627,11342593]),
2595   y_minus_x: Fe([26514989,4740088,27912651,3697550,19331575,-11472339,6809886,4608608,7325975,-14801071]),
2596   xy2d: Fe([-11618399,-14554430,-24321212,7655128,-1369274,5214312,-27400540,10258390,-17646694,-8186692]),
2597  },
2598  GePrecomp {
2599   y_plus_x: Fe([11431204,15823007,26570245,14329124,18029990,4796082,-31446179,15580664,9280358,-3973687]),
2600   y_minus_x: Fe([-160783,-10326257,-22855316,-4304997,-20861367,-13621002,-32810901,-11181622,-15545091,4387441]),
2601   xy2d: Fe([-20799378,12194512,3937617,-5805892,-27154820,9340370,-24513992,8548137,20617071,-7482001]),
2602  },
2603  GePrecomp {
2604   y_plus_x: Fe([-938825,-3930586,-8714311,16124718,24603125,-6225393,-13775352,-11875822,24345683,10325460]),
2605   y_minus_x: Fe([-19855277,-1568885,-22202708,8714034,14007766,6928528,16318175,-1010689,4766743,3552007]),
2606   xy2d: Fe([-21751364,-16730916,1351763,-803421,-4009670,3950935,3217514,14481909,10988822,-3994762]),
2607  },
2608  GePrecomp {
2609   y_plus_x: Fe([15564307,-14311570,3101243,5684148,30446780,-8051356,12677127,-6505343,-8295852,13296005]),
2610   y_minus_x: Fe([-9442290,6624296,-30298964,-11913677,-4670981,-2057379,31521204,9614054,-30000824,12074674]),
2611   xy2d: Fe([4771191,-135239,14290749,-13089852,27992298,14998318,-1413936,-1556716,29832613,-16391035]),
2612  },
2613  GePrecomp {
2614   y_plus_x: Fe([7064884,-7541174,-19161962,-5067537,-18891269,-2912736,25825242,5293297,-27122660,13101590]),
2615   y_minus_x: Fe([-2298563,2439670,-7466610,1719965,-27267541,-16328445,32512469,-5317593,-30356070,-4190957]),
2616   xy2d: Fe([-30006540,10162316,-33180176,3981723,-16482138,-13070044,14413974,9515896,19568978,9628812]),
2617  },
2618  GePrecomp {
2619   y_plus_x: Fe([33053803,199357,15894591,1583059,27380243,-4580435,-17838894,-6106839,-6291786,3437740]),
2620   y_minus_x: Fe([-18978877,3884493,19469877,12726490,15913552,13614290,-22961733,70104,7463304,4176122]),
2621   xy2d: Fe([-27124001,10659917,11482427,-16070381,12771467,-6635117,-32719404,-5322751,24216882,5944158]),
2622  },
2623  GePrecomp {
2624   y_plus_x: Fe([8894125,7450974,-2664149,-9765752,-28080517,-12389115,19345746,14680796,11632993,5847885]),
2625   y_minus_x: Fe([26942781,-2315317,9129564,-4906607,26024105,11769399,-11518837,6367194,-9727230,4782140]),
2626   xy2d: Fe([19916461,-4828410,-22910704,-11414391,25606324,-5972441,33253853,8220911,6358847,-1873857]),
2627  },
2628  GePrecomp {
2629   y_plus_x: Fe([801428,-2081702,16569428,11065167,29875704,96627,7908388,-4480480,-13538503,1387155]),
2630   y_minus_x: Fe([19646058,5720633,-11416706,12814209,11607948,12749789,14147075,15156355,-21866831,11835260]),
2631   xy2d: Fe([19299512,1155910,28703737,14890794,2925026,7269399,26121523,15467869,-26560550,5052483]),
2632  },
2633 ],
2634 [
2635  GePrecomp {
2636   y_plus_x: Fe([-3017432,10058206,1980837,3964243,22160966,12322533,-6431123,-12618185,12228557,-7003677]),
2637   y_minus_x: Fe([32944382,14922211,-22844894,5188528,21913450,-8719943,4001465,13238564,-6114803,8653815]),
2638   xy2d: Fe([22865569,-4652735,27603668,-12545395,14348958,8234005,24808405,5719875,28483275,2841751]),
2639  },
2640  GePrecomp {
2641   y_plus_x: Fe([-16420968,-1113305,-327719,-12107856,21886282,-15552774,-1887966,-315658,19932058,-12739203]),
2642   y_minus_x: Fe([-11656086,10087521,-8864888,-5536143,-19278573,-3055912,3999228,13239134,-4777469,-13910208]),
2643   xy2d: Fe([1382174,-11694719,17266790,9194690,-13324356,9720081,20403944,11284705,-14013818,3093230]),
2644  },
2645  GePrecomp {
2646   y_plus_x: Fe([16650921,-11037932,-1064178,1570629,-8329746,7352753,-302424,16271225,-24049421,-6691850]),
2647   y_minus_x: Fe([-21911077,-5927941,-4611316,-5560156,-31744103,-10785293,24123614,15193618,-21652117,-16739389]),
2648   xy2d: Fe([-9935934,-4289447,-25279823,4372842,2087473,10399484,31870908,14690798,17361620,11864968]),
2649  },
2650  GePrecomp {
2651   y_plus_x: Fe([-11307610,6210372,13206574,5806320,-29017692,-13967200,-12331205,-7486601,-25578460,-16240689]),
2652   y_minus_x: Fe([14668462,-12270235,26039039,15305210,25515617,4542480,10453892,6577524,9145645,-6443880]),
2653   xy2d: Fe([5974874,3053895,-9433049,-10385191,-31865124,3225009,-7972642,3936128,-5652273,-3050304]),
2654  },
2655  GePrecomp {
2656   y_plus_x: Fe([30625386,-4729400,-25555961,-12792866,-20484575,7695099,17097188,-16303496,-27999779,1803632]),
2657   y_minus_x: Fe([-3553091,9865099,-5228566,4272701,-5673832,-16689700,14911344,12196514,-21405489,7047412]),
2658   xy2d: Fe([20093277,9920966,-11138194,-5343857,13161587,12044805,-32856851,4124601,-32343828,-10257566]),
2659  },
2660  GePrecomp {
2661   y_plus_x: Fe([-20788824,14084654,-13531713,7842147,19119038,-13822605,4752377,-8714640,-21679658,2288038]),
2662   y_minus_x: Fe([-26819236,-3283715,29965059,3039786,-14473765,2540457,29457502,14625692,-24819617,12570232]),
2663   xy2d: Fe([-1063558,-11551823,16920318,12494842,1278292,-5869109,-21159943,-3498680,-11974704,4724943]),
2664  },
2665  GePrecomp {
2666   y_plus_x: Fe([17960970,-11775534,-4140968,-9702530,-8876562,-1410617,-12907383,-8659932,-29576300,1903856]),
2667   y_minus_x: Fe([23134274,-14279132,-10681997,-1611936,20684485,15770816,-12989750,3190296,26955097,14109738]),
2668   xy2d: Fe([15308788,5320727,-30113809,-14318877,22902008,7767164,29425325,-11277562,31960942,11934971]),
2669  },
2670  GePrecomp {
2671   y_plus_x: Fe([-27395711,8435796,4109644,12222639,-24627868,14818669,20638173,4875028,10491392,1379718]),
2672   y_minus_x: Fe([-13159415,9197841,3875503,-8936108,-1383712,-5879801,33518459,16176658,21432314,12180697]),
2673   xy2d: Fe([-11787308,11500838,13787581,-13832590,-22430679,10140205,1465425,12689540,-10301319,-13872883]),
2674  },
2675 ],
2676 [
2677  GePrecomp {
2678   y_plus_x: Fe([5414091,-15386041,-21007664,9643570,12834970,1186149,-2622916,-1342231,26128231,6032912]),
2679   y_minus_x: Fe([-26337395,-13766162,32496025,-13653919,17847801,-12669156,3604025,8316894,-25875034,-10437358]),
2680   xy2d: Fe([3296484,6223048,24680646,-12246460,-23052020,5903205,-8862297,-4639164,12376617,3188849]),
2681  },
2682  GePrecomp {
2683   y_plus_x: Fe([29190488,-14659046,27549113,-1183516,3520066,-10697301,32049515,-7309113,-16109234,-9852307]),
2684   y_minus_x: Fe([-14744486,-9309156,735818,-598978,-20407687,-5057904,25246078,-15795669,18640741,-960977]),
2685   xy2d: Fe([-6928835,-16430795,10361374,5642961,4910474,12345252,-31638386,-494430,10530747,1053335]),
2686  },
2687  GePrecomp {
2688   y_plus_x: Fe([-29265967,-14186805,-13538216,-12117373,-19457059,-10655384,-31462369,-2948985,24018831,15026644]),
2689   y_minus_x: Fe([-22592535,-3145277,-2289276,5953843,-13440189,9425631,25310643,13003497,-2314791,-15145616]),
2690   xy2d: Fe([-27419985,-603321,-8043984,-1669117,-26092265,13987819,-27297622,187899,-23166419,-2531735]),
2691  },
2692  GePrecomp {
2693   y_plus_x: Fe([-21744398,-13810475,1844840,5021428,-10434399,-15911473,9716667,16266922,-5070217,726099]),
2694   y_minus_x: Fe([29370922,-6053998,7334071,-15342259,9385287,2247707,-13661962,-4839461,30007388,-15823341]),
2695   xy2d: Fe([-936379,16086691,23751945,-543318,-1167538,-5189036,9137109,730663,9835848,4555336]),
2696  },
2697  GePrecomp {
2698   y_plus_x: Fe([-23376435,1410446,-22253753,-12899614,30867635,15826977,17693930,544696,-11985298,12422646]),
2699   y_minus_x: Fe([31117226,-12215734,-13502838,6561947,-9876867,-12757670,-5118685,-4096706,29120153,13924425]),
2700   xy2d: Fe([-17400879,-14233209,19675799,-2734756,-11006962,-5858820,-9383939,-11317700,7240931,-237388]),
2701  },
2702  GePrecomp {
2703   y_plus_x: Fe([-31361739,-11346780,-15007447,-5856218,-22453340,-12152771,1222336,4389483,3293637,-15551743]),
2704   y_minus_x: Fe([-16684801,-14444245,11038544,11054958,-13801175,-3338533,-24319580,7733547,12796905,-6335822]),
2705   xy2d: Fe([-8759414,-10817836,-25418864,10783769,-30615557,-9746811,-28253339,3647836,3222231,-11160462]),
2706  },
2707  GePrecomp {
2708   y_plus_x: Fe([18606113,1693100,-25448386,-15170272,4112353,10045021,23603893,-2048234,-7550776,2484985]),
2709   y_minus_x: Fe([9255317,-3131197,-12156162,-1004256,13098013,-9214866,16377220,-2102812,-19802075,-3034702]),
2710   xy2d: Fe([-22729289,7496160,-5742199,11329249,19991973,-3347502,-31718148,9936966,-30097688,-10618797]),
2711  },
2712  GePrecomp {
2713   y_plus_x: Fe([21878590,-5001297,4338336,13643897,-3036865,13160960,19708896,5415497,-7360503,-4109293]),
2714   y_minus_x: Fe([27736861,10103576,12500508,8502413,-3413016,-9633558,10436918,-1550276,-23659143,-8132100]),
2715   xy2d: Fe([19492550,-12104365,-29681976,-852630,-3208171,12403437,30066266,8367329,13243957,8709688]),
2716  },
2717 ],
2718 [
2719  GePrecomp {
2720   y_plus_x: Fe([12015105,2801261,28198131,10151021,24818120,-4743133,-11194191,-5645734,5150968,7274186]),
2721   y_minus_x: Fe([2831366,-12492146,1478975,6122054,23825128,-12733586,31097299,6083058,31021603,-9793610]),
2722   xy2d: Fe([-2529932,-2229646,445613,10720828,-13849527,-11505937,-23507731,16354465,15067285,-14147707]),
2723  },
2724  GePrecomp {
2725   y_plus_x: Fe([7840942,14037873,-33364863,15934016,-728213,-3642706,21403988,1057586,-19379462,-12403220]),
2726   y_minus_x: Fe([915865,-16469274,15608285,-8789130,-24357026,6060030,-17371319,8410997,-7220461,16527025]),
2727   xy2d: Fe([32922597,-556987,20336074,-16184568,10903705,-5384487,16957574,52992,23834301,6588044]),
2728  },
2729  GePrecomp {
2730   y_plus_x: Fe([32752030,11232950,3381995,-8714866,22652988,-10744103,17159699,16689107,-20314580,-1305992]),
2731   y_minus_x: Fe([-4689649,9166776,-25710296,-10847306,11576752,12733943,7924251,-2752281,1976123,-7249027]),
2732   xy2d: Fe([21251222,16309901,-2983015,-6783122,30810597,12967303,156041,-3371252,12331345,-8237197]),
2733  },
2734  GePrecomp {
2735   y_plus_x: Fe([8651614,-4477032,-16085636,-4996994,13002507,2950805,29054427,-5106970,10008136,-4667901]),
2736   y_minus_x: Fe([31486080,15114593,-14261250,12951354,14369431,-7387845,16347321,-13662089,8684155,-10532952]),
2737   xy2d: Fe([19443825,11385320,24468943,-9659068,-23919258,2187569,-26263207,-6086921,31316348,14219878]),
2738  },
2739  GePrecomp {
2740   y_plus_x: Fe([-28594490,1193785,32245219,11392485,31092169,15722801,27146014,6992409,29126555,9207390]),
2741   y_minus_x: Fe([32382935,1110093,18477781,11028262,-27411763,-7548111,-4980517,10843782,-7957600,-14435730]),
2742   xy2d: Fe([2814918,7836403,27519878,-7868156,-20894015,-11553689,-21494559,8550130,28346258,1994730]),
2743  },
2744  GePrecomp {
2745   y_plus_x: Fe([-19578299,8085545,-14000519,-3948622,2785838,-16231307,-19516951,7174894,22628102,8115180]),
2746   y_minus_x: Fe([-30405132,955511,-11133838,-15078069,-32447087,-13278079,-25651578,3317160,-9943017,930272]),
2747   xy2d: Fe([-15303681,-6833769,28856490,1357446,23421993,1057177,24091212,-1388970,-22765376,-10650715]),
2748  },
2749  GePrecomp {
2750   y_plus_x: Fe([-22751231,-5303997,-12907607,-12768866,-15811511,-7797053,-14839018,-16554220,-1867018,8398970]),
2751   y_minus_x: Fe([-31969310,2106403,-4736360,1362501,12813763,16200670,22981545,-6291273,18009408,-15772772]),
2752   xy2d: Fe([-17220923,-9545221,-27784654,14166835,29815394,7444469,29551787,-3727419,19288549,1325865]),
2753  },
2754  GePrecomp {
2755   y_plus_x: Fe([15100157,-15835752,-23923978,-1005098,-26450192,15509408,12376730,-3479146,33166107,-8042750]),
2756   y_minus_x: Fe([20909231,13023121,-9209752,16251778,-5778415,-8094914,12412151,10018715,2213263,-13878373]),
2757   xy2d: Fe([32529814,-11074689,30361439,-16689753,-9135940,1513226,22922121,6382134,-5766928,8371348]),
2758  },
2759 ],
2760 [
2761  GePrecomp {
2762   y_plus_x: Fe([9923462,11271500,12616794,3544722,-29998368,-1721626,12891687,-8193132,-26442943,10486144]),
2763   y_minus_x: Fe([-22597207,-7012665,8587003,-8257861,4084309,-12970062,361726,2610596,-23921530,-11455195]),
2764   xy2d: Fe([5408411,-1136691,-4969122,10561668,24145918,14240566,31319731,-4235541,19985175,-3436086]),
2765  },
2766  GePrecomp {
2767   y_plus_x: Fe([-13994457,16616821,14549246,3341099,32155958,13648976,-17577068,8849297,65030,8370684]),
2768   y_minus_x: Fe([-8320926,-12049626,31204563,5839400,-20627288,-1057277,-19442942,6922164,12743482,-9800518]),
2769   xy2d: Fe([-2361371,12678785,28815050,4759974,-23893047,4884717,23783145,11038569,18800704,255233]),
2770  },
2771  GePrecomp {
2772   y_plus_x: Fe([-5269658,-1773886,13957886,7990715,23132995,728773,13393847,9066957,19258688,-14753793]),
2773   y_minus_x: Fe([-2936654,-10827535,-10432089,14516793,-3640786,4372541,-31934921,2209390,-1524053,2055794]),
2774   xy2d: Fe([580882,16705327,5468415,-2683018,-30926419,-14696000,-7203346,-8994389,-30021019,7394435]),
2775  },
2776  GePrecomp {
2777   y_plus_x: Fe([23838809,1822728,-15738443,15242727,8318092,-3733104,-21672180,-3492205,-4821741,14799921]),
2778   y_minus_x: Fe([13345610,9759151,3371034,-16137791,16353039,8577942,31129804,13496856,-9056018,7402518]),
2779   xy2d: Fe([2286874,-4435931,-20042458,-2008336,-13696227,5038122,11006906,-15760352,8205061,1607563]),
2780  },
2781  GePrecomp {
2782   y_plus_x: Fe([14414086,-8002132,3331830,-3208217,22249151,-5594188,18364661,-2906958,30019587,-9029278]),
2783   y_minus_x: Fe([-27688051,1585953,-10775053,931069,-29120221,-11002319,-14410829,12029093,9944378,8024]),
2784   xy2d: Fe([4368715,-3709630,29874200,-15022983,-20230386,-11410704,-16114594,-999085,-8142388,5640030]),
2785  },
2786  GePrecomp {
2787   y_plus_x: Fe([10299610,13746483,11661824,16234854,7630238,5998374,9809887,-16694564,15219798,-14327783]),
2788   y_minus_x: Fe([27425505,-5719081,3055006,10660664,23458024,595578,-15398605,-1173195,-18342183,9742717]),
2789   xy2d: Fe([6744077,2427284,26042789,2720740,-847906,1118974,32324614,7406442,12420155,1994844]),
2790  },
2791  GePrecomp {
2792   y_plus_x: Fe([14012521,-5024720,-18384453,-9578469,-26485342,-3936439,-13033478,-10909803,24319929,-6446333]),
2793   y_minus_x: Fe([16412690,-4507367,10772641,15929391,-17068788,-4658621,10555945,-10484049,-30102368,-4739048]),
2794   xy2d: Fe([22397382,-7767684,-9293161,-12792868,17166287,-9755136,-27333065,6199366,21880021,-12250760]),
2795  },
2796  GePrecomp {
2797   y_plus_x: Fe([-4283307,5368523,-31117018,8163389,-30323063,3209128,16557151,8890729,8840445,4957760]),
2798   y_minus_x: Fe([-15447727,709327,-6919446,-10870178,-29777922,6522332,-21720181,12130072,-14796503,5005757]),
2799   xy2d: Fe([-2114751,-14308128,23019042,15765735,-25269683,6002752,10183197,-13239326,-16395286,-2176112]),
2800  },
2801 ],
2802 [
2803  GePrecomp {
2804   y_plus_x: Fe([-19025756,1632005,13466291,-7995100,-23640451,16573537,-32013908,-3057104,22208662,2000468]),
2805   y_minus_x: Fe([3065073,-1412761,-25598674,-361432,-17683065,-5703415,-8164212,11248527,-3691214,-7414184]),
2806   xy2d: Fe([10379208,-6045554,8877319,1473647,-29291284,-12507580,16690915,2553332,-3132688,16400289]),
2807  },
2808  GePrecomp {
2809   y_plus_x: Fe([15716668,1254266,-18472690,7446274,-8448918,6344164,-22097271,-7285580,26894937,9132066]),
2810   y_minus_x: Fe([24158887,12938817,11085297,-8177598,-28063478,-4457083,-30576463,64452,-6817084,-2692882]),
2811   xy2d: Fe([13488534,7794716,22236231,5989356,25426474,-12578208,2350710,-3418511,-4688006,2364226]),
2812  },
2813  GePrecomp {
2814   y_plus_x: Fe([16335052,9132434,25640582,6678888,1725628,8517937,-11807024,-11697457,15445875,-7798101]),
2815   y_minus_x: Fe([29004207,-7867081,28661402,-640412,-12794003,-7943086,31863255,-4135540,-278050,-15759279]),
2816   xy2d: Fe([-6122061,-14866665,-28614905,14569919,-10857999,-3591829,10343412,-6976290,-29828287,-10815811]),
2817  },
2818  GePrecomp {
2819   y_plus_x: Fe([27081650,3463984,14099042,-4517604,1616303,-6205604,29542636,15372179,17293797,960709]),
2820   y_minus_x: Fe([20263915,11434237,-5765435,11236810,13505955,-10857102,-16111345,6493122,-19384511,7639714]),
2821   xy2d: Fe([-2830798,-14839232,25403038,-8215196,-8317012,-16173699,18006287,-16043750,29994677,-15808121]),
2822  },
2823  GePrecomp {
2824   y_plus_x: Fe([9769828,5202651,-24157398,-13631392,-28051003,-11561624,-24613141,-13860782,-31184575,709464]),
2825   y_minus_x: Fe([12286395,13076066,-21775189,-1176622,-25003198,4057652,-32018128,-8890874,16102007,13205847]),
2826   xy2d: Fe([13733362,5599946,10557076,3195751,-5557991,8536970,-25540170,8525972,10151379,10394400]),
2827  },
2828  GePrecomp {
2829   y_plus_x: Fe([4024660,-16137551,22436262,12276534,-9099015,-2686099,19698229,11743039,-33302334,8934414]),
2830   y_minus_x: Fe([-15879800,-4525240,-8580747,-2934061,14634845,-698278,-9449077,3137094,-11536886,11721158]),
2831   xy2d: Fe([17555939,-5013938,8268606,2331751,-22738815,9761013,9319229,8835153,-9205489,-1280045]),
2832  },
2833  GePrecomp {
2834   y_plus_x: Fe([-461409,-7830014,20614118,16688288,-7514766,-4807119,22300304,505429,6108462,-6183415]),
2835   y_minus_x: Fe([-5070281,12367917,-30663534,3234473,32617080,-8422642,29880583,-13483331,-26898490,-7867459]),
2836   xy2d: Fe([-31975283,5726539,26934134,10237677,-3173717,-605053,24199304,3795095,7592688,-14992079]),
2837  },
2838  GePrecomp {
2839   y_plus_x: Fe([21594432,-14964228,17466408,-4077222,32537084,2739898,6407723,12018833,-28256052,4298412]),
2840   y_minus_x: Fe([-20650503,-11961496,-27236275,570498,3767144,-1717540,13891942,-1569194,13717174,10805743]),
2841   xy2d: Fe([-14676630,-15644296,15287174,11927123,24177847,-8175568,-796431,14860609,-26938930,-5863836]),
2842  },
2843 ],
2844 [
2845  GePrecomp {
2846   y_plus_x: Fe([12962541,5311799,-10060768,11658280,18855286,-7954201,13286263,-12808704,-4381056,9882022]),
2847   y_minus_x: Fe([18512079,11319350,-20123124,15090309,18818594,5271736,-22727904,3666879,-23967430,-3299429]),
2848   xy2d: Fe([-6789020,-3146043,16192429,13241070,15898607,-14206114,-10084880,-6661110,-2403099,5276065]),
2849  },
2850  GePrecomp {
2851   y_plus_x: Fe([30169808,-5317648,26306206,-11750859,27814964,7069267,7152851,3684982,1449224,13082861]),
2852   y_minus_x: Fe([10342826,3098505,2119311,193222,25702612,12233820,23697382,15056736,-21016438,-8202000]),
2853   xy2d: Fe([-33150110,3261608,22745853,7948688,19370557,-15177665,-26171976,6482814,-10300080,-11060101]),
2854  },
2855  GePrecomp {
2856   y_plus_x: Fe([32869458,-5408545,25609743,15678670,-10687769,-15471071,26112421,2521008,-22664288,6904815]),
2857   y_minus_x: Fe([29506923,4457497,3377935,-9796444,-30510046,12935080,1561737,3841096,-29003639,-6657642]),
2858   xy2d: Fe([10340844,-6630377,-18656632,-2278430,12621151,-13339055,30878497,-11824370,-25584551,5181966]),
2859  },
2860  GePrecomp {
2861   y_plus_x: Fe([25940115,-12658025,17324188,-10307374,-8671468,15029094,24396252,-16450922,-2322852,-12388574]),
2862   y_minus_x: Fe([-21765684,9916823,-1300409,4079498,-1028346,11909559,1782390,12641087,20603771,-6561742]),
2863   xy2d: Fe([-18882287,-11673380,24849422,11501709,13161720,-4768874,1925523,11914390,4662781,7820689]),
2864  },
2865  GePrecomp {
2866   y_plus_x: Fe([12241050,-425982,8132691,9393934,32846760,-1599620,29749456,12172924,16136752,15264020]),
2867   y_minus_x: Fe([-10349955,-14680563,-8211979,2330220,-17662549,-14545780,10658213,6671822,19012087,3772772]),
2868   xy2d: Fe([3753511,-3421066,10617074,2028709,14841030,-6721664,28718732,-15762884,20527771,12988982]),
2869  },
2870  GePrecomp {
2871   y_plus_x: Fe([-14822485,-5797269,-3707987,12689773,-898983,-10914866,-24183046,-10564943,3299665,-12424953]),
2872   y_minus_x: Fe([-16777703,-15253301,-9642417,4978983,3308785,8755439,6943197,6461331,-25583147,8991218]),
2873   xy2d: Fe([-17226263,1816362,-1673288,-6086439,31783888,-8175991,-32948145,7417950,-30242287,1507265]),
2874  },
2875  GePrecomp {
2876   y_plus_x: Fe([29692663,6829891,-10498800,4334896,20945975,-11906496,-28887608,8209391,14606362,-10647073]),
2877   y_minus_x: Fe([-3481570,8707081,32188102,5672294,22096700,1711240,-33020695,9761487,4170404,-2085325]),
2878   xy2d: Fe([-11587470,14855945,-4127778,-1531857,-26649089,15084046,22186522,16002000,-14276837,-8400798]),
2879  },
2880  GePrecomp {
2881   y_plus_x: Fe([-4811456,13761029,-31703877,-2483919,-3312471,7869047,-7113572,-9620092,13240845,10965870]),
2882   y_minus_x: Fe([-7742563,-8256762,-14768334,-13656260,-23232383,12387166,4498947,14147411,29514390,4302863]),
2883   xy2d: Fe([-13413405,-12407859,20757302,-13801832,14785143,8976368,-5061276,-2144373,17846988,-13971927]),
2884  },
2885 ],
2886 [
2887  GePrecomp {
2888   y_plus_x: Fe([-2244452,-754728,-4597030,-1066309,-6247172,1455299,-21647728,-9214789,-5222701,12650267]),
2889   y_minus_x: Fe([-9906797,-16070310,21134160,12198166,-27064575,708126,387813,13770293,-19134326,10958663]),
2890   xy2d: Fe([22470984,12369526,23446014,-5441109,-21520802,-9698723,-11772496,-11574455,-25083830,4271862]),
2891  },
2892  GePrecomp {
2893   y_plus_x: Fe([-25169565,-10053642,-19909332,15361595,-5984358,2159192,75375,-4278529,-32526221,8469673]),
2894   y_minus_x: Fe([15854970,4148314,-8893890,7259002,11666551,13824734,-30531198,2697372,24154791,-9460943]),
2895   xy2d: Fe([15446137,-15806644,29759747,14019369,30811221,-9610191,-31582008,12840104,24913809,9815020]),
2896  },
2897  GePrecomp {
2898   y_plus_x: Fe([-4709286,-5614269,-31841498,-12288893,-14443537,10799414,-9103676,13438769,18735128,9466238]),
2899   y_minus_x: Fe([11933045,9281483,5081055,-5183824,-2628162,-4905629,-7727821,-10896103,-22728655,16199064]),
2900   xy2d: Fe([14576810,379472,-26786533,-8317236,-29426508,-10812974,-102766,1876699,30801119,2164795]),
2901  },
2902  GePrecomp {
2903   y_plus_x: Fe([15995086,3199873,13672555,13712240,-19378835,-4647646,-13081610,-15496269,-13492807,1268052]),
2904   y_minus_x: Fe([-10290614,-3659039,-3286592,10948818,23037027,3794475,-3470338,-12600221,-17055369,3565904]),
2905   xy2d: Fe([29210088,-9419337,-5919792,-4952785,10834811,-13327726,-16512102,-10820713,-27162222,-14030531]),
2906  },
2907  GePrecomp {
2908   y_plus_x: Fe([-13161890,15508588,16663704,-8156150,-28349942,9019123,-29183421,-3769423,2244111,-14001979]),
2909   y_minus_x: Fe([-5152875,-3800936,-9306475,-6071583,16243069,14684434,-25673088,-16180800,13491506,4641841]),
2910   xy2d: Fe([10813417,643330,-19188515,-728916,30292062,-16600078,27548447,-7721242,14476989,-12767431]),
2911  },
2912  GePrecomp {
2913   y_plus_x: Fe([10292079,9984945,6481436,8279905,-7251514,7032743,27282937,-1644259,-27912810,12651324]),
2914   y_minus_x: Fe([-31185513,-813383,22271204,11835308,10201545,15351028,17099662,3988035,21721536,-3148940]),
2915   xy2d: Fe([10202177,-6545839,-31373232,-9574638,-32150642,-8119683,-12906320,3852694,13216206,14842320]),
2916  },
2917  GePrecomp {
2918   y_plus_x: Fe([-15815640,-10601066,-6538952,-7258995,-6984659,-6581778,-31500847,13765824,-27434397,9900184]),
2919   y_minus_x: Fe([14465505,-13833331,-32133984,-14738873,-27443187,12990492,33046193,15796406,-7051866,-8040114]),
2920   xy2d: Fe([30924417,-8279620,6359016,-12816335,16508377,9071735,-25488601,15413635,9524356,-7018878]),
2921  },
2922  GePrecomp {
2923   y_plus_x: Fe([12274201,-13175547,32627641,-1785326,6736625,13267305,5237659,-5109483,15663516,4035784]),
2924   y_minus_x: Fe([-2951309,8903985,17349946,601635,-16432815,-4612556,-13732739,-15889334,-22258478,4659091]),
2925   xy2d: Fe([-16916263,-4952973,-30393711,-15158821,20774812,15897498,5736189,15026997,-2178256,-13455585]),
2926  },
2927 ],
2928 [
2929  GePrecomp {
2930   y_plus_x: Fe([-8858980,-2219056,28571666,-10155518,-474467,-10105698,-3801496,278095,23440562,-290208]),
2931   y_minus_x: Fe([10226241,-5928702,15139956,120818,-14867693,5218603,32937275,11551483,-16571960,-7442864]),
2932   xy2d: Fe([17932739,-12437276,-24039557,10749060,11316803,7535897,22503767,5561594,-3646624,3898661]),
2933  },
2934  GePrecomp {
2935   y_plus_x: Fe([7749907,-969567,-16339731,-16464,-25018111,15122143,-1573531,7152530,21831162,1245233]),
2936   y_minus_x: Fe([26958459,-14658026,4314586,8346991,-5677764,11960072,-32589295,-620035,-30402091,-16716212]),
2937   xy2d: Fe([-12165896,9166947,33491384,13673479,29787085,13096535,6280834,14587357,-22338025,13987525]),
2938  },
2939  GePrecomp {
2940   y_plus_x: Fe([-24349909,7778775,21116000,15572597,-4833266,-5357778,-4300898,-5124639,-7469781,-2858068]),
2941   y_minus_x: Fe([9681908,-6737123,-31951644,13591838,-6883821,386950,31622781,6439245,-14581012,4091397]),
2942   xy2d: Fe([-8426427,1470727,-28109679,-1596990,3978627,-5123623,-19622683,12092163,29077877,-14741988]),
2943  },
2944  GePrecomp {
2945   y_plus_x: Fe([5269168,-6859726,-13230211,-8020715,25932563,1763552,-5606110,-5505881,-20017847,2357889]),
2946   y_minus_x: Fe([32264008,-15407652,-5387735,-1160093,-2091322,-3946900,23104804,-12869908,5727338,189038]),
2947   xy2d: Fe([14609123,-8954470,-6000566,-16622781,-14577387,-7743898,-26745169,10942115,-25888931,-14884697]),
2948  },
2949  GePrecomp {
2950   y_plus_x: Fe([20513500,5557931,-15604613,7829531,26413943,-2019404,-21378968,7471781,13913677,-5137875]),
2951   y_minus_x: Fe([-25574376,11967826,29233242,12948236,-6754465,4713227,-8940970,14059180,12878652,8511905]),
2952   xy2d: Fe([-25656801,3393631,-2955415,-7075526,-2250709,9366908,-30223418,6812974,5568676,-3127656]),
2953  },
2954  GePrecomp {
2955   y_plus_x: Fe([11630004,12144454,2116339,13606037,27378885,15676917,-17408753,-13504373,-14395196,8070818]),
2956   y_minus_x: Fe([27117696,-10007378,-31282771,-5570088,1127282,12772488,-29845906,10483306,-11552749,-1028714]),
2957   xy2d: Fe([10637467,-5688064,5674781,1072708,-26343588,-6982302,-1683975,9177853,-27493162,15431203]),
2958  },
2959  GePrecomp {
2960   y_plus_x: Fe([20525145,10892566,-12742472,12779443,-29493034,16150075,-28240519,14943142,-15056790,-7935931]),
2961   y_minus_x: Fe([-30024462,5626926,-551567,-9981087,753598,11981191,25244767,-3239766,-3356550,9594024]),
2962   xy2d: Fe([-23752644,2636870,-5163910,-10103818,585134,7877383,11345683,-6492290,13352335,-10977084]),
2963  },
2964  GePrecomp {
2965   y_plus_x: Fe([-1931799,-5407458,3304649,-12884869,17015806,-4877091,-29783850,-7752482,-13215537,-319204]),
2966   y_minus_x: Fe([20239939,6607058,6203985,3483793,-18386976,-779229,-20723742,15077870,-22750759,14523817]),
2967   xy2d: Fe([27406042,-6041657,27423596,-4497394,4996214,10002360,-28842031,-4545494,-30172742,-4805667]),
2968  },
2969 ],
2970 [
2971  GePrecomp {
2972   y_plus_x: Fe([11374242,12660715,17861383,-12540833,10935568,1099227,-13886076,-9091740,-27727044,11358504]),
2973   y_minus_x: Fe([-12730809,10311867,1510375,10778093,-2119455,-9145702,32676003,11149336,-26123651,4985768]),
2974   xy2d: Fe([-19096303,341147,-6197485,-239033,15756973,-8796662,-983043,13794114,-19414307,-15621255]),
2975  },
2976  GePrecomp {
2977   y_plus_x: Fe([6490081,11940286,25495923,-7726360,8668373,-8751316,3367603,6970005,-1691065,-9004790]),
2978   y_minus_x: Fe([1656497,13457317,15370807,6364910,13605745,8362338,-19174622,-5475723,-16796596,-5031438]),
2979   xy2d: Fe([-22273315,-13524424,-64685,-4334223,-18605636,-10921968,-20571065,-7007978,-99853,-10237333]),
2980  },
2981  GePrecomp {
2982   y_plus_x: Fe([17747465,10039260,19368299,-4050591,-20630635,-16041286,31992683,-15857976,-29260363,-5511971]),
2983   y_minus_x: Fe([31932027,-4986141,-19612382,16366580,22023614,88450,11371999,-3744247,4882242,-10626905]),
2984   xy2d: Fe([29796507,37186,19818052,10115756,-11829032,3352736,18551198,3272828,-5190932,-4162409]),
2985  },
2986  GePrecomp {
2987   y_plus_x: Fe([12501286,4044383,-8612957,-13392385,-32430052,5136599,-19230378,-3529697,330070,-3659409]),
2988   y_minus_x: Fe([6384877,2899513,17807477,7663917,-2358888,12363165,25366522,-8573892,-271295,12071499]),
2989   xy2d: Fe([-8365515,-4042521,25133448,-4517355,-6211027,2265927,-32769618,1936675,-5159697,3829363]),
2990  },
2991  GePrecomp {
2992   y_plus_x: Fe([28425966,-5835433,-577090,-4697198,-14217555,6870930,7921550,-6567787,26333140,14267664]),
2993   y_minus_x: Fe([-11067219,11871231,27385719,-10559544,-4585914,-11189312,10004786,-8709488,-21761224,8930324]),
2994   xy2d: Fe([-21197785,-16396035,25654216,-1725397,12282012,11008919,1541940,4757911,-26491501,-16408940]),
2995  },
2996  GePrecomp {
2997   y_plus_x: Fe([13537262,-7759490,-20604840,10961927,-5922820,-13218065,-13156584,6217254,-15943699,13814990]),
2998   y_minus_x: Fe([-17422573,15157790,18705543,29619,24409717,-260476,27361681,9257833,-1956526,-1776914]),
2999   xy2d: Fe([-25045300,-10191966,15366585,15166509,-13105086,8423556,-29171540,12361135,-18685978,4578290]),
3000  },
3001  GePrecomp {
3002   y_plus_x: Fe([24579768,3711570,1342322,-11180126,-27005135,14124956,-22544529,14074919,21964432,8235257]),
3003   y_minus_x: Fe([-6528613,-2411497,9442966,-5925588,12025640,-1487420,-2981514,-1669206,13006806,2355433]),
3004   xy2d: Fe([-16304899,-13605259,-6632427,-5142349,16974359,-10911083,27202044,1719366,1141648,-12796236]),
3005  },
3006  GePrecomp {
3007   y_plus_x: Fe([-12863944,-13219986,-8318266,-11018091,-6810145,-4843894,13475066,-3133972,32674895,13715045]),
3008   y_minus_x: Fe([11423335,-5468059,32344216,8962751,24989809,9241752,-13265253,16086212,-28740881,-15642093]),
3009   xy2d: Fe([-1409668,12530728,-6368726,10847387,19531186,-14132160,-11709148,7791794,-27245943,4383347]),
3010  },
3011 ],
3012 [
3013  GePrecomp {
3014   y_plus_x: Fe([-28970898,5271447,-1266009,-9736989,-12455236,16732599,-4862407,-4906449,27193557,6245191]),
3015   y_minus_x: Fe([-15193956,5362278,-1783893,2695834,4960227,12840725,23061898,3260492,22510453,8577507]),
3016   xy2d: Fe([-12632451,11257346,-32692994,13548177,-721004,10879011,31168030,13952092,-29571492,-3635906]),
3017  },
3018  GePrecomp {
3019   y_plus_x: Fe([3877321,-9572739,32416692,5405324,-11004407,-13656635,3759769,11935320,5611860,8164018]),
3020   y_minus_x: Fe([-16275802,14667797,15906460,12155291,-22111149,-9039718,32003002,-8832289,5773085,-8422109]),
3021   xy2d: Fe([-23788118,-8254300,1950875,8937633,18686727,16459170,-905725,12376320,31632953,190926]),
3022  },
3023  GePrecomp {
3024   y_plus_x: Fe([-24593607,-16138885,-8423991,13378746,14162407,6901328,-8288749,4508564,-25341555,-3627528]),
3025   y_minus_x: Fe([8884438,-5884009,6023974,10104341,-6881569,-4941533,18722941,-14786005,-1672488,827625]),
3026   xy2d: Fe([-32720583,-16289296,-32503547,7101210,13354605,2659080,-1800575,-14108036,-24878478,1541286]),
3027  },
3028  GePrecomp {
3029   y_plus_x: Fe([2901347,-1117687,3880376,-10059388,-17620940,-3612781,-21802117,-3567481,20456845,-1885033]),
3030   y_minus_x: Fe([27019610,12299467,-13658288,-1603234,-12861660,-4861471,-19540150,-5016058,29439641,15138866]),
3031   xy2d: Fe([21536104,-6626420,-32447818,-10690208,-22408077,5175814,-5420040,-16361163,7779328,109896]),
3032  },
3033  GePrecomp {
3034   y_plus_x: Fe([30279744,14648750,-8044871,6425558,13639621,-743509,28698390,12180118,23177719,-554075]),
3035   y_minus_x: Fe([26572847,3405927,-31701700,12890905,-19265668,5335866,-6493768,2378492,4439158,-13279347]),
3036   xy2d: Fe([-22716706,3489070,-9225266,-332753,18875722,-1140095,14819434,-12731527,-17717757,-5461437]),
3037  },
3038  GePrecomp {
3039   y_plus_x: Fe([-5056483,16566551,15953661,3767752,-10436499,15627060,-820954,2177225,8550082,-15114165]),
3040   y_minus_x: Fe([-18473302,16596775,-381660,15663611,22860960,15585581,-27844109,-3582739,-23260460,-8428588]),
3041   xy2d: Fe([-32480551,15707275,-8205912,-5652081,29464558,2713815,-22725137,15860482,-21902570,1494193]),
3042  },
3043  GePrecomp {
3044   y_plus_x: Fe([-19562091,-14087393,-25583872,-9299552,13127842,759709,21923482,16529112,8742704,12967017]),
3045   y_minus_x: Fe([-28464899,1553205,32536856,-10473729,-24691605,-406174,-8914625,-2933896,-29903758,15553883]),
3046   xy2d: Fe([21877909,3230008,9881174,10539357,-4797115,2841332,11543572,14513274,19375923,-12647961]),
3047  },
3048  GePrecomp {
3049   y_plus_x: Fe([8832269,-14495485,13253511,5137575,5037871,4078777,24880818,-6222716,2862653,9455043]),
3050   y_minus_x: Fe([29306751,5123106,20245049,-14149889,9592566,8447059,-2077124,-2990080,15511449,4789663]),
3051   xy2d: Fe([-20679756,7004547,8824831,-9434977,-4045704,-3750736,-5754762,108893,23513200,16652362]),
3052  },
3053 ],
3054 [
3055  GePrecomp {
3056   y_plus_x: Fe([-33256173,4144782,-4476029,-6579123,10770039,-7155542,-6650416,-12936300,-18319198,10212860]),
3057   y_minus_x: Fe([2756081,8598110,7383731,-6859892,22312759,-1105012,21179801,2600940,-9988298,-12506466]),
3058   xy2d: Fe([-24645692,13317462,-30449259,-15653928,21365574,-10869657,11344424,864440,-2499677,-16710063]),
3059  },
3060  GePrecomp {
3061   y_plus_x: Fe([-26432803,6148329,-17184412,-14474154,18782929,-275997,-22561534,211300,2719757,4940997]),
3062   y_minus_x: Fe([-1323882,3911313,-6948744,14759765,-30027150,7851207,21690126,8518463,26699843,5276295]),
3063   xy2d: Fe([-13149873,-6429067,9396249,365013,24703301,-10488939,1321586,149635,-15452774,7159369]),
3064  },
3065  GePrecomp {
3066   y_plus_x: Fe([9987780,-3404759,17507962,9505530,9731535,-2165514,22356009,8312176,22477218,-8403385]),
3067   y_minus_x: Fe([18155857,-16504990,19744716,9006923,15154154,-10538976,24256460,-4864995,-22548173,9334109]),
3068   xy2d: Fe([2986088,-4911893,10776628,-3473844,10620590,-7083203,-21413845,14253545,-22587149,536906]),
3069  },
3070  GePrecomp {
3071   y_plus_x: Fe([4377756,8115836,24567078,15495314,11625074,13064599,7390551,10589625,10838060,-15420424]),
3072   y_minus_x: Fe([-19342404,867880,9277171,-3218459,-14431572,-1986443,19295826,-15796950,6378260,699185]),
3073   xy2d: Fe([7895026,4057113,-7081772,-13077756,-17886831,-323126,-716039,15693155,-5045064,-13373962]),
3074  },
3075  GePrecomp {
3076   y_plus_x: Fe([-7737563,-5869402,-14566319,-7406919,11385654,13201616,31730678,-10962840,-3918636,-9669325]),
3077   y_minus_x: Fe([10188286,-15770834,-7336361,13427543,22223443,14896287,30743455,7116568,-21786507,5427593]),
3078   xy2d: Fe([696102,13206899,27047647,-10632082,15285305,-9853179,10798490,-4578720,19236243,12477404]),
3079  },
3080  GePrecomp {
3081   y_plus_x: Fe([-11229439,11243796,-17054270,-8040865,-788228,-8167967,-3897669,11180504,-23169516,7733644]),
3082   y_minus_x: Fe([17800790,-14036179,-27000429,-11766671,23887827,3149671,23466177,-10538171,10322027,15313801]),
3083   xy2d: Fe([26246234,11968874,32263343,-5468728,6830755,-13323031,-15794704,-101982,-24449242,10890804]),
3084  },
3085  GePrecomp {
3086   y_plus_x: Fe([-31365647,10271363,-12660625,-6267268,16690207,-13062544,-14982212,16484931,25180797,-5334884]),
3087   y_minus_x: Fe([-586574,10376444,-32586414,-11286356,19801893,10997610,2276632,9482883,316878,13820577]),
3088   xy2d: Fe([-9882808,-4510367,-2115506,16457136,-11100081,11674996,30756178,-7515054,30696930,-3712849]),
3089  },
3090  GePrecomp {
3091   y_plus_x: Fe([32988917,-9603412,12499366,7910787,-10617257,-11931514,-7342816,-9985397,-32349517,7392473]),
3092   y_minus_x: Fe([-8855661,15927861,9866406,-3649411,-2396914,-16655781,-30409476,-9134995,25112947,-2926644]),
3093   xy2d: Fe([-2504044,-436966,25621774,-5678772,15085042,-5479877,-24884878,-13526194,5537438,-13914319]),
3094  },
3095 ],
3096 [
3097  GePrecomp {
3098   y_plus_x: Fe([-11225584,2320285,-9584280,10149187,-33444663,5808648,-14876251,-1729667,31234590,6090599]),
3099   y_minus_x: Fe([-9633316,116426,26083934,2897444,-6364437,-2688086,609721,15878753,-6970405,-9034768]),
3100   xy2d: Fe([-27757857,247744,-15194774,-9002551,23288161,-10011936,-23869595,6503646,20650474,1804084]),
3101  },
3102  GePrecomp {
3103   y_plus_x: Fe([-27589786,15456424,8972517,8469608,15640622,4439847,3121995,-10329713,27842616,-202328]),
3104   y_minus_x: Fe([-15306973,2839644,22530074,10026331,4602058,5048462,28248656,5031932,-11375082,12714369]),
3105   xy2d: Fe([20807691,-7270825,29286141,11421711,-27876523,-13868230,-21227475,1035546,-19733229,12796920]),
3106  },
3107  GePrecomp {
3108   y_plus_x: Fe([12076899,-14301286,-8785001,-11848922,-25012791,16400684,-17591495,-12899438,3480665,-15182815]),
3109   y_minus_x: Fe([-32361549,5457597,28548107,7833186,7303070,-11953545,-24363064,-15921875,-33374054,2771025]),
3110   xy2d: Fe([-21389266,421932,26597266,6860826,22486084,-6737172,-17137485,-4210226,-24552282,15673397]),
3111  },
3112  GePrecomp {
3113   y_plus_x: Fe([-20184622,2338216,19788685,-9620956,-4001265,-8740893,-20271184,4733254,3727144,-12934448]),
3114   y_minus_x: Fe([6120119,814863,-11794402,-622716,6812205,-15747771,2019594,7975683,31123697,-10958981]),
3115   xy2d: Fe([30069250,-11435332,30434654,2958439,18399564,-976289,12296869,9204260,-16432438,9648165]),
3116  },
3117  GePrecomp {
3118   y_plus_x: Fe([32705432,-1550977,30705658,7451065,-11805606,9631813,3305266,5248604,-26008332,-11377501]),
3119   y_minus_x: Fe([17219865,2375039,-31570947,-5575615,-19459679,9219903,294711,15298639,2662509,-16297073]),
3120   xy2d: Fe([-1172927,-7558695,-4366770,-4287744,-21346413,-8434326,32087529,-1222777,32247248,-14389861]),
3121  },
3122  GePrecomp {
3123   y_plus_x: Fe([14312628,1221556,17395390,-8700143,-4945741,-8684635,-28197744,-9637817,-16027623,-13378845]),
3124   y_minus_x: Fe([-1428825,-9678990,-9235681,6549687,-7383069,-468664,23046502,9803137,17597934,2346211]),
3125   xy2d: Fe([18510800,15337574,26171504,981392,-22241552,7827556,-23491134,-11323352,3059833,-11782870]),
3126  },
3127  GePrecomp {
3128   y_plus_x: Fe([10141598,6082907,17829293,-1947643,9830092,13613136,-25556636,-5544586,-33502212,3592096]),
3129   y_minus_x: Fe([33114168,-15889352,-26525686,-13343397,33076705,8716171,1151462,1521897,-982665,-6837803]),
3130   xy2d: Fe([-32939165,-4255815,23947181,-324178,-33072974,-12305637,-16637686,3891704,26353178,693168]),
3131  },
3132  GePrecomp {
3133   y_plus_x: Fe([30374239,1595580,-16884039,13186931,4600344,406904,9585294,-400668,31375464,14369965]),
3134   y_minus_x: Fe([-14370654,-7772529,1510301,6434173,-18784789,-6262728,32732230,-13108839,17901441,16011505]),
3135   xy2d: Fe([18171223,-11934626,-12500402,15197122,-11038147,-15230035,-19172240,-16046376,8764035,12309598]),
3136  },
3137 ],
3138 [
3139  GePrecomp {
3140   y_plus_x: Fe([5975908,-5243188,-19459362,-9681747,-11541277,14015782,-23665757,1228319,17544096,-10593782]),
3141   y_minus_x: Fe([5811932,-1715293,3442887,-2269310,-18367348,-8359541,-18044043,-15410127,-5565381,12348900]),
3142   xy2d: Fe([-31399660,11407555,25755363,6891399,-3256938,14872274,-24849353,8141295,-10632534,-585479]),
3143  },
3144  GePrecomp {
3145   y_plus_x: Fe([-12675304,694026,-5076145,13300344,14015258,-14451394,-9698672,-11329050,30944593,1130208]),
3146   y_minus_x: Fe([8247766,-6710942,-26562381,-7709309,-14401939,-14648910,4652152,2488540,23550156,-271232]),
3147   xy2d: Fe([17294316,-3788438,7026748,15626851,22990044,113481,2267737,-5908146,-408818,-137719]),
3148  },
3149  GePrecomp {
3150   y_plus_x: Fe([16091085,-16253926,18599252,7340678,2137637,-1221657,-3364161,14550936,3260525,-7166271]),
3151   y_minus_x: Fe([-4910104,-13332887,18550887,10864893,-16459325,-7291596,-23028869,-13204905,-12748722,2701326]),
3152   xy2d: Fe([-8574695,16099415,4629974,-16340524,-20786213,-6005432,-10018363,9276971,11329923,1862132]),
3153  },
3154  GePrecomp {
3155   y_plus_x: Fe([14763076,-15903608,-30918270,3689867,3511892,10313526,-21951088,12219231,-9037963,-940300]),
3156   y_minus_x: Fe([8894987,-3446094,6150753,3013931,301220,15693451,-31981216,-2909717,-15438168,11595570]),
3157   xy2d: Fe([15214962,3537601,-26238722,-14058872,4418657,-15230761,13947276,10730794,-13489462,-4363670]),
3158  },
3159  GePrecomp {
3160   y_plus_x: Fe([-2538306,7682793,32759013,263109,-29984731,-7955452,-22332124,-10188635,977108,699994]),
3161   y_minus_x: Fe([-12466472,4195084,-9211532,550904,-15565337,12917920,19118110,-439841,-30534533,-14337913]),
3162   xy2d: Fe([31788461,-14507657,4799989,7372237,8808585,-14747943,9408237,-10051775,12493932,-5409317]),
3163  },
3164  GePrecomp {
3165   y_plus_x: Fe([-25680606,5260744,-19235809,-6284470,-3695942,16566087,27218280,2607121,29375955,6024730]),
3166   y_minus_x: Fe([842132,-2794693,-4763381,-8722815,26332018,-12405641,11831880,6985184,-9940361,2854096]),
3167   xy2d: Fe([-4847262,-7969331,2516242,-5847713,9695691,-7221186,16512645,960770,12121869,16648078]),
3168  },
3169  GePrecomp {
3170   y_plus_x: Fe([-15218652,14667096,-13336229,2013717,30598287,-464137,-31504922,-7882064,20237806,2838411]),
3171   y_minus_x: Fe([-19288047,4453152,15298546,-16178388,22115043,-15972604,12544294,-13470457,1068881,-12499905]),
3172   xy2d: Fe([-9558883,-16518835,33238498,13506958,30505848,-1114596,-8486907,-2630053,12521378,4845654]),
3173  },
3174  GePrecomp {
3175   y_plus_x: Fe([-28198521,10744108,-2958380,10199664,7759311,-13088600,3409348,-873400,-6482306,-12885870]),
3176   y_minus_x: Fe([-23561822,6230156,-20382013,10655314,-24040585,-11621172,10477734,-1240216,-3113227,13974498]),
3177   xy2d: Fe([12966261,15550616,-32038948,-1615346,21025980,-629444,5642325,7188737,18895762,12629579]),
3178  },
3179 ],
3180 [
3181  GePrecomp {
3182   y_plus_x: Fe([14741879,-14946887,22177208,-11721237,1279741,8058600,11758140,789443,32195181,3895677]),
3183   y_minus_x: Fe([10758205,15755439,-4509950,9243698,-4879422,6879879,-2204575,-3566119,-8982069,4429647]),
3184   xy2d: Fe([-2453894,15725973,-20436342,-10410672,-5803908,-11040220,-7135870,-11642895,18047436,-15281743]),
3185  },
3186  GePrecomp {
3187   y_plus_x: Fe([-25173001,-11307165,29759956,11776784,-22262383,-15820455,10993114,-12850837,-17620701,-9408468]),
3188   y_minus_x: Fe([21987233,700364,-24505048,14972008,-7774265,-5718395,32155026,2581431,-29958985,8773375]),
3189   xy2d: Fe([-25568350,454463,-13211935,16126715,25240068,8594567,20656846,12017935,-7874389,-13920155]),
3190  },
3191  GePrecomp {
3192   y_plus_x: Fe([6028182,6263078,-31011806,-11301710,-818919,2461772,-31841174,-5468042,-1721788,-2776725]),
3193   y_minus_x: Fe([-12278994,16624277,987579,-5922598,32908203,1248608,7719845,-4166698,28408820,6816612]),
3194   xy2d: Fe([-10358094,-8237829,19549651,-12169222,22082623,16147817,20613181,13982702,-10339570,5067943]),
3195  },
3196  GePrecomp {
3197   y_plus_x: Fe([-30505967,-3821767,12074681,13582412,-19877972,2443951,-19719286,12746132,5331210,-10105944]),
3198   y_minus_x: Fe([30528811,3601899,-1957090,4619785,-27361822,-15436388,24180793,-12570394,27679908,-1648928]),
3199   xy2d: Fe([9402404,-13957065,32834043,10838634,-26580150,-13237195,26653274,-8685565,22611444,-12715406]),
3200  },
3201  GePrecomp {
3202   y_plus_x: Fe([22190590,1118029,22736441,15130463,-30460692,-5991321,19189625,-4648942,4854859,6622139]),
3203   y_minus_x: Fe([-8310738,-2953450,-8262579,-3388049,-10401731,-271929,13424426,-3567227,26404409,13001963]),
3204   xy2d: Fe([-31241838,-15415700,-2994250,8939346,11562230,-12840670,-26064365,-11621720,-15405155,11020693]),
3205  },
3206  GePrecomp {
3207   y_plus_x: Fe([1866042,-7949489,-7898649,-10301010,12483315,13477547,3175636,-12424163,28761762,1406734]),
3208   y_minus_x: Fe([-448555,-1777666,13018551,3194501,-9580420,-11161737,24760585,-4347088,25577411,-13378680]),
3209   xy2d: Fe([-24290378,4759345,-690653,-1852816,2066747,10693769,-29595790,9884936,-9368926,4745410]),
3210  },
3211  GePrecomp {
3212   y_plus_x: Fe([-9141284,6049714,-19531061,-4341411,-31260798,9944276,-15462008,-11311852,10931924,-11931931]),
3213   y_minus_x: Fe([-16561513,14112680,-8012645,4817318,-8040464,-11414606,-22853429,10856641,-20470770,13434654]),
3214   xy2d: Fe([22759489,-10073434,-16766264,-1871422,13637442,-10168091,1765144,-12654326,28445307,-5364710]),
3215  },
3216  GePrecomp {
3217   y_plus_x: Fe([29875063,12493613,2795536,-3786330,1710620,15181182,-10195717,-8788675,9074234,1167180]),
3218   y_minus_x: Fe([-26205683,11014233,-9842651,-2635485,-26908120,7532294,-18716888,-9535498,3843903,9367684]),
3219   xy2d: Fe([-10969595,-6403711,9591134,9582310,11349256,108879,16235123,8601684,-139197,4242895]),
3220  },
3221 ],
3222 [
3223  GePrecomp {
3224   y_plus_x: Fe([22092954,-13191123,-2042793,-11968512,32186753,-11517388,-6574341,2470660,-27417366,16625501]),
3225   y_minus_x: Fe([-11057722,3042016,13770083,-9257922,584236,-544855,-7770857,2602725,-27351616,14247413]),
3226   xy2d: Fe([6314175,-10264892,-32772502,15957557,-10157730,168750,-8618807,14290061,27108877,-1180880]),
3227  },
3228  GePrecomp {
3229   y_plus_x: Fe([-8586597,-7170966,13241782,10960156,-32991015,-13794596,33547976,-11058889,-27148451,981874]),
3230   y_minus_x: Fe([22833440,9293594,-32649448,-13618667,-9136966,14756819,-22928859,-13970780,-10479804,-16197962]),
3231   xy2d: Fe([-7768587,3326786,-28111797,10783824,19178761,14905060,22680049,13906969,-15933690,3797899]),
3232  },
3233  GePrecomp {
3234   y_plus_x: Fe([21721356,-4212746,-12206123,9310182,-3882239,-13653110,23740224,-2709232,20491983,-8042152]),
3235   y_minus_x: Fe([9209270,-15135055,-13256557,-6167798,-731016,15289673,25947805,15286587,30997318,-6703063]),
3236   xy2d: Fe([7392032,16618386,23946583,-8039892,-13265164,-1533858,-14197445,-2321576,17649998,-250080]),
3237  },
3238  GePrecomp {
3239   y_plus_x: Fe([-9301088,-14193827,30609526,-3049543,-25175069,-1283752,-15241566,-9525724,-2233253,7662146]),
3240   y_minus_x: Fe([-17558673,1763594,-33114336,15908610,-30040870,-12174295,7335080,-8472199,-3174674,3440183]),
3241   xy2d: Fe([-19889700,-5977008,-24111293,-9688870,10799743,-16571957,40450,-4431835,4862400,1133]),
3242  },
3243  GePrecomp {
3244   y_plus_x: Fe([-32856209,-7873957,-5422389,14860950,-16319031,7956142,7258061,311861,-30594991,-7379421]),
3245   y_minus_x: Fe([-3773428,-1565936,28985340,7499440,24445838,9325937,29727763,16527196,18278453,15405622]),
3246   xy2d: Fe([-4381906,8508652,-19898366,-3674424,-5984453,15149970,-13313598,843523,-21875062,13626197]),
3247  },
3248  GePrecomp {
3249   y_plus_x: Fe([2281448,-13487055,-10915418,-2609910,1879358,16164207,-10783882,3953792,13340839,15928663]),
3250   y_minus_x: Fe([31727126,-7179855,-18437503,-8283652,2875793,-16390330,-25269894,-7014826,-23452306,5964753]),
3251   xy2d: Fe([4100420,-5959452,-17179337,6017714,-18705837,12227141,-26684835,11344144,2538215,-7570755]),
3252  },
3253  GePrecomp {
3254   y_plus_x: Fe([-9433605,6123113,11159803,-2156608,30016280,14966241,-20474983,1485421,-629256,-15958862]),
3255   y_minus_x: Fe([-26804558,4260919,11851389,9658551,-32017107,16367492,-20205425,-13191288,11659922,-11115118]),
3256   xy2d: Fe([26180396,10015009,-30844224,-8581293,5418197,9480663,2231568,-10170080,33100372,-1306171]),
3257  },
3258  GePrecomp {
3259   y_plus_x: Fe([15121113,-5201871,-10389905,15427821,-27509937,-15992507,21670947,4486675,-5931810,-14466380]),
3260   y_minus_x: Fe([16166486,-9483733,-11104130,6023908,-31926798,-1364923,2340060,-16254968,-10735770,-10039824]),
3261   xy2d: Fe([28042865,-3557089,-12126526,12259706,-3717498,-6945899,6766453,-8689599,18036436,5803270]),
3262  },
3263 ],
3264 [
3265  GePrecomp {
3266   y_plus_x: Fe([-817581,6763912,11803561,1585585,10958447,-2671165,23855391,4598332,-6159431,-14117438]),
3267   y_minus_x: Fe([-31031306,-14256194,17332029,-2383520,31312682,-5967183,696309,50292,-20095739,11763584]),
3268   xy2d: Fe([-594563,-2514283,-32234153,12643980,12650761,14811489,665117,-12613632,-19773211,-10713562]),
3269  },
3270  GePrecomp {
3271   y_plus_x: Fe([30464590,-11262872,-4127476,-12734478,19835327,-7105613,-24396175,2075773,-17020157,992471]),
3272   y_minus_x: Fe([18357185,-6994433,7766382,16342475,-29324918,411174,14578841,8080033,-11574335,-10601610]),
3273   xy2d: Fe([19598397,10334610,12555054,2555664,18821899,-10339780,21873263,16014234,26224780,16452269]),
3274  },
3275  GePrecomp {
3276   y_plus_x: Fe([-30223925,5145196,5944548,16385966,3976735,2009897,-11377804,-7618186,-20533829,3698650]),
3277   y_minus_x: Fe([14187449,3448569,-10636236,-10810935,-22663880,-3433596,7268410,-10890444,27394301,12015369]),
3278   xy2d: Fe([19695761,16087646,28032085,12999827,6817792,11427614,20244189,-1312777,-13259127,-3402461]),
3279  },
3280  GePrecomp {
3281   y_plus_x: Fe([30860103,12735208,-1888245,-4699734,-16974906,2256940,-8166013,12298312,-8550524,-10393462]),
3282   y_minus_x: Fe([-5719826,-11245325,-1910649,15569035,26642876,-7587760,-5789354,-15118654,-4976164,12651793]),
3283   xy2d: Fe([-2848395,9953421,11531313,-5282879,26895123,-12697089,-13118820,-16517902,9768698,-2533218]),
3284  },
3285  GePrecomp {
3286   y_plus_x: Fe([-24719459,1894651,-287698,-4704085,15348719,-8156530,32767513,12765450,4940095,10678226]),
3287   y_minus_x: Fe([18860224,15980149,-18987240,-1562570,-26233012,-11071856,-7843882,13944024,-24372348,16582019]),
3288   xy2d: Fe([-15504260,4970268,-29893044,4175593,-20993212,-2199756,-11704054,15444560,-11003761,7989037]),
3289  },
3290  GePrecomp {
3291   y_plus_x: Fe([31490452,5568061,-2412803,2182383,-32336847,4531686,-32078269,6200206,-19686113,-14800171]),
3292   y_minus_x: Fe([-17308668,-15879940,-31522777,-2831,-32887382,16375549,8680158,-16371713,28550068,-6857132]),
3293   xy2d: Fe([-28126887,-5688091,16837845,-1820458,-6850681,12700016,-30039981,4364038,1155602,5988841]),
3294  },
3295  GePrecomp {
3296   y_plus_x: Fe([21890435,-13272907,-12624011,12154349,-7831873,15300496,23148983,-4470481,24618407,8283181]),
3297   y_minus_x: Fe([-33136107,-10512751,9975416,6841041,-31559793,16356536,3070187,-7025928,1466169,10740210]),
3298   xy2d: Fe([-1509399,-15488185,-13503385,-10655916,32799044,909394,-13938903,-5779719,-32164649,-15327040]),
3299  },
3300  GePrecomp {
3301   y_plus_x: Fe([3960823,-14267803,-28026090,-15918051,-19404858,13146868,15567327,951507,-3260321,-573935]),
3302   y_minus_x: Fe([24740841,5052253,-30094131,8961361,25877428,6165135,-24368180,14397372,-7380369,-6144105]),
3303   xy2d: Fe([-28888365,3510803,-28103278,-1158478,-11238128,-10631454,-15441463,-14453128,-1625486,-6494814]),
3304  },
3305 ],
3306 [
3307  GePrecomp {
3308   y_plus_x: Fe([793299,-9230478,8836302,-6235707,-27360908,-2369593,33152843,-4885251,-9906200,-621852]),
3309   y_minus_x: Fe([5666233,525582,20782575,-8038419,-24538499,14657740,16099374,1468826,-6171428,-15186581]),
3310   xy2d: Fe([-4859255,-3779343,-2917758,-6748019,7778750,11688288,-30404353,-9871238,-1558923,-9863646]),
3311  },
3312  GePrecomp {
3313   y_plus_x: Fe([10896332,-7719704,824275,472601,-19460308,3009587,25248958,14783338,-30581476,-15757844]),
3314   y_minus_x: Fe([10566929,12612572,-31944212,11118703,-12633376,12362879,21752402,8822496,24003793,14264025]),
3315   xy2d: Fe([27713862,-7355973,-11008240,9227530,27050101,2504721,23886875,-13117525,13958495,-5732453]),
3316  },
3317  GePrecomp {
3318   y_plus_x: Fe([-23481610,4867226,-27247128,3900521,29838369,-8212291,-31889399,-10041781,7340521,-15410068]),
3319   y_minus_x: Fe([4646514,-8011124,-22766023,-11532654,23184553,8566613,31366726,-1381061,-15066784,-10375192]),
3320   xy2d: Fe([-17270517,12723032,-16993061,14878794,21619651,-6197576,27584817,3093888,-8843694,3849921]),
3321  },
3322  GePrecomp {
3323   y_plus_x: Fe([-9064912,2103172,25561640,-15125738,-5239824,9582958,32477045,-9017955,5002294,-15550259]),
3324   y_minus_x: Fe([-12057553,-11177906,21115585,-13365155,8808712,-12030708,16489530,13378448,-25845716,12741426]),
3325   xy2d: Fe([-5946367,10645103,-30911586,15390284,-3286982,-7118677,24306472,15852464,28834118,-7646072]),
3326  },
3327  GePrecomp {
3328   y_plus_x: Fe([-17335748,-9107057,-24531279,9434953,-8472084,-583362,-13090771,455841,20461858,5491305]),
3329   y_minus_x: Fe([13669248,-16095482,-12481974,-10203039,-14569770,-11893198,-24995986,11293807,-28588204,-9421832]),
3330   xy2d: Fe([28497928,6272777,-33022994,14470570,8906179,-1225630,18504674,-14165166,29867745,-8795943]),
3331  },
3332  GePrecomp {
3333   y_plus_x: Fe([-16207023,13517196,-27799630,-13697798,24009064,-6373891,-6367600,-13175392,22853429,-4012011]),
3334   y_minus_x: Fe([24191378,16712145,-13931797,15217831,14542237,1646131,18603514,-11037887,12876623,-2112447]),
3335   xy2d: Fe([17902668,4518229,-411702,-2829247,26878217,5258055,-12860753,608397,16031844,3723494]),
3336  },
3337  GePrecomp {
3338   y_plus_x: Fe([-28632773,12763728,-20446446,7577504,33001348,-13017745,17558842,-7872890,23896954,-4314245]),
3339   y_minus_x: Fe([-20005381,-12011952,31520464,605201,2543521,5991821,-2945064,7229064,-9919646,-8826859]),
3340   xy2d: Fe([28816045,298879,-28165016,-15920938,19000928,-1665890,-12680833,-2949325,-18051778,-2082915]),
3341  },
3342  GePrecomp {
3343   y_plus_x: Fe([16000882,-344896,3493092,-11447198,-29504595,-13159789,12577740,16041268,-19715240,7847707]),
3344   y_minus_x: Fe([10151868,10572098,27312476,7922682,14825339,4723128,-32855931,-6519018,-10020567,3852848]),
3345   xy2d: Fe([-11430470,15697596,-21121557,-4420647,5386314,15063598,16514493,-15932110,29330899,-15076224]),
3346  },
3347 ],
3348 [
3349  GePrecomp {
3350   y_plus_x: Fe([-25499735,-4378794,-15222908,-6901211,16615731,2051784,3303702,15490,-27548796,12314391]),
3351   y_minus_x: Fe([15683520,-6003043,18109120,-9980648,15337968,-5997823,-16717435,15921866,16103996,-3731215]),
3352   xy2d: Fe([-23169824,-10781249,13588192,-1628807,-3798557,-1074929,-19273607,5402699,-29815713,-9841101]),
3353  },
3354  GePrecomp {
3355   y_plus_x: Fe([23190676,2384583,-32714340,3462154,-29903655,-1529132,-11266856,8911517,-25205859,2739713]),
3356   y_minus_x: Fe([21374101,-3554250,-33524649,9874411,15377179,11831242,-33529904,6134907,4931255,11987849]),
3357   xy2d: Fe([-7732,-2978858,-16223486,7277597,105524,-322051,-31480539,13861388,-30076310,10117930]),
3358  },
3359  GePrecomp {
3360   y_plus_x: Fe([-29501170,-10744872,-26163768,13051539,-25625564,5089643,-6325503,6704079,12890019,15728940]),
3361   y_minus_x: Fe([-21972360,-11771379,-951059,-4418840,14704840,2695116,903376,-10428139,12885167,8311031]),
3362   xy2d: Fe([-17516482,5352194,10384213,-13811658,7506451,13453191,26423267,4384730,1888765,-5435404]),
3363  },
3364  GePrecomp {
3365   y_plus_x: Fe([-25817338,-3107312,-13494599,-3182506,30896459,-13921729,-32251644,-12707869,-19464434,-3340243]),
3366   y_minus_x: Fe([-23607977,-2665774,-526091,4651136,5765089,4618330,6092245,14845197,17151279,-9854116]),
3367   xy2d: Fe([-24830458,-12733720,-15165978,10367250,-29530908,-265356,22825805,-7087279,-16866484,16176525]),
3368  },
3369  GePrecomp {
3370   y_plus_x: Fe([-23583256,6564961,20063689,3798228,-4740178,7359225,2006182,-10363426,-28746253,-10197509]),
3371   y_minus_x: Fe([-10626600,-4486402,-13320562,-5125317,3432136,-6393229,23632037,-1940610,32808310,1099883]),
3372   xy2d: Fe([15030977,5768825,-27451236,-2887299,-6427378,-15361371,-15277896,-6809350,2051441,-15225865]),
3373  },
3374  GePrecomp {
3375   y_plus_x: Fe([-3362323,-7239372,7517890,9824992,23555850,295369,5148398,-14154188,-22686354,16633660]),
3376   y_minus_x: Fe([4577086,-16752288,13249841,-15304328,19958763,-14537274,18559670,-10759549,8402478,-9864273]),
3377   xy2d: Fe([-28406330,-1051581,-26790155,-907698,-17212414,-11030789,9453451,-14980072,17983010,9967138]),
3378  },
3379  GePrecomp {
3380   y_plus_x: Fe([-25762494,6524722,26585488,9969270,24709298,1220360,-1677990,7806337,17507396,3651560]),
3381   y_minus_x: Fe([-10420457,-4118111,14584639,15971087,-15768321,8861010,26556809,-5574557,-18553322,-11357135]),
3382   xy2d: Fe([2839101,14284142,4029895,3472686,14402957,12689363,-26642121,8459447,-5605463,-7621941]),
3383  },
3384  GePrecomp {
3385   y_plus_x: Fe([-4839289,-3535444,9744961,2871048,25113978,3187018,-25110813,-849066,17258084,-7977739]),
3386   y_minus_x: Fe([18164541,-10595176,-17154882,-1542417,19237078,-9745295,23357533,-15217008,26908270,12150756]),
3387   xy2d: Fe([-30264870,-7647865,5112249,-7036672,-1499807,-6974257,43168,-5537701,-32302074,16215819]),
3388  },
3389 ],
3390 [
3391  GePrecomp {
3392   y_plus_x: Fe([-6898905,9824394,-12304779,-4401089,-31397141,-6276835,32574489,12532905,-7503072,-8675347]),
3393   y_minus_x: Fe([-27343522,-16515468,-27151524,-10722951,946346,16291093,254968,7168080,21676107,-1943028]),
3394   xy2d: Fe([21260961,-8424752,-16831886,-11920822,-23677961,3968121,-3651949,-6215466,-3556191,-7913075]),
3395  },
3396  GePrecomp {
3397   y_plus_x: Fe([16544754,13250366,-16804428,15546242,-4583003,12757258,-2462308,-8680336,-18907032,-9662799]),
3398   y_minus_x: Fe([-2415239,-15577728,18312303,4964443,-15272530,-12653564,26820651,16690659,25459437,-4564609]),
3399   xy2d: Fe([-25144690,11425020,28423002,-11020557,-6144921,-15826224,9142795,-2391602,-6432418,-1644817]),
3400  },
3401  GePrecomp {
3402   y_plus_x: Fe([-23104652,6253476,16964147,-3768872,-25113972,-12296437,-27457225,-16344658,6335692,7249989]),
3403   y_minus_x: Fe([-30333227,13979675,7503222,-12368314,-11956721,-4621693,-30272269,2682242,25993170,-12478523]),
3404   xy2d: Fe([4364628,5930691,32304656,-10044554,-8054781,15091131,22857016,-10598955,31820368,15075278]),
3405  },
3406  GePrecomp {
3407   y_plus_x: Fe([31879134,-8918693,17258761,90626,-8041836,-4917709,24162788,-9650886,-17970238,12833045]),
3408   y_minus_x: Fe([19073683,14851414,-24403169,-11860168,7625278,11091125,-19619190,2074449,-9413939,14905377]),
3409   xy2d: Fe([24483667,-11935567,-2518866,-11547418,-1553130,15355506,-25282080,9253129,27628530,-7555480]),
3410  },
3411  GePrecomp {
3412   y_plus_x: Fe([17597607,8340603,19355617,552187,26198470,-3176583,4593324,-9157582,-14110875,15297016]),
3413   y_minus_x: Fe([510886,14337390,-31785257,16638632,6328095,2713355,-20217417,-11864220,8683221,2921426]),
3414   xy2d: Fe([18606791,11874196,27155355,-5281482,-24031742,6265446,-25178240,-1278924,4674690,13890525]),
3415  },
3416  GePrecomp {
3417   y_plus_x: Fe([13609624,13069022,-27372361,-13055908,24360586,9592974,14977157,9835105,4389687,288396]),
3418   y_minus_x: Fe([9922506,-519394,13613107,5883594,-18758345,-434263,-12304062,8317628,23388070,16052080]),
3419   xy2d: Fe([12720016,11937594,-31970060,-5028689,26900120,8561328,-20155687,-11632979,-14754271,-10812892]),
3420  },
3421  GePrecomp {
3422   y_plus_x: Fe([15961858,14150409,26716931,-665832,-22794328,13603569,11829573,7467844,-28822128,929275]),
3423   y_minus_x: Fe([11038231,-11582396,-27310482,-7316562,-10498527,-16307831,-23479533,-9371869,-21393143,2465074]),
3424   xy2d: Fe([20017163,-4323226,27915242,1529148,12396362,15675764,13817261,-9658066,2463391,-4622140]),
3425  },
3426  GePrecomp {
3427   y_plus_x: Fe([-16358878,-12663911,-12065183,4996454,-1256422,1073572,9583558,12851107,4003896,12673717]),
3428   y_minus_x: Fe([-1731589,-15155870,-3262930,16143082,19294135,13385325,14741514,-9103726,7903886,2348101]),
3429   xy2d: Fe([24536016,-16515207,12715592,-3862155,1511293,10047386,-3842346,-7129159,-28377538,10048127]),
3430  },
3431 ],
3432 [
3433  GePrecomp {
3434   y_plus_x: Fe([-12622226,-6204820,30718825,2591312,-10617028,12192840,18873298,-7297090,-32297756,15221632]),
3435   y_minus_x: Fe([-26478122,-11103864,11546244,-1852483,9180880,7656409,-21343950,2095755,29769758,6593415]),
3436   xy2d: Fe([-31994208,-2907461,4176912,3264766,12538965,-868111,26312345,-6118678,30958054,8292160]),
3437  },
3438  GePrecomp {
3439   y_plus_x: Fe([31429822,-13959116,29173532,15632448,12174511,-2760094,32808831,3977186,26143136,-3148876]),
3440   y_minus_x: Fe([22648901,1402143,-22799984,13746059,7936347,365344,-8668633,-1674433,-3758243,-2304625]),
3441   xy2d: Fe([-15491917,8012313,-2514730,-12702462,-23965846,-10254029,-1612713,-1535569,-16664475,8194478]),
3442  },
3443  GePrecomp {
3444   y_plus_x: Fe([27338066,-7507420,-7414224,10140405,-19026427,-6589889,27277191,8855376,28572286,3005164]),
3445   y_minus_x: Fe([26287124,4821776,25476601,-4145903,-3764513,-15788984,-18008582,1182479,-26094821,-13079595]),
3446   xy2d: Fe([-7171154,3178080,23970071,6201893,-17195577,-4489192,-21876275,-13982627,32208683,-1198248]),
3447  },
3448  GePrecomp {
3449   y_plus_x: Fe([-16657702,2817643,-10286362,14811298,6024667,13349505,-27315504,-10497842,-27672585,-11539858]),
3450   y_minus_x: Fe([15941029,-9405932,-21367050,8062055,31876073,-238629,-15278393,-1444429,15397331,-4130193]),
3451   xy2d: Fe([8934485,-13485467,-23286397,-13423241,-32446090,14047986,31170398,-1441021,-27505566,15087184]),
3452  },
3453  GePrecomp {
3454   y_plus_x: Fe([-18357243,-2156491,24524913,-16677868,15520427,-6360776,-15502406,11461896,16788528,-5868942]),
3455   y_minus_x: Fe([-1947386,16013773,21750665,3714552,-17401782,-16055433,-3770287,-10323320,31322514,-11615635]),
3456   xy2d: Fe([21426655,-5650218,-13648287,-5347537,-28812189,-4920970,-18275391,-14621414,13040862,-12112948]),
3457  },
3458  GePrecomp {
3459   y_plus_x: Fe([11293895,12478086,-27136401,15083750,-29307421,14748872,14555558,-13417103,1613711,4896935]),
3460   y_minus_x: Fe([-25894883,15323294,-8489791,-8057900,25967126,-13425460,2825960,-4897045,-23971776,-11267415]),
3461   xy2d: Fe([-15924766,-5229880,-17443532,6410664,3622847,10243618,20615400,12405433,-23753030,-8436416]),
3462  },
3463  GePrecomp {
3464   y_plus_x: Fe([-7091295,12556208,-20191352,9025187,-17072479,4333801,4378436,2432030,23097949,-566018]),
3465   y_minus_x: Fe([4565804,-16025654,20084412,-7842817,1724999,189254,24767264,10103221,-18512313,2424778]),
3466   xy2d: Fe([366633,-11976806,8173090,-6890119,30788634,5745705,-7168678,1344109,-3642553,12412659]),
3467  },
3468  GePrecomp {
3469   y_plus_x: Fe([-24001791,7690286,14929416,-168257,-32210835,-13412986,24162697,-15326504,-3141501,11179385]),
3470   y_minus_x: Fe([18289522,-14724954,8056945,16430056,-21729724,7842514,-6001441,-1486897,-18684645,-11443503]),
3471   xy2d: Fe([476239,6601091,-6152790,-9723375,17503545,-4863900,27672959,13403813,11052904,5219329]),
3472  },
3473 ],
3474 [
3475  GePrecomp {
3476   y_plus_x: Fe([20678546,-8375738,-32671898,8849123,-5009758,14574752,31186971,-3973730,9014762,-8579056]),
3477   y_minus_x: Fe([-13644050,-10350239,-15962508,5075808,-1514661,-11534600,-33102500,9160280,8473550,-3256838]),
3478   xy2d: Fe([24900749,14435722,17209120,-15292541,-22592275,9878983,-7689309,-16335821,-24568481,11788948]),
3479  },
3480  GePrecomp {
3481   y_plus_x: Fe([-3118155,-11395194,-13802089,14797441,9652448,-6845904,-20037437,10410733,-24568470,-1458691]),
3482   y_minus_x: Fe([-15659161,16736706,-22467150,10215878,-9097177,7563911,11871841,-12505194,-18513325,8464118]),
3483   xy2d: Fe([-23400612,8348507,-14585951,-861714,-3950205,-6373419,14325289,8628612,33313881,-8370517]),
3484  },
3485  GePrecomp {
3486   y_plus_x: Fe([-20186973,-4967935,22367356,5271547,-1097117,-4788838,-24805667,-10236854,-8940735,-5818269]),
3487   y_minus_x: Fe([-6948785,-1795212,-32625683,-16021179,32635414,-7374245,15989197,-12838188,28358192,-4253904]),
3488   xy2d: Fe([-23561781,-2799059,-32351682,-1661963,-9147719,10429267,-16637684,4072016,-5351664,5596589]),
3489  },
3490  GePrecomp {
3491   y_plus_x: Fe([-28236598,-3390048,12312896,6213178,3117142,16078565,29266239,2557221,1768301,15373193]),
3492   y_minus_x: Fe([-7243358,-3246960,-4593467,-7553353,-127927,-912245,-1090902,-4504991,-24660491,3442910]),
3493   xy2d: Fe([-30210571,5124043,14181784,8197961,18964734,-11939093,22597931,7176455,-18585478,13365930]),
3494  },
3495  GePrecomp {
3496   y_plus_x: Fe([-7877390,-1499958,8324673,4690079,6261860,890446,24538107,-8570186,-9689599,-3031667]),
3497   y_minus_x: Fe([25008904,-10771599,-4305031,-9638010,16265036,15721635,683793,-11823784,15723479,-15163481]),
3498   xy2d: Fe([-9660625,12374379,-27006999,-7026148,-7724114,-12314514,11879682,5400171,519526,-1235876]),
3499  },
3500  GePrecomp {
3501   y_plus_x: Fe([22258397,-16332233,-7869817,14613016,-22520255,-2950923,-20353881,7315967,16648397,7605640]),
3502   y_minus_x: Fe([-8081308,-8464597,-8223311,9719710,19259459,-15348212,23994942,-5281555,-9468848,4763278]),
3503   xy2d: Fe([-21699244,9220969,-15730624,1084137,-25476107,-2852390,31088447,-7764523,-11356529,728112]),
3504  },
3505  GePrecomp {
3506   y_plus_x: Fe([26047220,-11751471,-6900323,-16521798,24092068,9158119,-4273545,-12555558,-29365436,-5498272]),
3507   y_minus_x: Fe([17510331,-322857,5854289,8403524,17133918,-3112612,-28111007,12327945,10750447,10014012]),
3508   xy2d: Fe([-10312768,3936952,9156313,-8897683,16498692,-994647,-27481051,-666732,3424691,7540221]),
3509  },
3510  GePrecomp {
3511   y_plus_x: Fe([30322361,-6964110,11361005,-4143317,7433304,4989748,-7071422,-16317219,-9244265,15258046]),
3512   y_minus_x: Fe([13054562,-2779497,19155474,469045,-12482797,4566042,5631406,2711395,1062915,-5136345]),
3513   xy2d: Fe([-19240248,-11254599,-29509029,-7499965,-5835763,13005411,-6066489,12194497,32960380,1459310]),
3514  },
3515 ],
3516 [
3517  GePrecomp {
3518   y_plus_x: Fe([19852034,7027924,23669353,10020366,8586503,-6657907,394197,-6101885,18638003,-11174937]),
3519   y_minus_x: Fe([31395534,15098109,26581030,8030562,-16527914,-5007134,9012486,-7584354,-6643087,-5442636]),
3520   xy2d: Fe([-9192165,-2347377,-1997099,4529534,25766844,607986,-13222,9677543,-32294889,-6456008]),
3521  },
3522  GePrecomp {
3523   y_plus_x: Fe([-2444496,-149937,29348902,8186665,1873760,12489863,-30934579,-7839692,-7852844,-8138429]),
3524   y_minus_x: Fe([-15236356,-15433509,7766470,746860,26346930,-10221762,-27333451,10754588,-9431476,5203576]),
3525   xy2d: Fe([31834314,14135496,-770007,5159118,20917671,-16768096,-7467973,-7337524,31809243,7347066]),
3526  },
3527  GePrecomp {
3528   y_plus_x: Fe([-9606723,-11874240,20414459,13033986,13716524,-11691881,19797970,-12211255,15192876,-2087490]),
3529   y_minus_x: Fe([-12663563,-2181719,1168162,-3804809,26747877,-14138091,10609330,12694420,33473243,-13382104]),
3530   xy2d: Fe([33184999,11180355,15832085,-11385430,-1633671,225884,15089336,-11023903,-6135662,14480053]),
3531  },
3532  GePrecomp {
3533   y_plus_x: Fe([31308717,-5619998,31030840,-1897099,15674547,-6582883,5496208,13685227,27595050,8737275]),
3534   y_minus_x: Fe([-20318852,-15150239,10933843,-16178022,8335352,-7546022,-31008351,-12610604,26498114,66511]),
3535   xy2d: Fe([22644454,-8761729,-16671776,4884562,-3105614,-13559366,30540766,-4286747,-13327787,-7515095]),
3536  },
3537  GePrecomp {
3538   y_plus_x: Fe([-28017847,9834845,18617207,-2681312,-3401956,-13307506,8205540,13585437,-17127465,15115439]),
3539   y_minus_x: Fe([23711543,-672915,31206561,-8362711,6164647,-9709987,-33535882,-1426096,8236921,16492939]),
3540   xy2d: Fe([-23910559,-13515526,-26299483,-4503841,25005590,-7687270,19574902,10071562,6708380,-6222424]),
3541  },
3542  GePrecomp {
3543   y_plus_x: Fe([2101391,-4930054,19702731,2367575,-15427167,1047675,5301017,9328700,29955601,-11678310]),
3544   y_minus_x: Fe([3096359,9271816,-21620864,-15521844,-14847996,-7592937,-25892142,-12635595,-9917575,6216608]),
3545   xy2d: Fe([-32615849,338663,-25195611,2510422,-29213566,-13820213,24822830,-6146567,-26767480,7525079]),
3546  },
3547  GePrecomp {
3548   y_plus_x: Fe([-23066649,-13985623,16133487,-7896178,-3389565,778788,-910336,-2782495,-19386633,11994101]),
3549   y_minus_x: Fe([21691500,-13624626,-641331,-14367021,3285881,-3483596,-25064666,9718258,-7477437,13381418]),
3550   xy2d: Fe([18445390,-4202236,14979846,11622458,-1727110,-3582980,23111648,-6375247,28535282,15779576]),
3551  },
3552  GePrecomp {
3553   y_plus_x: Fe([30098053,3089662,-9234387,16662135,-21306940,11308411,-14068454,12021730,9955285,-16303356]),
3554   y_minus_x: Fe([9734894,-14576830,-7473633,-9138735,2060392,11313496,-18426029,9924399,20194861,13380996]),
3555   xy2d: Fe([-26378102,-7965207,-22167821,15789297,-18055342,-6168792,-1984914,15707771,26342023,10146099]),
3556  },
3557 ],
3558 [
3559  GePrecomp {
3560   y_plus_x: Fe([-26016874,-219943,21339191,-41388,19745256,-2878700,-29637280,2227040,21612326,-545728]),
3561   y_minus_x: Fe([-13077387,1184228,23562814,-5970442,-20351244,-6348714,25764461,12243797,-20856566,11649658]),
3562   xy2d: Fe([-10031494,11262626,27384172,2271902,26947504,-15997771,39944,6114064,33514190,2333242]),
3563  },
3564  GePrecomp {
3565   y_plus_x: Fe([-21433588,-12421821,8119782,7219913,-21830522,-9016134,-6679750,-12670638,24350578,-13450001]),
3566   y_minus_x: Fe([-4116307,-11271533,-23886186,4843615,-30088339,690623,-31536088,-10406836,8317860,12352766]),
3567   xy2d: Fe([18200138,-14475911,-33087759,-2696619,-23702521,-9102511,-23552096,-2287550,20712163,6719373]),
3568  },
3569  GePrecomp {
3570   y_plus_x: Fe([26656208,6075253,-7858556,1886072,-28344043,4262326,11117530,-3763210,26224235,-3297458]),
3571   y_minus_x: Fe([-17168938,-14854097,-3395676,-16369877,-19954045,14050420,21728352,9493610,18620611,-16428628]),
3572   xy2d: Fe([-13323321,13325349,11432106,5964811,18609221,6062965,-5269471,-9725556,-30701573,-16479657]),
3573  },
3574  GePrecomp {
3575   y_plus_x: Fe([-23860538,-11233159,26961357,1640861,-32413112,-16737940,12248509,-5240639,13735342,1934062]),
3576   y_minus_x: Fe([25089769,6742589,17081145,-13406266,21909293,-16067981,-15136294,-3765346,-21277997,5473616]),
3577   xy2d: Fe([31883677,-7961101,1083432,-11572403,22828471,13290673,-7125085,12469656,29111212,-5451014]),
3578  },
3579  GePrecomp {
3580   y_plus_x: Fe([24244947,-15050407,-26262976,2791540,-14997599,16666678,24367466,6388839,-10295587,452383]),
3581   y_minus_x: Fe([-25640782,-3417841,5217916,16224624,19987036,-4082269,-24236251,-5915248,15766062,8407814]),
3582   xy2d: Fe([-20406999,13990231,15495425,16395525,5377168,15166495,-8917023,-4388953,-8067909,2276718]),
3583  },
3584  GePrecomp {
3585   y_plus_x: Fe([30157918,12924066,-17712050,9245753,19895028,3368142,-23827587,5096219,22740376,-7303417]),
3586   y_minus_x: Fe([2041139,-14256350,7783687,13876377,-25946985,-13352459,24051124,13742383,-15637599,13295222]),
3587   xy2d: Fe([33338237,-8505733,12532113,7977527,9106186,-1715251,-17720195,-4612972,-4451357,-14669444]),
3588  },
3589  GePrecomp {
3590   y_plus_x: Fe([-20045281,5454097,-14346548,6447146,28862071,1883651,-2469266,-4141880,7770569,9620597]),
3591   y_minus_x: Fe([23208068,7979712,33071466,8149229,1758231,-10834995,30945528,-1694323,-33502340,-14767970]),
3592   xy2d: Fe([1439958,-16270480,-1079989,-793782,4625402,10647766,-5043801,1220118,30494170,-11440799]),
3593  },
3594  GePrecomp {
3595   y_plus_x: Fe([-5037580,-13028295,-2970559,-3061767,15640974,-6701666,-26739026,926050,-1684339,-13333647]),
3596   y_minus_x: Fe([13908495,-3549272,30919928,-6273825,-21521863,7989039,9021034,9078865,3353509,4033511]),
3597   xy2d: Fe([-29663431,-15113610,32259991,-344482,24295849,-12912123,23161163,8839127,27485041,7356032]),
3598  },
3599 ],
3600 [
3601  GePrecomp {
3602   y_plus_x: Fe([9661027,705443,11980065,-5370154,-1628543,14661173,-6346142,2625015,28431036,-16771834]),
3603   y_minus_x: Fe([-23839233,-8311415,-25945511,7480958,-17681669,-8354183,-22545972,14150565,15970762,4099461]),
3604   xy2d: Fe([29262576,16756590,26350592,-8793563,8529671,-11208050,13617293,-9937143,11465739,8317062]),
3605  },
3606  GePrecomp {
3607   y_plus_x: Fe([-25493081,-6962928,32500200,-9419051,-23038724,-2302222,14898637,3848455,20969334,-5157516]),
3608   y_minus_x: Fe([-20384450,-14347713,-18336405,13884722,-33039454,2842114,-21610826,-3649888,11177095,14989547]),
3609   xy2d: Fe([-24496721,-11716016,16959896,2278463,12066309,10137771,13515641,2581286,-28487508,9930240]),
3610  },
3611  GePrecomp {
3612   y_plus_x: Fe([-17751622,-2097826,16544300,-13009300,-15914807,-14949081,18345767,-13403753,16291481,-5314038]),
3613   y_minus_x: Fe([-33229194,2553288,32678213,9875984,8534129,6889387,-9676774,6957617,4368891,9788741]),
3614   xy2d: Fe([16660756,7281060,-10830758,12911820,20108584,-8101676,-21722536,-8613148,16250552,-11111103]),
3615  },
3616  GePrecomp {
3617   y_plus_x: Fe([-19765507,2390526,-16551031,14161980,1905286,6414907,4689584,10604807,-30190403,4782747]),
3618   y_minus_x: Fe([-1354539,14736941,-7367442,-13292886,7710542,-14155590,-9981571,4383045,22546403,437323]),
3619   xy2d: Fe([31665577,-12180464,-16186830,1491339,-18368625,3294682,27343084,2786261,-30633590,-14097016]),
3620  },
3621  GePrecomp {
3622   y_plus_x: Fe([-14467279,-683715,-33374107,7448552,19294360,14334329,-19690631,2355319,-19284671,-6114373]),
3623   y_minus_x: Fe([15121312,-15796162,6377020,-6031361,-10798111,-12957845,18952177,15496498,-29380133,11754228]),
3624   xy2d: Fe([-2637277,-13483075,8488727,-14303896,12728761,-1622493,7141596,11724556,22761615,-10134141]),
3625  },
3626  GePrecomp {
3627   y_plus_x: Fe([16918416,11729663,-18083579,3022987,-31015732,-13339659,-28741185,-12227393,32851222,11717399]),
3628   y_minus_x: Fe([11166634,7338049,-6722523,4531520,-29468672,-7302055,31474879,3483633,-1193175,-4030831]),
3629   xy2d: Fe([-185635,9921305,31456609,-13536438,-12013818,13348923,33142652,6546660,-19985279,-3948376]),
3630  },
3631  GePrecomp {
3632   y_plus_x: Fe([-32460596,11266712,-11197107,-7899103,31703694,3855903,-8537131,-12833048,-30772034,-15486313]),
3633   y_minus_x: Fe([-18006477,12709068,3991746,-6479188,-21491523,-10550425,-31135347,-16049879,10928917,3011958]),
3634   xy2d: Fe([-6957757,-15594337,31696059,334240,29576716,14796075,-30831056,-12805180,18008031,10258577]),
3635  },
3636  GePrecomp {
3637   y_plus_x: Fe([-22448644,15655569,7018479,-4410003,-30314266,-1201591,-1853465,1367120,25127874,6671743]),
3638   y_minus_x: Fe([29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684]),
3639   xy2d: Fe([-20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476]),
3640  },
3641 ],
3642 ];
3643