Coverage Report

Created: 2022-08-24 06:30

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