crypto/
curve25519.rs

1use std::ops::{Add, Sub, Mul};
2use std::cmp::{Eq, PartialEq,min};
3use util::{fixed_time_eq};
4use step_by::RangeExt;
5
6/*
7fe means field element.
8Here the field is \Z/(2^255-19).
9An element t, entries t[0]...t[9], represents the integer
10t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
11Bounds on each t[i] vary depending on context.
12*/
13
14#[derive(Clone, Copy)]
15pub struct Fe(pub [i32; 10]);
16
17impl PartialEq for Fe {
18    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}
24impl Eq for Fe { }
25
26static FE_ZERO : Fe = Fe([0,0,0,0,0,0,0,0,0,0]);
27static FE_ONE : Fe = Fe([1,0,0,0,0,0,0,0,0,0]);
28static FE_SQRTM1 : Fe = Fe([-32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482]);
29static FE_D : Fe = Fe([-10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116]);
30static FE_D2 : Fe = Fe([-21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199]);
31
32
33fn 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}
39fn load_4i(s: &[u8]) -> i64 {
40    load_4u(s) as i64
41}
42fn load_3u(s: &[u8]) -> u64 {
43    (s[0] as u64)
44        | ((s[1] as u64)<<8)
45        | ((s[2] as u64)<<16)
46}
47fn load_3i(s: &[u8]) -> i64 {
48    load_3u(s) as i64
49}
50
51impl 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    */
65    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
103impl 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    */
117    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
155impl 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
190    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
403impl Fe {
404    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
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
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
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
650    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    */
695    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
810    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
946    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
1021    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
1027    fn is_negative(&self) -> bool {
1028        (self.to_bytes()[0] & 1) != 0
1029    }
1030
1031    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
1037    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)]
1066pub struct GeP2 {
1067    x: Fe,
1068    y: Fe,
1069    z: Fe,
1070}
1071
1072#[derive(Clone, Copy)]
1073pub struct GeP3 {
1074    x: Fe,
1075    y: Fe,
1076    z: Fe,
1077    t: Fe,
1078}
1079
1080#[derive(Clone, Copy)]
1081pub struct GeP1P1 {
1082    x: Fe,
1083    y: Fe,
1084    z: Fe,
1085    t: Fe,
1086}
1087
1088#[derive(Clone, Copy)]
1089pub struct GePrecomp {
1090    y_plus_x: Fe,
1091    y_minus_x: Fe,
1092    xy2d: Fe,
1093}
1094
1095#[derive(Clone, Copy)]
1096pub struct GeCached {
1097    y_plus_x: Fe,
1098    y_minus_x: Fe,
1099    z: Fe,
1100    t2d: Fe,
1101}
1102
1103impl GeP1P1 {
1104    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
1113    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
1124impl GeP2 {
1125    fn zero() -> GeP2 {
1126        GeP2 {
1127            x: FE_ZERO,
1128            y: FE_ONE,
1129            z: FE_ONE,
1130        }
1131    }
1132
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
1142    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
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    */
1193    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
1246impl 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
1278    fn to_p2(&self) -> GeP2 {
1279        GeP2 {
1280            x: self.x,
1281            y: self.y,
1282            z: self.z,
1283        }
1284    }
1285
1286    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
1295    fn zero() -> GeP3 {
1296        GeP3 {
1297            x: FE_ZERO,
1298            y: FE_ONE,
1299            z: FE_ONE,
1300            t: FE_ZERO,
1301        }
1302    }
1303
1304    fn dbl(&self) -> GeP1P1 {
1305        self.to_p2().dbl()
1306    }
1307
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
1320impl Add<GeCached> for GeP3 {
1321    type Output = GeP1P1;
1322
1323    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
1340impl Add<GePrecomp> for GeP3 {
1341    type Output = GeP1P1;
1342
1343    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
1359impl Sub<GeCached> for GeP3 {
1360    type Output = GeP1P1;
1361
1362    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
1379impl Sub<GePrecomp> for GeP3 {
1380    type Output = GeP1P1;
1381
1382    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
1398fn 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
1408impl GePrecomp {
1409    fn zero() -> GePrecomp {
1410        GePrecomp {
1411            y_plus_x: FE_ONE,
1412            y_minus_x: FE_ONE,
1413            xy2d: FE_ZERO,
1414        }
1415    }
1416
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
1423    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/*
1446h = a * B
1447where a = a[0]+256*a[1]+...+256^31 a[31]
1448B is the Ed25519 base point (x,4/5) with x positive.
1449
1450Preconditions:
1451  a[31] <= 127
1452*/
1453pub 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/*
1497Input:
1498    s[0]+256*s[1]+...+256^63*s[63] = s
1499
1500Output:
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*/
1505pub 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/*
1748Input:
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
1753Output:
1754    s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
1755    where l = 2^252 + 27742317777372353535851937790883648493.
1756*/
1757pub 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
2091pub 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
2152pub 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)]
2159mod tests {
2160    use curve25519::{Fe, curve25519_base};
2161
2162    #[test]
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]
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 {
2194        fn new(seed: u32) -> CurveGen {
2195            CurveGen{which: seed}
2196        }
2197    }
2198    impl Iterator for CurveGen {
2199        type Item = Fe;
2200
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]
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]
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]
2225    fn invert_inverts() {
2226       for x in CurveGen::new(1).take(40) {
2227          assert!(x.invert().invert() == x);
2228       };
2229    }
2230
2231    #[test]
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]
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
2254static 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
2297static 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];