File Coverage

src/ed25519/fe.c
Criterion Covered Total %
statement 963 1072 89.8
branch 40 44 90.9
condition n/a
subroutine n/a
pod n/a
total 1003 1116 89.8


line stmt bran cond sub pod time code
1             #include "fixedint.h"
2             #include "fe.h"
3              
4              
5             /*
6             helper functions
7             */
8 8           static uint64_t load_3(const unsigned char *in) {
9             uint64_t result;
10              
11 8           result = (uint64_t) in[0];
12 8           result |= ((uint64_t) in[1]) << 8;
13 8           result |= ((uint64_t) in[2]) << 16;
14              
15 8           return result;
16             }
17              
18 2           static uint64_t load_4(const unsigned char *in) {
19             uint64_t result;
20              
21 2           result = (uint64_t) in[0];
22 2           result |= ((uint64_t) in[1]) << 8;
23 2           result |= ((uint64_t) in[2]) << 16;
24 2           result |= ((uint64_t) in[3]) << 24;
25            
26 2           return result;
27             }
28              
29              
30              
31             /*
32             h = 0
33             */
34              
35 133           void fe_0(fe h) {
36 133           h[0] = 0;
37 133           h[1] = 0;
38 133           h[2] = 0;
39 133           h[3] = 0;
40 133           h[4] = 0;
41 133           h[5] = 0;
42 133           h[6] = 0;
43 133           h[7] = 0;
44 133           h[8] = 0;
45 133           h[9] = 0;
46 133           }
47              
48              
49              
50             /*
51             h = 1
52             */
53              
54 263           void fe_1(fe h) {
55 263           h[0] = 1;
56 263           h[1] = 0;
57 263           h[2] = 0;
58 263           h[3] = 0;
59 263           h[4] = 0;
60 263           h[5] = 0;
61 263           h[6] = 0;
62 263           h[7] = 0;
63 263           h[8] = 0;
64 263           h[9] = 0;
65 263           }
66              
67              
68              
69             /*
70             h = f + g
71             Can overlap h with f or g.
72              
73             Preconditions:
74             |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
75             |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
76              
77             Postconditions:
78             |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
79             */
80              
81 1405           void fe_add(fe h, const fe f, const fe g) {
82 1405           int32_t f0 = f[0];
83 1405           int32_t f1 = f[1];
84 1405           int32_t f2 = f[2];
85 1405           int32_t f3 = f[3];
86 1405           int32_t f4 = f[4];
87 1405           int32_t f5 = f[5];
88 1405           int32_t f6 = f[6];
89 1405           int32_t f7 = f[7];
90 1405           int32_t f8 = f[8];
91 1405           int32_t f9 = f[9];
92 1405           int32_t g0 = g[0];
93 1405           int32_t g1 = g[1];
94 1405           int32_t g2 = g[2];
95 1405           int32_t g3 = g[3];
96 1405           int32_t g4 = g[4];
97 1405           int32_t g5 = g[5];
98 1405           int32_t g6 = g[6];
99 1405           int32_t g7 = g[7];
100 1405           int32_t g8 = g[8];
101 1405           int32_t g9 = g[9];
102 1405           int32_t h0 = f0 + g0;
103 1405           int32_t h1 = f1 + g1;
104 1405           int32_t h2 = f2 + g2;
105 1405           int32_t h3 = f3 + g3;
106 1405           int32_t h4 = f4 + g4;
107 1405           int32_t h5 = f5 + g5;
108 1405           int32_t h6 = f6 + g6;
109 1405           int32_t h7 = f7 + g7;
110 1405           int32_t h8 = f8 + g8;
111 1405           int32_t h9 = f9 + g9;
112            
113 1405           h[0] = h0;
114 1405           h[1] = h1;
115 1405           h[2] = h2;
116 1405           h[3] = h3;
117 1405           h[4] = h4;
118 1405           h[5] = h5;
119 1405           h[6] = h6;
120 1405           h[7] = h7;
121 1405           h[8] = h8;
122 1405           h[9] = h9;
123 1405           }
124              
125              
126              
127             /*
128             Replace (f,g) with (g,g) if b == 1;
129             replace (f,g) with (f,g) if b == 0.
130              
131             Preconditions: b in {0,1}.
132             */
133              
134 3456           void fe_cmov(fe f, const fe g, unsigned int b) {
135 3456           int32_t f0 = f[0];
136 3456           int32_t f1 = f[1];
137 3456           int32_t f2 = f[2];
138 3456           int32_t f3 = f[3];
139 3456           int32_t f4 = f[4];
140 3456           int32_t f5 = f[5];
141 3456           int32_t f6 = f[6];
142 3456           int32_t f7 = f[7];
143 3456           int32_t f8 = f[8];
144 3456           int32_t f9 = f[9];
145 3456           int32_t g0 = g[0];
146 3456           int32_t g1 = g[1];
147 3456           int32_t g2 = g[2];
148 3456           int32_t g3 = g[3];
149 3456           int32_t g4 = g[4];
150 3456           int32_t g5 = g[5];
151 3456           int32_t g6 = g[6];
152 3456           int32_t g7 = g[7];
153 3456           int32_t g8 = g[8];
154 3456           int32_t g9 = g[9];
155 3456           int32_t x0 = f0 ^ g0;
156 3456           int32_t x1 = f1 ^ g1;
157 3456           int32_t x2 = f2 ^ g2;
158 3456           int32_t x3 = f3 ^ g3;
159 3456           int32_t x4 = f4 ^ g4;
160 3456           int32_t x5 = f5 ^ g5;
161 3456           int32_t x6 = f6 ^ g6;
162 3456           int32_t x7 = f7 ^ g7;
163 3456           int32_t x8 = f8 ^ g8;
164 3456           int32_t x9 = f9 ^ g9;
165              
166 3456           b = (unsigned int) (- (int) b); /* silence warning */
167 3456           x0 &= b;
168 3456           x1 &= b;
169 3456           x2 &= b;
170 3456           x3 &= b;
171 3456           x4 &= b;
172 3456           x5 &= b;
173 3456           x6 &= b;
174 3456           x7 &= b;
175 3456           x8 &= b;
176 3456           x9 &= b;
177            
178 3456           f[0] = f0 ^ x0;
179 3456           f[1] = f1 ^ x1;
180 3456           f[2] = f2 ^ x2;
181 3456           f[3] = f3 ^ x3;
182 3456           f[4] = f4 ^ x4;
183 3456           f[5] = f5 ^ x5;
184 3456           f[6] = f6 ^ x6;
185 3456           f[7] = f7 ^ x7;
186 3456           f[8] = f8 ^ x8;
187 3456           f[9] = f9 ^ x9;
188 3456           }
189              
190             /*
191             Replace (f,g) with (g,f) if b == 1;
192             replace (f,g) with (f,g) if b == 0.
193              
194             Preconditions: b in {0,1}.
195             */
196              
197 0           void fe_cswap(fe f,fe g,unsigned int b) {
198 0           int32_t f0 = f[0];
199 0           int32_t f1 = f[1];
200 0           int32_t f2 = f[2];
201 0           int32_t f3 = f[3];
202 0           int32_t f4 = f[4];
203 0           int32_t f5 = f[5];
204 0           int32_t f6 = f[6];
205 0           int32_t f7 = f[7];
206 0           int32_t f8 = f[8];
207 0           int32_t f9 = f[9];
208 0           int32_t g0 = g[0];
209 0           int32_t g1 = g[1];
210 0           int32_t g2 = g[2];
211 0           int32_t g3 = g[3];
212 0           int32_t g4 = g[4];
213 0           int32_t g5 = g[5];
214 0           int32_t g6 = g[6];
215 0           int32_t g7 = g[7];
216 0           int32_t g8 = g[8];
217 0           int32_t g9 = g[9];
218 0           int32_t x0 = f0 ^ g0;
219 0           int32_t x1 = f1 ^ g1;
220 0           int32_t x2 = f2 ^ g2;
221 0           int32_t x3 = f3 ^ g3;
222 0           int32_t x4 = f4 ^ g4;
223 0           int32_t x5 = f5 ^ g5;
224 0           int32_t x6 = f6 ^ g6;
225 0           int32_t x7 = f7 ^ g7;
226 0           int32_t x8 = f8 ^ g8;
227 0           int32_t x9 = f9 ^ g9;
228 0           b = (unsigned int) (- (int) b); /* silence warning */
229 0           x0 &= b;
230 0           x1 &= b;
231 0           x2 &= b;
232 0           x3 &= b;
233 0           x4 &= b;
234 0           x5 &= b;
235 0           x6 &= b;
236 0           x7 &= b;
237 0           x8 &= b;
238 0           x9 &= b;
239 0           f[0] = f0 ^ x0;
240 0           f[1] = f1 ^ x1;
241 0           f[2] = f2 ^ x2;
242 0           f[3] = f3 ^ x3;
243 0           f[4] = f4 ^ x4;
244 0           f[5] = f5 ^ x5;
245 0           f[6] = f6 ^ x6;
246 0           f[7] = f7 ^ x7;
247 0           f[8] = f8 ^ x8;
248 0           f[9] = f9 ^ x9;
249 0           g[0] = g0 ^ x0;
250 0           g[1] = g1 ^ x1;
251 0           g[2] = g2 ^ x2;
252 0           g[3] = g3 ^ x3;
253 0           g[4] = g4 ^ x4;
254 0           g[5] = g5 ^ x5;
255 0           g[6] = g6 ^ x6;
256 0           g[7] = g7 ^ x7;
257 0           g[8] = g8 ^ x8;
258 0           g[9] = g9 ^ x9;
259 0           }
260              
261              
262              
263             /*
264             h = f
265             */
266              
267 273           void fe_copy(fe h, const fe f) {
268 273           int32_t f0 = f[0];
269 273           int32_t f1 = f[1];
270 273           int32_t f2 = f[2];
271 273           int32_t f3 = f[3];
272 273           int32_t f4 = f[4];
273 273           int32_t f5 = f[5];
274 273           int32_t f6 = f[6];
275 273           int32_t f7 = f[7];
276 273           int32_t f8 = f[8];
277 273           int32_t f9 = f[9];
278            
279 273           h[0] = f0;
280 273           h[1] = f1;
281 273           h[2] = f2;
282 273           h[3] = f3;
283 273           h[4] = f4;
284 273           h[5] = f5;
285 273           h[6] = f6;
286 273           h[7] = f7;
287 273           h[8] = f8;
288 273           h[9] = f9;
289 273           }
290              
291              
292              
293             /*
294             Ignores top bit of h.
295             */
296              
297 1           void fe_frombytes(fe h, const unsigned char *s) {
298 1           int64_t h0 = load_4(s);
299 1           int64_t h1 = load_3(s + 4) << 6;
300 1           int64_t h2 = load_3(s + 7) << 5;
301 1           int64_t h3 = load_3(s + 10) << 3;
302 1           int64_t h4 = load_3(s + 13) << 2;
303 1           int64_t h5 = load_4(s + 16);
304 1           int64_t h6 = load_3(s + 20) << 7;
305 1           int64_t h7 = load_3(s + 23) << 5;
306 1           int64_t h8 = load_3(s + 26) << 4;
307 1           int64_t h9 = (load_3(s + 29) & 8388607) << 2;
308             int64_t carry0;
309             int64_t carry1;
310             int64_t carry2;
311             int64_t carry3;
312             int64_t carry4;
313             int64_t carry5;
314             int64_t carry6;
315             int64_t carry7;
316             int64_t carry8;
317             int64_t carry9;
318              
319 1           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
320 1           h0 += carry9 * 19;
321 1           h9 -= carry9 << 25;
322 1           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
323 1           h2 += carry1;
324 1           h1 -= carry1 << 25;
325 1           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
326 1           h4 += carry3;
327 1           h3 -= carry3 << 25;
328 1           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
329 1           h6 += carry5;
330 1           h5 -= carry5 << 25;
331 1           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
332 1           h8 += carry7;
333 1           h7 -= carry7 << 25;
334 1           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
335 1           h1 += carry0;
336 1           h0 -= carry0 << 26;
337 1           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
338 1           h3 += carry2;
339 1           h2 -= carry2 << 26;
340 1           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
341 1           h5 += carry4;
342 1           h4 -= carry4 << 26;
343 1           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
344 1           h7 += carry6;
345 1           h6 -= carry6 << 26;
346 1           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
347 1           h9 += carry8;
348 1           h8 -= carry8 << 26;
349              
350 1           h[0] = (int32_t) h0;
351 1           h[1] = (int32_t) h1;
352 1           h[2] = (int32_t) h2;
353 1           h[3] = (int32_t) h3;
354 1           h[4] = (int32_t) h4;
355 1           h[5] = (int32_t) h5;
356 1           h[6] = (int32_t) h6;
357 1           h[7] = (int32_t) h7;
358 1           h[8] = (int32_t) h8;
359 1           h[9] = (int32_t) h9;
360 1           }
361              
362              
363              
364 3           void fe_invert(fe out, const fe z) {
365             fe t0;
366             fe t1;
367             fe t2;
368             fe t3;
369             int i;
370              
371 3           fe_sq(t0, z);
372              
373 3 50         for (i = 1; i < 1; ++i) {
374 0           fe_sq(t0, t0);
375             }
376              
377 3           fe_sq(t1, t0);
378              
379 6 100         for (i = 1; i < 2; ++i) {
380 3           fe_sq(t1, t1);
381             }
382              
383 3           fe_mul(t1, z, t1);
384 3           fe_mul(t0, t0, t1);
385 3           fe_sq(t2, t0);
386              
387 3 50         for (i = 1; i < 1; ++i) {
388 0           fe_sq(t2, t2);
389             }
390              
391 3           fe_mul(t1, t1, t2);
392 3           fe_sq(t2, t1);
393              
394 15 100         for (i = 1; i < 5; ++i) {
395 12           fe_sq(t2, t2);
396             }
397              
398 3           fe_mul(t1, t2, t1);
399 3           fe_sq(t2, t1);
400              
401 30 100         for (i = 1; i < 10; ++i) {
402 27           fe_sq(t2, t2);
403             }
404              
405 3           fe_mul(t2, t2, t1);
406 3           fe_sq(t3, t2);
407              
408 60 100         for (i = 1; i < 20; ++i) {
409 57           fe_sq(t3, t3);
410             }
411              
412 3           fe_mul(t2, t3, t2);
413 3           fe_sq(t2, t2);
414              
415 30 100         for (i = 1; i < 10; ++i) {
416 27           fe_sq(t2, t2);
417             }
418              
419 3           fe_mul(t1, t2, t1);
420 3           fe_sq(t2, t1);
421              
422 150 100         for (i = 1; i < 50; ++i) {
423 147           fe_sq(t2, t2);
424             }
425              
426 3           fe_mul(t2, t2, t1);
427 3           fe_sq(t3, t2);
428              
429 300 100         for (i = 1; i < 100; ++i) {
430 297           fe_sq(t3, t3);
431             }
432              
433 3           fe_mul(t2, t3, t2);
434 3           fe_sq(t2, t2);
435              
436 150 100         for (i = 1; i < 50; ++i) {
437 147           fe_sq(t2, t2);
438             }
439              
440 3           fe_mul(t1, t2, t1);
441 3           fe_sq(t1, t1);
442              
443 15 100         for (i = 1; i < 5; ++i) {
444 12           fe_sq(t1, t1);
445             }
446              
447 3           fe_mul(out, t1, t0);
448 3           }
449              
450              
451              
452             /*
453             return 1 if f is in {1,3,5,...,q-2}
454             return 0 if f is in {0,2,4,...,q-1}
455              
456             Preconditions:
457             |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
458             */
459              
460 4           int fe_isnegative(const fe f) {
461             unsigned char s[32];
462              
463 4           fe_tobytes(s, f);
464            
465 4           return s[0] & 1;
466             }
467              
468              
469              
470             /*
471             return 1 if f == 0
472             return 0 if f != 0
473              
474             Preconditions:
475             |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
476             */
477              
478 1           int fe_isnonzero(const fe f) {
479             unsigned char s[32];
480             unsigned char r;
481              
482 1           fe_tobytes(s, f);
483              
484 1           r = s[0];
485             #define F(i) r |= s[i]
486 1           F(1);
487 1           F(2);
488 1           F(3);
489 1           F(4);
490 1           F(5);
491 1           F(6);
492 1           F(7);
493 1           F(8);
494 1           F(9);
495 1           F(10);
496 1           F(11);
497 1           F(12);
498 1           F(13);
499 1           F(14);
500 1           F(15);
501 1           F(16);
502 1           F(17);
503 1           F(18);
504 1           F(19);
505 1           F(20);
506 1           F(21);
507 1           F(22);
508 1           F(23);
509 1           F(24);
510 1           F(25);
511 1           F(26);
512 1           F(27);
513 1           F(28);
514 1           F(29);
515 1           F(30);
516 1           F(31);
517             #undef F
518              
519 1           return r != 0;
520             }
521              
522              
523              
524             /*
525             h = f * g
526             Can overlap h with f or g.
527              
528             Preconditions:
529             |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
530             |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
531              
532             Postconditions:
533             |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
534             */
535              
536             /*
537             Notes on implementation strategy:
538              
539             Using schoolbook multiplication.
540             Karatsuba would save a little in some cost models.
541              
542             Most multiplications by 2 and 19 are 32-bit precomputations;
543             cheaper than 64-bit postcomputations.
544              
545             There is one remaining multiplication by 19 in the carry chain;
546             one *19 precomputation can be merged into this,
547             but the resulting data flow is considerably less clean.
548              
549             There are 12 carries below.
550             10 of them are 2-way parallelizable and vectorizable.
551             Can get away with 11 carries, but then data flow is much deeper.
552              
553             With tighter constraints on inputs can squeeze carries into int32.
554             */
555              
556 2430           void fe_mul(fe h, const fe f, const fe g) {
557 2430           int32_t f0 = f[0];
558 2430           int32_t f1 = f[1];
559 2430           int32_t f2 = f[2];
560 2430           int32_t f3 = f[3];
561 2430           int32_t f4 = f[4];
562 2430           int32_t f5 = f[5];
563 2430           int32_t f6 = f[6];
564 2430           int32_t f7 = f[7];
565 2430           int32_t f8 = f[8];
566 2430           int32_t f9 = f[9];
567 2430           int32_t g0 = g[0];
568 2430           int32_t g1 = g[1];
569 2430           int32_t g2 = g[2];
570 2430           int32_t g3 = g[3];
571 2430           int32_t g4 = g[4];
572 2430           int32_t g5 = g[5];
573 2430           int32_t g6 = g[6];
574 2430           int32_t g7 = g[7];
575 2430           int32_t g8 = g[8];
576 2430           int32_t g9 = g[9];
577 2430           int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
578 2430           int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
579 2430           int32_t g3_19 = 19 * g3;
580 2430           int32_t g4_19 = 19 * g4;
581 2430           int32_t g5_19 = 19 * g5;
582 2430           int32_t g6_19 = 19 * g6;
583 2430           int32_t g7_19 = 19 * g7;
584 2430           int32_t g8_19 = 19 * g8;
585 2430           int32_t g9_19 = 19 * g9;
586 2430           int32_t f1_2 = 2 * f1;
587 2430           int32_t f3_2 = 2 * f3;
588 2430           int32_t f5_2 = 2 * f5;
589 2430           int32_t f7_2 = 2 * f7;
590 2430           int32_t f9_2 = 2 * f9;
591 2430           int64_t f0g0 = f0 * (int64_t) g0;
592 2430           int64_t f0g1 = f0 * (int64_t) g1;
593 2430           int64_t f0g2 = f0 * (int64_t) g2;
594 2430           int64_t f0g3 = f0 * (int64_t) g3;
595 2430           int64_t f0g4 = f0 * (int64_t) g4;
596 2430           int64_t f0g5 = f0 * (int64_t) g5;
597 2430           int64_t f0g6 = f0 * (int64_t) g6;
598 2430           int64_t f0g7 = f0 * (int64_t) g7;
599 2430           int64_t f0g8 = f0 * (int64_t) g8;
600 2430           int64_t f0g9 = f0 * (int64_t) g9;
601 2430           int64_t f1g0 = f1 * (int64_t) g0;
602 2430           int64_t f1g1_2 = f1_2 * (int64_t) g1;
603 2430           int64_t f1g2 = f1 * (int64_t) g2;
604 2430           int64_t f1g3_2 = f1_2 * (int64_t) g3;
605 2430           int64_t f1g4 = f1 * (int64_t) g4;
606 2430           int64_t f1g5_2 = f1_2 * (int64_t) g5;
607 2430           int64_t f1g6 = f1 * (int64_t) g6;
608 2430           int64_t f1g7_2 = f1_2 * (int64_t) g7;
609 2430           int64_t f1g8 = f1 * (int64_t) g8;
610 2430           int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
611 2430           int64_t f2g0 = f2 * (int64_t) g0;
612 2430           int64_t f2g1 = f2 * (int64_t) g1;
613 2430           int64_t f2g2 = f2 * (int64_t) g2;
614 2430           int64_t f2g3 = f2 * (int64_t) g3;
615 2430           int64_t f2g4 = f2 * (int64_t) g4;
616 2430           int64_t f2g5 = f2 * (int64_t) g5;
617 2430           int64_t f2g6 = f2 * (int64_t) g6;
618 2430           int64_t f2g7 = f2 * (int64_t) g7;
619 2430           int64_t f2g8_19 = f2 * (int64_t) g8_19;
620 2430           int64_t f2g9_19 = f2 * (int64_t) g9_19;
621 2430           int64_t f3g0 = f3 * (int64_t) g0;
622 2430           int64_t f3g1_2 = f3_2 * (int64_t) g1;
623 2430           int64_t f3g2 = f3 * (int64_t) g2;
624 2430           int64_t f3g3_2 = f3_2 * (int64_t) g3;
625 2430           int64_t f3g4 = f3 * (int64_t) g4;
626 2430           int64_t f3g5_2 = f3_2 * (int64_t) g5;
627 2430           int64_t f3g6 = f3 * (int64_t) g6;
628 2430           int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
629 2430           int64_t f3g8_19 = f3 * (int64_t) g8_19;
630 2430           int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
631 2430           int64_t f4g0 = f4 * (int64_t) g0;
632 2430           int64_t f4g1 = f4 * (int64_t) g1;
633 2430           int64_t f4g2 = f4 * (int64_t) g2;
634 2430           int64_t f4g3 = f4 * (int64_t) g3;
635 2430           int64_t f4g4 = f4 * (int64_t) g4;
636 2430           int64_t f4g5 = f4 * (int64_t) g5;
637 2430           int64_t f4g6_19 = f4 * (int64_t) g6_19;
638 2430           int64_t f4g7_19 = f4 * (int64_t) g7_19;
639 2430           int64_t f4g8_19 = f4 * (int64_t) g8_19;
640 2430           int64_t f4g9_19 = f4 * (int64_t) g9_19;
641 2430           int64_t f5g0 = f5 * (int64_t) g0;
642 2430           int64_t f5g1_2 = f5_2 * (int64_t) g1;
643 2430           int64_t f5g2 = f5 * (int64_t) g2;
644 2430           int64_t f5g3_2 = f5_2 * (int64_t) g3;
645 2430           int64_t f5g4 = f5 * (int64_t) g4;
646 2430           int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
647 2430           int64_t f5g6_19 = f5 * (int64_t) g6_19;
648 2430           int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
649 2430           int64_t f5g8_19 = f5 * (int64_t) g8_19;
650 2430           int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
651 2430           int64_t f6g0 = f6 * (int64_t) g0;
652 2430           int64_t f6g1 = f6 * (int64_t) g1;
653 2430           int64_t f6g2 = f6 * (int64_t) g2;
654 2430           int64_t f6g3 = f6 * (int64_t) g3;
655 2430           int64_t f6g4_19 = f6 * (int64_t) g4_19;
656 2430           int64_t f6g5_19 = f6 * (int64_t) g5_19;
657 2430           int64_t f6g6_19 = f6 * (int64_t) g6_19;
658 2430           int64_t f6g7_19 = f6 * (int64_t) g7_19;
659 2430           int64_t f6g8_19 = f6 * (int64_t) g8_19;
660 2430           int64_t f6g9_19 = f6 * (int64_t) g9_19;
661 2430           int64_t f7g0 = f7 * (int64_t) g0;
662 2430           int64_t f7g1_2 = f7_2 * (int64_t) g1;
663 2430           int64_t f7g2 = f7 * (int64_t) g2;
664 2430           int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
665 2430           int64_t f7g4_19 = f7 * (int64_t) g4_19;
666 2430           int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
667 2430           int64_t f7g6_19 = f7 * (int64_t) g6_19;
668 2430           int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
669 2430           int64_t f7g8_19 = f7 * (int64_t) g8_19;
670 2430           int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
671 2430           int64_t f8g0 = f8 * (int64_t) g0;
672 2430           int64_t f8g1 = f8 * (int64_t) g1;
673 2430           int64_t f8g2_19 = f8 * (int64_t) g2_19;
674 2430           int64_t f8g3_19 = f8 * (int64_t) g3_19;
675 2430           int64_t f8g4_19 = f8 * (int64_t) g4_19;
676 2430           int64_t f8g5_19 = f8 * (int64_t) g5_19;
677 2430           int64_t f8g6_19 = f8 * (int64_t) g6_19;
678 2430           int64_t f8g7_19 = f8 * (int64_t) g7_19;
679 2430           int64_t f8g8_19 = f8 * (int64_t) g8_19;
680 2430           int64_t f8g9_19 = f8 * (int64_t) g9_19;
681 2430           int64_t f9g0 = f9 * (int64_t) g0;
682 2430           int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
683 2430           int64_t f9g2_19 = f9 * (int64_t) g2_19;
684 2430           int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
685 2430           int64_t f9g4_19 = f9 * (int64_t) g4_19;
686 2430           int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
687 2430           int64_t f9g6_19 = f9 * (int64_t) g6_19;
688 2430           int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
689 2430           int64_t f9g8_19 = f9 * (int64_t) g8_19;
690 2430           int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
691 2430           int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
692 2430           int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
693 2430           int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
694 2430           int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
695 2430           int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
696 2430           int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
697 2430           int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
698 2430           int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
699 2430           int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
700 2430           int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 ;
701             int64_t carry0;
702             int64_t carry1;
703             int64_t carry2;
704             int64_t carry3;
705             int64_t carry4;
706             int64_t carry5;
707             int64_t carry6;
708             int64_t carry7;
709             int64_t carry8;
710             int64_t carry9;
711              
712 2430           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
713 2430           h1 += carry0;
714 2430           h0 -= carry0 << 26;
715 2430           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
716 2430           h5 += carry4;
717 2430           h4 -= carry4 << 26;
718              
719 2430           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
720 2430           h2 += carry1;
721 2430           h1 -= carry1 << 25;
722 2430           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
723 2430           h6 += carry5;
724 2430           h5 -= carry5 << 25;
725              
726 2430           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
727 2430           h3 += carry2;
728 2430           h2 -= carry2 << 26;
729 2430           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
730 2430           h7 += carry6;
731 2430           h6 -= carry6 << 26;
732              
733 2430           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
734 2430           h4 += carry3;
735 2430           h3 -= carry3 << 25;
736 2430           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
737 2430           h8 += carry7;
738 2430           h7 -= carry7 << 25;
739              
740 2430           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
741 2430           h5 += carry4;
742 2430           h4 -= carry4 << 26;
743 2430           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
744 2430           h9 += carry8;
745 2430           h8 -= carry8 << 26;
746              
747 2430           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
748 2430           h0 += carry9 * 19;
749 2430           h9 -= carry9 << 25;
750              
751 2430           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
752 2430           h1 += carry0;
753 2430           h0 -= carry0 << 26;
754              
755 2430           h[0] = (int32_t) h0;
756 2430           h[1] = (int32_t) h1;
757 2430           h[2] = (int32_t) h2;
758 2430           h[3] = (int32_t) h3;
759 2430           h[4] = (int32_t) h4;
760 2430           h[5] = (int32_t) h5;
761 2430           h[6] = (int32_t) h6;
762 2430           h[7] = (int32_t) h7;
763 2430           h[8] = (int32_t) h8;
764 2430           h[9] = (int32_t) h9;
765 2430           }
766              
767              
768             /*
769             h = f * 121666
770             Can overlap h with f.
771              
772             Preconditions:
773             |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
774              
775             Postconditions:
776             |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
777             */
778              
779 0           void fe_mul121666(fe h, fe f) {
780 0           int32_t f0 = f[0];
781 0           int32_t f1 = f[1];
782 0           int32_t f2 = f[2];
783 0           int32_t f3 = f[3];
784 0           int32_t f4 = f[4];
785 0           int32_t f5 = f[5];
786 0           int32_t f6 = f[6];
787 0           int32_t f7 = f[7];
788 0           int32_t f8 = f[8];
789 0           int32_t f9 = f[9];
790 0           int64_t h0 = f0 * (int64_t) 121666;
791 0           int64_t h1 = f1 * (int64_t) 121666;
792 0           int64_t h2 = f2 * (int64_t) 121666;
793 0           int64_t h3 = f3 * (int64_t) 121666;
794 0           int64_t h4 = f4 * (int64_t) 121666;
795 0           int64_t h5 = f5 * (int64_t) 121666;
796 0           int64_t h6 = f6 * (int64_t) 121666;
797 0           int64_t h7 = f7 * (int64_t) 121666;
798 0           int64_t h8 = f8 * (int64_t) 121666;
799 0           int64_t h9 = f9 * (int64_t) 121666;
800             int64_t carry0;
801             int64_t carry1;
802             int64_t carry2;
803             int64_t carry3;
804             int64_t carry4;
805             int64_t carry5;
806             int64_t carry6;
807             int64_t carry7;
808             int64_t carry8;
809             int64_t carry9;
810              
811 0           carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
812 0           carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
813 0           carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
814 0           carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
815 0           carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
816              
817 0           carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
818 0           carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
819 0           carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
820 0           carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
821 0           carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
822              
823 0           h[0] = h0;
824 0           h[1] = h1;
825 0           h[2] = h2;
826 0           h[3] = h3;
827 0           h[4] = h4;
828 0           h[5] = h5;
829 0           h[6] = h6;
830 0           h[7] = h7;
831 0           h[8] = h8;
832 0           h[9] = h9;
833 0           }
834              
835              
836             /*
837             h = -f
838              
839             Preconditions:
840             |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
841              
842             Postconditions:
843             |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
844             */
845              
846 129           void fe_neg(fe h, const fe f) {
847 129           int32_t f0 = f[0];
848 129           int32_t f1 = f[1];
849 129           int32_t f2 = f[2];
850 129           int32_t f3 = f[3];
851 129           int32_t f4 = f[4];
852 129           int32_t f5 = f[5];
853 129           int32_t f6 = f[6];
854 129           int32_t f7 = f[7];
855 129           int32_t f8 = f[8];
856 129           int32_t f9 = f[9];
857 129           int32_t h0 = -f0;
858 129           int32_t h1 = -f1;
859 129           int32_t h2 = -f2;
860 129           int32_t h3 = -f3;
861 129           int32_t h4 = -f4;
862 129           int32_t h5 = -f5;
863 129           int32_t h6 = -f6;
864 129           int32_t h7 = -f7;
865 129           int32_t h8 = -f8;
866 129           int32_t h9 = -f9;
867              
868 129           h[0] = h0;
869 129           h[1] = h1;
870 129           h[2] = h2;
871 129           h[3] = h3;
872 129           h[4] = h4;
873 129           h[5] = h5;
874 129           h[6] = h6;
875 129           h[7] = h7;
876 129           h[8] = h8;
877 129           h[9] = h9;
878 129           }
879              
880              
881 1           void fe_pow22523(fe out, const fe z) {
882             fe t0;
883             fe t1;
884             fe t2;
885             int i;
886 1           fe_sq(t0, z);
887              
888 1 50         for (i = 1; i < 1; ++i) {
889 0           fe_sq(t0, t0);
890             }
891              
892 1           fe_sq(t1, t0);
893              
894 2 100         for (i = 1; i < 2; ++i) {
895 1           fe_sq(t1, t1);
896             }
897              
898 1           fe_mul(t1, z, t1);
899 1           fe_mul(t0, t0, t1);
900 1           fe_sq(t0, t0);
901              
902 1 50         for (i = 1; i < 1; ++i) {
903 0           fe_sq(t0, t0);
904             }
905              
906 1           fe_mul(t0, t1, t0);
907 1           fe_sq(t1, t0);
908              
909 5 100         for (i = 1; i < 5; ++i) {
910 4           fe_sq(t1, t1);
911             }
912              
913 1           fe_mul(t0, t1, t0);
914 1           fe_sq(t1, t0);
915              
916 10 100         for (i = 1; i < 10; ++i) {
917 9           fe_sq(t1, t1);
918             }
919              
920 1           fe_mul(t1, t1, t0);
921 1           fe_sq(t2, t1);
922              
923 20 100         for (i = 1; i < 20; ++i) {
924 19           fe_sq(t2, t2);
925             }
926              
927 1           fe_mul(t1, t2, t1);
928 1           fe_sq(t1, t1);
929              
930 10 100         for (i = 1; i < 10; ++i) {
931 9           fe_sq(t1, t1);
932             }
933              
934 1           fe_mul(t0, t1, t0);
935 1           fe_sq(t1, t0);
936              
937 50 100         for (i = 1; i < 50; ++i) {
938 49           fe_sq(t1, t1);
939             }
940              
941 1           fe_mul(t1, t1, t0);
942 1           fe_sq(t2, t1);
943              
944 100 100         for (i = 1; i < 100; ++i) {
945 99           fe_sq(t2, t2);
946             }
947              
948 1           fe_mul(t1, t2, t1);
949 1           fe_sq(t1, t1);
950              
951 50 100         for (i = 1; i < 50; ++i) {
952 49           fe_sq(t1, t1);
953             }
954              
955 1           fe_mul(t0, t1, t0);
956 1           fe_sq(t0, t0);
957              
958 2 100         for (i = 1; i < 2; ++i) {
959 1           fe_sq(t0, t0);
960             }
961              
962 1           fe_mul(out, t0, z);
963 1           return;
964             }
965              
966              
967             /*
968             h = f * f
969             Can overlap h with f.
970              
971             Preconditions:
972             |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
973              
974             Postconditions:
975             |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
976             */
977              
978             /*
979             See fe_mul.c for discussion of implementation strategy.
980             */
981              
982 1797           void fe_sq(fe h, const fe f) {
983 1797           int32_t f0 = f[0];
984 1797           int32_t f1 = f[1];
985 1797           int32_t f2 = f[2];
986 1797           int32_t f3 = f[3];
987 1797           int32_t f4 = f[4];
988 1797           int32_t f5 = f[5];
989 1797           int32_t f6 = f[6];
990 1797           int32_t f7 = f[7];
991 1797           int32_t f8 = f[8];
992 1797           int32_t f9 = f[9];
993 1797           int32_t f0_2 = 2 * f0;
994 1797           int32_t f1_2 = 2 * f1;
995 1797           int32_t f2_2 = 2 * f2;
996 1797           int32_t f3_2 = 2 * f3;
997 1797           int32_t f4_2 = 2 * f4;
998 1797           int32_t f5_2 = 2 * f5;
999 1797           int32_t f6_2 = 2 * f6;
1000 1797           int32_t f7_2 = 2 * f7;
1001 1797           int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
1002 1797           int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
1003 1797           int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
1004 1797           int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
1005 1797           int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
1006 1797           int64_t f0f0 = f0 * (int64_t) f0;
1007 1797           int64_t f0f1_2 = f0_2 * (int64_t) f1;
1008 1797           int64_t f0f2_2 = f0_2 * (int64_t) f2;
1009 1797           int64_t f0f3_2 = f0_2 * (int64_t) f3;
1010 1797           int64_t f0f4_2 = f0_2 * (int64_t) f4;
1011 1797           int64_t f0f5_2 = f0_2 * (int64_t) f5;
1012 1797           int64_t f0f6_2 = f0_2 * (int64_t) f6;
1013 1797           int64_t f0f7_2 = f0_2 * (int64_t) f7;
1014 1797           int64_t f0f8_2 = f0_2 * (int64_t) f8;
1015 1797           int64_t f0f9_2 = f0_2 * (int64_t) f9;
1016 1797           int64_t f1f1_2 = f1_2 * (int64_t) f1;
1017 1797           int64_t f1f2_2 = f1_2 * (int64_t) f2;
1018 1797           int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
1019 1797           int64_t f1f4_2 = f1_2 * (int64_t) f4;
1020 1797           int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
1021 1797           int64_t f1f6_2 = f1_2 * (int64_t) f6;
1022 1797           int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
1023 1797           int64_t f1f8_2 = f1_2 * (int64_t) f8;
1024 1797           int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
1025 1797           int64_t f2f2 = f2 * (int64_t) f2;
1026 1797           int64_t f2f3_2 = f2_2 * (int64_t) f3;
1027 1797           int64_t f2f4_2 = f2_2 * (int64_t) f4;
1028 1797           int64_t f2f5_2 = f2_2 * (int64_t) f5;
1029 1797           int64_t f2f6_2 = f2_2 * (int64_t) f6;
1030 1797           int64_t f2f7_2 = f2_2 * (int64_t) f7;
1031 1797           int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
1032 1797           int64_t f2f9_38 = f2 * (int64_t) f9_38;
1033 1797           int64_t f3f3_2 = f3_2 * (int64_t) f3;
1034 1797           int64_t f3f4_2 = f3_2 * (int64_t) f4;
1035 1797           int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
1036 1797           int64_t f3f6_2 = f3_2 * (int64_t) f6;
1037 1797           int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
1038 1797           int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
1039 1797           int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
1040 1797           int64_t f4f4 = f4 * (int64_t) f4;
1041 1797           int64_t f4f5_2 = f4_2 * (int64_t) f5;
1042 1797           int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
1043 1797           int64_t f4f7_38 = f4 * (int64_t) f7_38;
1044 1797           int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
1045 1797           int64_t f4f9_38 = f4 * (int64_t) f9_38;
1046 1797           int64_t f5f5_38 = f5 * (int64_t) f5_38;
1047 1797           int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
1048 1797           int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
1049 1797           int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
1050 1797           int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
1051 1797           int64_t f6f6_19 = f6 * (int64_t) f6_19;
1052 1797           int64_t f6f7_38 = f6 * (int64_t) f7_38;
1053 1797           int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
1054 1797           int64_t f6f9_38 = f6 * (int64_t) f9_38;
1055 1797           int64_t f7f7_38 = f7 * (int64_t) f7_38;
1056 1797           int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
1057 1797           int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
1058 1797           int64_t f8f8_19 = f8 * (int64_t) f8_19;
1059 1797           int64_t f8f9_38 = f8 * (int64_t) f9_38;
1060 1797           int64_t f9f9_38 = f9 * (int64_t) f9_38;
1061 1797           int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1062 1797           int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1063 1797           int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1064 1797           int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1065 1797           int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1066 1797           int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1067 1797           int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1068 1797           int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1069 1797           int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1070 1797           int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
1071             int64_t carry0;
1072             int64_t carry1;
1073             int64_t carry2;
1074             int64_t carry3;
1075             int64_t carry4;
1076             int64_t carry5;
1077             int64_t carry6;
1078             int64_t carry7;
1079             int64_t carry8;
1080             int64_t carry9;
1081 1797           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1082 1797           h1 += carry0;
1083 1797           h0 -= carry0 << 26;
1084 1797           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1085 1797           h5 += carry4;
1086 1797           h4 -= carry4 << 26;
1087 1797           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
1088 1797           h2 += carry1;
1089 1797           h1 -= carry1 << 25;
1090 1797           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
1091 1797           h6 += carry5;
1092 1797           h5 -= carry5 << 25;
1093 1797           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
1094 1797           h3 += carry2;
1095 1797           h2 -= carry2 << 26;
1096 1797           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
1097 1797           h7 += carry6;
1098 1797           h6 -= carry6 << 26;
1099 1797           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
1100 1797           h4 += carry3;
1101 1797           h3 -= carry3 << 25;
1102 1797           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
1103 1797           h8 += carry7;
1104 1797           h7 -= carry7 << 25;
1105 1797           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1106 1797           h5 += carry4;
1107 1797           h4 -= carry4 << 26;
1108 1797           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
1109 1797           h9 += carry8;
1110 1797           h8 -= carry8 << 26;
1111 1797           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
1112 1797           h0 += carry9 * 19;
1113 1797           h9 -= carry9 << 25;
1114 1797           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1115 1797           h1 += carry0;
1116 1797           h0 -= carry0 << 26;
1117 1797           h[0] = (int32_t) h0;
1118 1797           h[1] = (int32_t) h1;
1119 1797           h[2] = (int32_t) h2;
1120 1797           h[3] = (int32_t) h3;
1121 1797           h[4] = (int32_t) h4;
1122 1797           h[5] = (int32_t) h5;
1123 1797           h[6] = (int32_t) h6;
1124 1797           h[7] = (int32_t) h7;
1125 1797           h[8] = (int32_t) h8;
1126 1797           h[9] = (int32_t) h9;
1127 1797           }
1128              
1129              
1130             /*
1131             h = 2 * f * f
1132             Can overlap h with f.
1133              
1134             Preconditions:
1135             |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
1136              
1137             Postconditions:
1138             |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
1139             */
1140              
1141             /*
1142             See fe_mul.c for discussion of implementation strategy.
1143             */
1144              
1145 260           void fe_sq2(fe h, const fe f) {
1146 260           int32_t f0 = f[0];
1147 260           int32_t f1 = f[1];
1148 260           int32_t f2 = f[2];
1149 260           int32_t f3 = f[3];
1150 260           int32_t f4 = f[4];
1151 260           int32_t f5 = f[5];
1152 260           int32_t f6 = f[6];
1153 260           int32_t f7 = f[7];
1154 260           int32_t f8 = f[8];
1155 260           int32_t f9 = f[9];
1156 260           int32_t f0_2 = 2 * f0;
1157 260           int32_t f1_2 = 2 * f1;
1158 260           int32_t f2_2 = 2 * f2;
1159 260           int32_t f3_2 = 2 * f3;
1160 260           int32_t f4_2 = 2 * f4;
1161 260           int32_t f5_2 = 2 * f5;
1162 260           int32_t f6_2 = 2 * f6;
1163 260           int32_t f7_2 = 2 * f7;
1164 260           int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
1165 260           int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
1166 260           int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
1167 260           int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
1168 260           int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
1169 260           int64_t f0f0 = f0 * (int64_t) f0;
1170 260           int64_t f0f1_2 = f0_2 * (int64_t) f1;
1171 260           int64_t f0f2_2 = f0_2 * (int64_t) f2;
1172 260           int64_t f0f3_2 = f0_2 * (int64_t) f3;
1173 260           int64_t f0f4_2 = f0_2 * (int64_t) f4;
1174 260           int64_t f0f5_2 = f0_2 * (int64_t) f5;
1175 260           int64_t f0f6_2 = f0_2 * (int64_t) f6;
1176 260           int64_t f0f7_2 = f0_2 * (int64_t) f7;
1177 260           int64_t f0f8_2 = f0_2 * (int64_t) f8;
1178 260           int64_t f0f9_2 = f0_2 * (int64_t) f9;
1179 260           int64_t f1f1_2 = f1_2 * (int64_t) f1;
1180 260           int64_t f1f2_2 = f1_2 * (int64_t) f2;
1181 260           int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
1182 260           int64_t f1f4_2 = f1_2 * (int64_t) f4;
1183 260           int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
1184 260           int64_t f1f6_2 = f1_2 * (int64_t) f6;
1185 260           int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
1186 260           int64_t f1f8_2 = f1_2 * (int64_t) f8;
1187 260           int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
1188 260           int64_t f2f2 = f2 * (int64_t) f2;
1189 260           int64_t f2f3_2 = f2_2 * (int64_t) f3;
1190 260           int64_t f2f4_2 = f2_2 * (int64_t) f4;
1191 260           int64_t f2f5_2 = f2_2 * (int64_t) f5;
1192 260           int64_t f2f6_2 = f2_2 * (int64_t) f6;
1193 260           int64_t f2f7_2 = f2_2 * (int64_t) f7;
1194 260           int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
1195 260           int64_t f2f9_38 = f2 * (int64_t) f9_38;
1196 260           int64_t f3f3_2 = f3_2 * (int64_t) f3;
1197 260           int64_t f3f4_2 = f3_2 * (int64_t) f4;
1198 260           int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
1199 260           int64_t f3f6_2 = f3_2 * (int64_t) f6;
1200 260           int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
1201 260           int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
1202 260           int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
1203 260           int64_t f4f4 = f4 * (int64_t) f4;
1204 260           int64_t f4f5_2 = f4_2 * (int64_t) f5;
1205 260           int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
1206 260           int64_t f4f7_38 = f4 * (int64_t) f7_38;
1207 260           int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
1208 260           int64_t f4f9_38 = f4 * (int64_t) f9_38;
1209 260           int64_t f5f5_38 = f5 * (int64_t) f5_38;
1210 260           int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
1211 260           int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
1212 260           int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
1213 260           int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
1214 260           int64_t f6f6_19 = f6 * (int64_t) f6_19;
1215 260           int64_t f6f7_38 = f6 * (int64_t) f7_38;
1216 260           int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
1217 260           int64_t f6f9_38 = f6 * (int64_t) f9_38;
1218 260           int64_t f7f7_38 = f7 * (int64_t) f7_38;
1219 260           int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
1220 260           int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
1221 260           int64_t f8f8_19 = f8 * (int64_t) f8_19;
1222 260           int64_t f8f9_38 = f8 * (int64_t) f9_38;
1223 260           int64_t f9f9_38 = f9 * (int64_t) f9_38;
1224 260           int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1225 260           int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1226 260           int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1227 260           int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1228 260           int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1229 260           int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1230 260           int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1231 260           int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1232 260           int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1233 260           int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2;
1234             int64_t carry0;
1235             int64_t carry1;
1236             int64_t carry2;
1237             int64_t carry3;
1238             int64_t carry4;
1239             int64_t carry5;
1240             int64_t carry6;
1241             int64_t carry7;
1242             int64_t carry8;
1243             int64_t carry9;
1244 260           h0 += h0;
1245 260           h1 += h1;
1246 260           h2 += h2;
1247 260           h3 += h3;
1248 260           h4 += h4;
1249 260           h5 += h5;
1250 260           h6 += h6;
1251 260           h7 += h7;
1252 260           h8 += h8;
1253 260           h9 += h9;
1254 260           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1255 260           h1 += carry0;
1256 260           h0 -= carry0 << 26;
1257 260           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1258 260           h5 += carry4;
1259 260           h4 -= carry4 << 26;
1260 260           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
1261 260           h2 += carry1;
1262 260           h1 -= carry1 << 25;
1263 260           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
1264 260           h6 += carry5;
1265 260           h5 -= carry5 << 25;
1266 260           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
1267 260           h3 += carry2;
1268 260           h2 -= carry2 << 26;
1269 260           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
1270 260           h7 += carry6;
1271 260           h6 -= carry6 << 26;
1272 260           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
1273 260           h4 += carry3;
1274 260           h3 -= carry3 << 25;
1275 260           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
1276 260           h8 += carry7;
1277 260           h7 -= carry7 << 25;
1278 260           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1279 260           h5 += carry4;
1280 260           h4 -= carry4 << 26;
1281 260           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
1282 260           h9 += carry8;
1283 260           h8 -= carry8 << 26;
1284 260           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
1285 260           h0 += carry9 * 19;
1286 260           h9 -= carry9 << 25;
1287 260           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1288 260           h1 += carry0;
1289 260           h0 -= carry0 << 26;
1290 260           h[0] = (int32_t) h0;
1291 260           h[1] = (int32_t) h1;
1292 260           h[2] = (int32_t) h2;
1293 260           h[3] = (int32_t) h3;
1294 260           h[4] = (int32_t) h4;
1295 260           h[5] = (int32_t) h5;
1296 260           h[6] = (int32_t) h6;
1297 260           h[7] = (int32_t) h7;
1298 260           h[8] = (int32_t) h8;
1299 260           h[9] = (int32_t) h9;
1300 260           }
1301              
1302              
1303             /*
1304             h = f - g
1305             Can overlap h with f or g.
1306              
1307             Preconditions:
1308             |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
1309             |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
1310              
1311             Postconditions:
1312             |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
1313             */
1314              
1315 1447           void fe_sub(fe h, const fe f, const fe g) {
1316 1447           int32_t f0 = f[0];
1317 1447           int32_t f1 = f[1];
1318 1447           int32_t f2 = f[2];
1319 1447           int32_t f3 = f[3];
1320 1447           int32_t f4 = f[4];
1321 1447           int32_t f5 = f[5];
1322 1447           int32_t f6 = f[6];
1323 1447           int32_t f7 = f[7];
1324 1447           int32_t f8 = f[8];
1325 1447           int32_t f9 = f[9];
1326 1447           int32_t g0 = g[0];
1327 1447           int32_t g1 = g[1];
1328 1447           int32_t g2 = g[2];
1329 1447           int32_t g3 = g[3];
1330 1447           int32_t g4 = g[4];
1331 1447           int32_t g5 = g[5];
1332 1447           int32_t g6 = g[6];
1333 1447           int32_t g7 = g[7];
1334 1447           int32_t g8 = g[8];
1335 1447           int32_t g9 = g[9];
1336 1447           int32_t h0 = f0 - g0;
1337 1447           int32_t h1 = f1 - g1;
1338 1447           int32_t h2 = f2 - g2;
1339 1447           int32_t h3 = f3 - g3;
1340 1447           int32_t h4 = f4 - g4;
1341 1447           int32_t h5 = f5 - g5;
1342 1447           int32_t h6 = f6 - g6;
1343 1447           int32_t h7 = f7 - g7;
1344 1447           int32_t h8 = f8 - g8;
1345 1447           int32_t h9 = f9 - g9;
1346              
1347 1447           h[0] = h0;
1348 1447           h[1] = h1;
1349 1447           h[2] = h2;
1350 1447           h[3] = h3;
1351 1447           h[4] = h4;
1352 1447           h[5] = h5;
1353 1447           h[6] = h6;
1354 1447           h[7] = h7;
1355 1447           h[8] = h8;
1356 1447           h[9] = h9;
1357 1447           }
1358              
1359              
1360              
1361             /*
1362             Preconditions:
1363             |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
1364              
1365             Write p=2^255-19; q=floor(h/p).
1366             Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
1367              
1368             Proof:
1369             Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
1370             Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
1371              
1372             Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
1373             Then 0
1374              
1375             Write r=h-pq.
1376             Have 0<=r<=p-1=2^255-20.
1377             Thus 0<=r+19(2^-255)r
1378              
1379             Write x=r+19(2^-255)r+y.
1380             Then 0
1381              
1382             Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
1383             so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
1384             */
1385              
1386 8           void fe_tobytes(unsigned char *s, const fe h) {
1387 8           int32_t h0 = h[0];
1388 8           int32_t h1 = h[1];
1389 8           int32_t h2 = h[2];
1390 8           int32_t h3 = h[3];
1391 8           int32_t h4 = h[4];
1392 8           int32_t h5 = h[5];
1393 8           int32_t h6 = h[6];
1394 8           int32_t h7 = h[7];
1395 8           int32_t h8 = h[8];
1396 8           int32_t h9 = h[9];
1397             int32_t q;
1398             int32_t carry0;
1399             int32_t carry1;
1400             int32_t carry2;
1401             int32_t carry3;
1402             int32_t carry4;
1403             int32_t carry5;
1404             int32_t carry6;
1405             int32_t carry7;
1406             int32_t carry8;
1407             int32_t carry9;
1408 8           q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
1409 8           q = (h0 + q) >> 26;
1410 8           q = (h1 + q) >> 25;
1411 8           q = (h2 + q) >> 26;
1412 8           q = (h3 + q) >> 25;
1413 8           q = (h4 + q) >> 26;
1414 8           q = (h5 + q) >> 25;
1415 8           q = (h6 + q) >> 26;
1416 8           q = (h7 + q) >> 25;
1417 8           q = (h8 + q) >> 26;
1418 8           q = (h9 + q) >> 25;
1419             /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
1420 8           h0 += 19 * q;
1421             /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
1422 8           carry0 = h0 >> 26;
1423 8           h1 += carry0;
1424 8           h0 -= carry0 << 26;
1425 8           carry1 = h1 >> 25;
1426 8           h2 += carry1;
1427 8           h1 -= carry1 << 25;
1428 8           carry2 = h2 >> 26;
1429 8           h3 += carry2;
1430 8           h2 -= carry2 << 26;
1431 8           carry3 = h3 >> 25;
1432 8           h4 += carry3;
1433 8           h3 -= carry3 << 25;
1434 8           carry4 = h4 >> 26;
1435 8           h5 += carry4;
1436 8           h4 -= carry4 << 26;
1437 8           carry5 = h5 >> 25;
1438 8           h6 += carry5;
1439 8           h5 -= carry5 << 25;
1440 8           carry6 = h6 >> 26;
1441 8           h7 += carry6;
1442 8           h6 -= carry6 << 26;
1443 8           carry7 = h7 >> 25;
1444 8           h8 += carry7;
1445 8           h7 -= carry7 << 25;
1446 8           carry8 = h8 >> 26;
1447 8           h9 += carry8;
1448 8           h8 -= carry8 << 26;
1449 8           carry9 = h9 >> 25;
1450 8           h9 -= carry9 << 25;
1451              
1452             /* h10 = carry9 */
1453             /*
1454             Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
1455             Have h0+...+2^230 h9 between 0 and 2^255-1;
1456             evidently 2^255 h10-2^255 q = 0.
1457             Goal: Output h0+...+2^230 h9.
1458             */
1459 8           s[0] = (unsigned char) (h0 >> 0);
1460 8           s[1] = (unsigned char) (h0 >> 8);
1461 8           s[2] = (unsigned char) (h0 >> 16);
1462 8           s[3] = (unsigned char) ((h0 >> 24) | (h1 << 2));
1463 8           s[4] = (unsigned char) (h1 >> 6);
1464 8           s[5] = (unsigned char) (h1 >> 14);
1465 8           s[6] = (unsigned char) ((h1 >> 22) | (h2 << 3));
1466 8           s[7] = (unsigned char) (h2 >> 5);
1467 8           s[8] = (unsigned char) (h2 >> 13);
1468 8           s[9] = (unsigned char) ((h2 >> 21) | (h3 << 5));
1469 8           s[10] = (unsigned char) (h3 >> 3);
1470 8           s[11] = (unsigned char) (h3 >> 11);
1471 8           s[12] = (unsigned char) ((h3 >> 19) | (h4 << 6));
1472 8           s[13] = (unsigned char) (h4 >> 2);
1473 8           s[14] = (unsigned char) (h4 >> 10);
1474 8           s[15] = (unsigned char) (h4 >> 18);
1475 8           s[16] = (unsigned char) (h5 >> 0);
1476 8           s[17] = (unsigned char) (h5 >> 8);
1477 8           s[18] = (unsigned char) (h5 >> 16);
1478 8           s[19] = (unsigned char) ((h5 >> 24) | (h6 << 1));
1479 8           s[20] = (unsigned char) (h6 >> 7);
1480 8           s[21] = (unsigned char) (h6 >> 15);
1481 8           s[22] = (unsigned char) ((h6 >> 23) | (h7 << 3));
1482 8           s[23] = (unsigned char) (h7 >> 5);
1483 8           s[24] = (unsigned char) (h7 >> 13);
1484 8           s[25] = (unsigned char) ((h7 >> 21) | (h8 << 4));
1485 8           s[26] = (unsigned char) (h8 >> 4);
1486 8           s[27] = (unsigned char) (h8 >> 12);
1487 8           s[28] = (unsigned char) ((h8 >> 20) | (h9 << 6));
1488 8           s[29] = (unsigned char) (h9 >> 2);
1489 8           s[30] = (unsigned char) (h9 >> 10);
1490 8           s[31] = (unsigned char) (h9 >> 18);
1491 8           }