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