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