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