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 1414           void fe_add(fe h, const fe f, const fe g) {
82 1414           int32_t f0 = f[0];
83 1414           int32_t f1 = f[1];
84 1414           int32_t f2 = f[2];
85 1414           int32_t f3 = f[3];
86 1414           int32_t f4 = f[4];
87 1414           int32_t f5 = f[5];
88 1414           int32_t f6 = f[6];
89 1414           int32_t f7 = f[7];
90 1414           int32_t f8 = f[8];
91 1414           int32_t f9 = f[9];
92 1414           int32_t g0 = g[0];
93 1414           int32_t g1 = g[1];
94 1414           int32_t g2 = g[2];
95 1414           int32_t g3 = g[3];
96 1414           int32_t g4 = g[4];
97 1414           int32_t g5 = g[5];
98 1414           int32_t g6 = g[6];
99 1414           int32_t g7 = g[7];
100 1414           int32_t g8 = g[8];
101 1414           int32_t g9 = g[9];
102 1414           int32_t h0 = f0 + g0;
103 1414           int32_t h1 = f1 + g1;
104 1414           int32_t h2 = f2 + g2;
105 1414           int32_t h3 = f3 + g3;
106 1414           int32_t h4 = f4 + g4;
107 1414           int32_t h5 = f5 + g5;
108 1414           int32_t h6 = f6 + g6;
109 1414           int32_t h7 = f7 + g7;
110 1414           int32_t h8 = f8 + g8;
111 1414           int32_t h9 = f9 + g9;
112            
113 1414           h[0] = h0;
114 1414           h[1] = h1;
115 1414           h[2] = h2;
116 1414           h[3] = h3;
117 1414           h[4] = h4;
118 1414           h[5] = h5;
119 1414           h[6] = h6;
120 1414           h[7] = h7;
121 1414           h[8] = h8;
122 1414           h[9] = h9;
123 1414           }
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 2           int fe_isnonzero(const fe f) {
479             unsigned char s[32];
480             unsigned char r;
481              
482 2           fe_tobytes(s, f);
483              
484 2           r = s[0];
485             #define F(i) r |= s[i]
486 2           F(1);
487 2           F(2);
488 2           F(3);
489 2           F(4);
490 2           F(5);
491 2           F(6);
492 2           F(7);
493 2           F(8);
494 2           F(9);
495 2           F(10);
496 2           F(11);
497 2           F(12);
498 2           F(13);
499 2           F(14);
500 2           F(15);
501 2           F(16);
502 2           F(17);
503 2           F(18);
504 2           F(19);
505 2           F(20);
506 2           F(21);
507 2           F(22);
508 2           F(23);
509 2           F(24);
510 2           F(25);
511 2           F(26);
512 2           F(27);
513 2           F(28);
514 2           F(29);
515 2           F(30);
516 2           F(31);
517             #undef F
518              
519 2           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 2445           void fe_mul(fe h, const fe f, const fe g) {
557 2445           int32_t f0 = f[0];
558 2445           int32_t f1 = f[1];
559 2445           int32_t f2 = f[2];
560 2445           int32_t f3 = f[3];
561 2445           int32_t f4 = f[4];
562 2445           int32_t f5 = f[5];
563 2445           int32_t f6 = f[6];
564 2445           int32_t f7 = f[7];
565 2445           int32_t f8 = f[8];
566 2445           int32_t f9 = f[9];
567 2445           int32_t g0 = g[0];
568 2445           int32_t g1 = g[1];
569 2445           int32_t g2 = g[2];
570 2445           int32_t g3 = g[3];
571 2445           int32_t g4 = g[4];
572 2445           int32_t g5 = g[5];
573 2445           int32_t g6 = g[6];
574 2445           int32_t g7 = g[7];
575 2445           int32_t g8 = g[8];
576 2445           int32_t g9 = g[9];
577 2445           int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
578 2445           int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
579 2445           int32_t g3_19 = 19 * g3;
580 2445           int32_t g4_19 = 19 * g4;
581 2445           int32_t g5_19 = 19 * g5;
582 2445           int32_t g6_19 = 19 * g6;
583 2445           int32_t g7_19 = 19 * g7;
584 2445           int32_t g8_19 = 19 * g8;
585 2445           int32_t g9_19 = 19 * g9;
586 2445           int32_t f1_2 = 2 * f1;
587 2445           int32_t f3_2 = 2 * f3;
588 2445           int32_t f5_2 = 2 * f5;
589 2445           int32_t f7_2 = 2 * f7;
590 2445           int32_t f9_2 = 2 * f9;
591 2445           int64_t f0g0 = f0 * (int64_t) g0;
592 2445           int64_t f0g1 = f0 * (int64_t) g1;
593 2445           int64_t f0g2 = f0 * (int64_t) g2;
594 2445           int64_t f0g3 = f0 * (int64_t) g3;
595 2445           int64_t f0g4 = f0 * (int64_t) g4;
596 2445           int64_t f0g5 = f0 * (int64_t) g5;
597 2445           int64_t f0g6 = f0 * (int64_t) g6;
598 2445           int64_t f0g7 = f0 * (int64_t) g7;
599 2445           int64_t f0g8 = f0 * (int64_t) g8;
600 2445           int64_t f0g9 = f0 * (int64_t) g9;
601 2445           int64_t f1g0 = f1 * (int64_t) g0;
602 2445           int64_t f1g1_2 = f1_2 * (int64_t) g1;
603 2445           int64_t f1g2 = f1 * (int64_t) g2;
604 2445           int64_t f1g3_2 = f1_2 * (int64_t) g3;
605 2445           int64_t f1g4 = f1 * (int64_t) g4;
606 2445           int64_t f1g5_2 = f1_2 * (int64_t) g5;
607 2445           int64_t f1g6 = f1 * (int64_t) g6;
608 2445           int64_t f1g7_2 = f1_2 * (int64_t) g7;
609 2445           int64_t f1g8 = f1 * (int64_t) g8;
610 2445           int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
611 2445           int64_t f2g0 = f2 * (int64_t) g0;
612 2445           int64_t f2g1 = f2 * (int64_t) g1;
613 2445           int64_t f2g2 = f2 * (int64_t) g2;
614 2445           int64_t f2g3 = f2 * (int64_t) g3;
615 2445           int64_t f2g4 = f2 * (int64_t) g4;
616 2445           int64_t f2g5 = f2 * (int64_t) g5;
617 2445           int64_t f2g6 = f2 * (int64_t) g6;
618 2445           int64_t f2g7 = f2 * (int64_t) g7;
619 2445           int64_t f2g8_19 = f2 * (int64_t) g8_19;
620 2445           int64_t f2g9_19 = f2 * (int64_t) g9_19;
621 2445           int64_t f3g0 = f3 * (int64_t) g0;
622 2445           int64_t f3g1_2 = f3_2 * (int64_t) g1;
623 2445           int64_t f3g2 = f3 * (int64_t) g2;
624 2445           int64_t f3g3_2 = f3_2 * (int64_t) g3;
625 2445           int64_t f3g4 = f3 * (int64_t) g4;
626 2445           int64_t f3g5_2 = f3_2 * (int64_t) g5;
627 2445           int64_t f3g6 = f3 * (int64_t) g6;
628 2445           int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
629 2445           int64_t f3g8_19 = f3 * (int64_t) g8_19;
630 2445           int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
631 2445           int64_t f4g0 = f4 * (int64_t) g0;
632 2445           int64_t f4g1 = f4 * (int64_t) g1;
633 2445           int64_t f4g2 = f4 * (int64_t) g2;
634 2445           int64_t f4g3 = f4 * (int64_t) g3;
635 2445           int64_t f4g4 = f4 * (int64_t) g4;
636 2445           int64_t f4g5 = f4 * (int64_t) g5;
637 2445           int64_t f4g6_19 = f4 * (int64_t) g6_19;
638 2445           int64_t f4g7_19 = f4 * (int64_t) g7_19;
639 2445           int64_t f4g8_19 = f4 * (int64_t) g8_19;
640 2445           int64_t f4g9_19 = f4 * (int64_t) g9_19;
641 2445           int64_t f5g0 = f5 * (int64_t) g0;
642 2445           int64_t f5g1_2 = f5_2 * (int64_t) g1;
643 2445           int64_t f5g2 = f5 * (int64_t) g2;
644 2445           int64_t f5g3_2 = f5_2 * (int64_t) g3;
645 2445           int64_t f5g4 = f5 * (int64_t) g4;
646 2445           int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
647 2445           int64_t f5g6_19 = f5 * (int64_t) g6_19;
648 2445           int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
649 2445           int64_t f5g8_19 = f5 * (int64_t) g8_19;
650 2445           int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
651 2445           int64_t f6g0 = f6 * (int64_t) g0;
652 2445           int64_t f6g1 = f6 * (int64_t) g1;
653 2445           int64_t f6g2 = f6 * (int64_t) g2;
654 2445           int64_t f6g3 = f6 * (int64_t) g3;
655 2445           int64_t f6g4_19 = f6 * (int64_t) g4_19;
656 2445           int64_t f6g5_19 = f6 * (int64_t) g5_19;
657 2445           int64_t f6g6_19 = f6 * (int64_t) g6_19;
658 2445           int64_t f6g7_19 = f6 * (int64_t) g7_19;
659 2445           int64_t f6g8_19 = f6 * (int64_t) g8_19;
660 2445           int64_t f6g9_19 = f6 * (int64_t) g9_19;
661 2445           int64_t f7g0 = f7 * (int64_t) g0;
662 2445           int64_t f7g1_2 = f7_2 * (int64_t) g1;
663 2445           int64_t f7g2 = f7 * (int64_t) g2;
664 2445           int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
665 2445           int64_t f7g4_19 = f7 * (int64_t) g4_19;
666 2445           int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
667 2445           int64_t f7g6_19 = f7 * (int64_t) g6_19;
668 2445           int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
669 2445           int64_t f7g8_19 = f7 * (int64_t) g8_19;
670 2445           int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
671 2445           int64_t f8g0 = f8 * (int64_t) g0;
672 2445           int64_t f8g1 = f8 * (int64_t) g1;
673 2445           int64_t f8g2_19 = f8 * (int64_t) g2_19;
674 2445           int64_t f8g3_19 = f8 * (int64_t) g3_19;
675 2445           int64_t f8g4_19 = f8 * (int64_t) g4_19;
676 2445           int64_t f8g5_19 = f8 * (int64_t) g5_19;
677 2445           int64_t f8g6_19 = f8 * (int64_t) g6_19;
678 2445           int64_t f8g7_19 = f8 * (int64_t) g7_19;
679 2445           int64_t f8g8_19 = f8 * (int64_t) g8_19;
680 2445           int64_t f8g9_19 = f8 * (int64_t) g9_19;
681 2445           int64_t f9g0 = f9 * (int64_t) g0;
682 2445           int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
683 2445           int64_t f9g2_19 = f9 * (int64_t) g2_19;
684 2445           int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
685 2445           int64_t f9g4_19 = f9 * (int64_t) g4_19;
686 2445           int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
687 2445           int64_t f9g6_19 = f9 * (int64_t) g6_19;
688 2445           int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
689 2445           int64_t f9g8_19 = f9 * (int64_t) g8_19;
690 2445           int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
691 2445           int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
692 2445           int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
693 2445           int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
694 2445           int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
695 2445           int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
696 2445           int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
697 2445           int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
698 2445           int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
699 2445           int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
700 2445           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 2445           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
713 2445           h1 += carry0;
714 2445           h0 -= carry0 << 26;
715 2445           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
716 2445           h5 += carry4;
717 2445           h4 -= carry4 << 26;
718              
719 2445           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
720 2445           h2 += carry1;
721 2445           h1 -= carry1 << 25;
722 2445           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
723 2445           h6 += carry5;
724 2445           h5 -= carry5 << 25;
725              
726 2445           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
727 2445           h3 += carry2;
728 2445           h2 -= carry2 << 26;
729 2445           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
730 2445           h7 += carry6;
731 2445           h6 -= carry6 << 26;
732              
733 2445           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
734 2445           h4 += carry3;
735 2445           h3 -= carry3 << 25;
736 2445           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
737 2445           h8 += carry7;
738 2445           h7 -= carry7 << 25;
739              
740 2445           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
741 2445           h5 += carry4;
742 2445           h4 -= carry4 << 26;
743 2445           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
744 2445           h9 += carry8;
745 2445           h8 -= carry8 << 26;
746              
747 2445           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
748 2445           h0 += carry9 * 19;
749 2445           h9 -= carry9 << 25;
750              
751 2445           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
752 2445           h1 += carry0;
753 2445           h0 -= carry0 << 26;
754              
755 2445           h[0] = (int32_t) h0;
756 2445           h[1] = (int32_t) h1;
757 2445           h[2] = (int32_t) h2;
758 2445           h[3] = (int32_t) h3;
759 2445           h[4] = (int32_t) h4;
760 2445           h[5] = (int32_t) h5;
761 2445           h[6] = (int32_t) h6;
762 2445           h[7] = (int32_t) h7;
763 2445           h[8] = (int32_t) h8;
764 2445           h[9] = (int32_t) h9;
765 2445           }
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 128           void fe_neg(fe h, const fe f) {
847 128           int32_t f0 = f[0];
848 128           int32_t f1 = f[1];
849 128           int32_t f2 = f[2];
850 128           int32_t f3 = f[3];
851 128           int32_t f4 = f[4];
852 128           int32_t f5 = f[5];
853 128           int32_t f6 = f[6];
854 128           int32_t f7 = f[7];
855 128           int32_t f8 = f[8];
856 128           int32_t f9 = f[9];
857 128           int32_t h0 = -f0;
858 128           int32_t h1 = -f1;
859 128           int32_t h2 = -f2;
860 128           int32_t h3 = -f3;
861 128           int32_t h4 = -f4;
862 128           int32_t h5 = -f5;
863 128           int32_t h6 = -f6;
864 128           int32_t h7 = -f7;
865 128           int32_t h8 = -f8;
866 128           int32_t h9 = -f9;
867              
868 128           h[0] = h0;
869 128           h[1] = h1;
870 128           h[2] = h2;
871 128           h[3] = h3;
872 128           h[4] = h4;
873 128           h[5] = h5;
874 128           h[6] = h6;
875 128           h[7] = h7;
876 128           h[8] = h8;
877 128           h[9] = h9;
878 128           }
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 1803           void fe_sq(fe h, const fe f) {
983 1803           int32_t f0 = f[0];
984 1803           int32_t f1 = f[1];
985 1803           int32_t f2 = f[2];
986 1803           int32_t f3 = f[3];
987 1803           int32_t f4 = f[4];
988 1803           int32_t f5 = f[5];
989 1803           int32_t f6 = f[6];
990 1803           int32_t f7 = f[7];
991 1803           int32_t f8 = f[8];
992 1803           int32_t f9 = f[9];
993 1803           int32_t f0_2 = 2 * f0;
994 1803           int32_t f1_2 = 2 * f1;
995 1803           int32_t f2_2 = 2 * f2;
996 1803           int32_t f3_2 = 2 * f3;
997 1803           int32_t f4_2 = 2 * f4;
998 1803           int32_t f5_2 = 2 * f5;
999 1803           int32_t f6_2 = 2 * f6;
1000 1803           int32_t f7_2 = 2 * f7;
1001 1803           int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
1002 1803           int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
1003 1803           int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
1004 1803           int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
1005 1803           int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
1006 1803           int64_t f0f0 = f0 * (int64_t) f0;
1007 1803           int64_t f0f1_2 = f0_2 * (int64_t) f1;
1008 1803           int64_t f0f2_2 = f0_2 * (int64_t) f2;
1009 1803           int64_t f0f3_2 = f0_2 * (int64_t) f3;
1010 1803           int64_t f0f4_2 = f0_2 * (int64_t) f4;
1011 1803           int64_t f0f5_2 = f0_2 * (int64_t) f5;
1012 1803           int64_t f0f6_2 = f0_2 * (int64_t) f6;
1013 1803           int64_t f0f7_2 = f0_2 * (int64_t) f7;
1014 1803           int64_t f0f8_2 = f0_2 * (int64_t) f8;
1015 1803           int64_t f0f9_2 = f0_2 * (int64_t) f9;
1016 1803           int64_t f1f1_2 = f1_2 * (int64_t) f1;
1017 1803           int64_t f1f2_2 = f1_2 * (int64_t) f2;
1018 1803           int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
1019 1803           int64_t f1f4_2 = f1_2 * (int64_t) f4;
1020 1803           int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
1021 1803           int64_t f1f6_2 = f1_2 * (int64_t) f6;
1022 1803           int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
1023 1803           int64_t f1f8_2 = f1_2 * (int64_t) f8;
1024 1803           int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
1025 1803           int64_t f2f2 = f2 * (int64_t) f2;
1026 1803           int64_t f2f3_2 = f2_2 * (int64_t) f3;
1027 1803           int64_t f2f4_2 = f2_2 * (int64_t) f4;
1028 1803           int64_t f2f5_2 = f2_2 * (int64_t) f5;
1029 1803           int64_t f2f6_2 = f2_2 * (int64_t) f6;
1030 1803           int64_t f2f7_2 = f2_2 * (int64_t) f7;
1031 1803           int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
1032 1803           int64_t f2f9_38 = f2 * (int64_t) f9_38;
1033 1803           int64_t f3f3_2 = f3_2 * (int64_t) f3;
1034 1803           int64_t f3f4_2 = f3_2 * (int64_t) f4;
1035 1803           int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
1036 1803           int64_t f3f6_2 = f3_2 * (int64_t) f6;
1037 1803           int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
1038 1803           int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
1039 1803           int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
1040 1803           int64_t f4f4 = f4 * (int64_t) f4;
1041 1803           int64_t f4f5_2 = f4_2 * (int64_t) f5;
1042 1803           int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
1043 1803           int64_t f4f7_38 = f4 * (int64_t) f7_38;
1044 1803           int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
1045 1803           int64_t f4f9_38 = f4 * (int64_t) f9_38;
1046 1803           int64_t f5f5_38 = f5 * (int64_t) f5_38;
1047 1803           int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
1048 1803           int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
1049 1803           int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
1050 1803           int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
1051 1803           int64_t f6f6_19 = f6 * (int64_t) f6_19;
1052 1803           int64_t f6f7_38 = f6 * (int64_t) f7_38;
1053 1803           int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
1054 1803           int64_t f6f9_38 = f6 * (int64_t) f9_38;
1055 1803           int64_t f7f7_38 = f7 * (int64_t) f7_38;
1056 1803           int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
1057 1803           int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
1058 1803           int64_t f8f8_19 = f8 * (int64_t) f8_19;
1059 1803           int64_t f8f9_38 = f8 * (int64_t) f9_38;
1060 1803           int64_t f9f9_38 = f9 * (int64_t) f9_38;
1061 1803           int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1062 1803           int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1063 1803           int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1064 1803           int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1065 1803           int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1066 1803           int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1067 1803           int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1068 1803           int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1069 1803           int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1070 1803           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 1803           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1082 1803           h1 += carry0;
1083 1803           h0 -= carry0 << 26;
1084 1803           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1085 1803           h5 += carry4;
1086 1803           h4 -= carry4 << 26;
1087 1803           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
1088 1803           h2 += carry1;
1089 1803           h1 -= carry1 << 25;
1090 1803           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
1091 1803           h6 += carry5;
1092 1803           h5 -= carry5 << 25;
1093 1803           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
1094 1803           h3 += carry2;
1095 1803           h2 -= carry2 << 26;
1096 1803           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
1097 1803           h7 += carry6;
1098 1803           h6 -= carry6 << 26;
1099 1803           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
1100 1803           h4 += carry3;
1101 1803           h3 -= carry3 << 25;
1102 1803           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
1103 1803           h8 += carry7;
1104 1803           h7 -= carry7 << 25;
1105 1803           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1106 1803           h5 += carry4;
1107 1803           h4 -= carry4 << 26;
1108 1803           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
1109 1803           h9 += carry8;
1110 1803           h8 -= carry8 << 26;
1111 1803           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
1112 1803           h0 += carry9 * 19;
1113 1803           h9 -= carry9 << 25;
1114 1803           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1115 1803           h1 += carry0;
1116 1803           h0 -= carry0 << 26;
1117 1803           h[0] = (int32_t) h0;
1118 1803           h[1] = (int32_t) h1;
1119 1803           h[2] = (int32_t) h2;
1120 1803           h[3] = (int32_t) h3;
1121 1803           h[4] = (int32_t) h4;
1122 1803           h[5] = (int32_t) h5;
1123 1803           h[6] = (int32_t) h6;
1124 1803           h[7] = (int32_t) h7;
1125 1803           h[8] = (int32_t) h8;
1126 1803           h[9] = (int32_t) h9;
1127 1803           }
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 262           void fe_sq2(fe h, const fe f) {
1146 262           int32_t f0 = f[0];
1147 262           int32_t f1 = f[1];
1148 262           int32_t f2 = f[2];
1149 262           int32_t f3 = f[3];
1150 262           int32_t f4 = f[4];
1151 262           int32_t f5 = f[5];
1152 262           int32_t f6 = f[6];
1153 262           int32_t f7 = f[7];
1154 262           int32_t f8 = f[8];
1155 262           int32_t f9 = f[9];
1156 262           int32_t f0_2 = 2 * f0;
1157 262           int32_t f1_2 = 2 * f1;
1158 262           int32_t f2_2 = 2 * f2;
1159 262           int32_t f3_2 = 2 * f3;
1160 262           int32_t f4_2 = 2 * f4;
1161 262           int32_t f5_2 = 2 * f5;
1162 262           int32_t f6_2 = 2 * f6;
1163 262           int32_t f7_2 = 2 * f7;
1164 262           int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
1165 262           int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
1166 262           int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
1167 262           int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
1168 262           int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
1169 262           int64_t f0f0 = f0 * (int64_t) f0;
1170 262           int64_t f0f1_2 = f0_2 * (int64_t) f1;
1171 262           int64_t f0f2_2 = f0_2 * (int64_t) f2;
1172 262           int64_t f0f3_2 = f0_2 * (int64_t) f3;
1173 262           int64_t f0f4_2 = f0_2 * (int64_t) f4;
1174 262           int64_t f0f5_2 = f0_2 * (int64_t) f5;
1175 262           int64_t f0f6_2 = f0_2 * (int64_t) f6;
1176 262           int64_t f0f7_2 = f0_2 * (int64_t) f7;
1177 262           int64_t f0f8_2 = f0_2 * (int64_t) f8;
1178 262           int64_t f0f9_2 = f0_2 * (int64_t) f9;
1179 262           int64_t f1f1_2 = f1_2 * (int64_t) f1;
1180 262           int64_t f1f2_2 = f1_2 * (int64_t) f2;
1181 262           int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
1182 262           int64_t f1f4_2 = f1_2 * (int64_t) f4;
1183 262           int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
1184 262           int64_t f1f6_2 = f1_2 * (int64_t) f6;
1185 262           int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
1186 262           int64_t f1f8_2 = f1_2 * (int64_t) f8;
1187 262           int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
1188 262           int64_t f2f2 = f2 * (int64_t) f2;
1189 262           int64_t f2f3_2 = f2_2 * (int64_t) f3;
1190 262           int64_t f2f4_2 = f2_2 * (int64_t) f4;
1191 262           int64_t f2f5_2 = f2_2 * (int64_t) f5;
1192 262           int64_t f2f6_2 = f2_2 * (int64_t) f6;
1193 262           int64_t f2f7_2 = f2_2 * (int64_t) f7;
1194 262           int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
1195 262           int64_t f2f9_38 = f2 * (int64_t) f9_38;
1196 262           int64_t f3f3_2 = f3_2 * (int64_t) f3;
1197 262           int64_t f3f4_2 = f3_2 * (int64_t) f4;
1198 262           int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
1199 262           int64_t f3f6_2 = f3_2 * (int64_t) f6;
1200 262           int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
1201 262           int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
1202 262           int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
1203 262           int64_t f4f4 = f4 * (int64_t) f4;
1204 262           int64_t f4f5_2 = f4_2 * (int64_t) f5;
1205 262           int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
1206 262           int64_t f4f7_38 = f4 * (int64_t) f7_38;
1207 262           int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
1208 262           int64_t f4f9_38 = f4 * (int64_t) f9_38;
1209 262           int64_t f5f5_38 = f5 * (int64_t) f5_38;
1210 262           int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
1211 262           int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
1212 262           int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
1213 262           int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
1214 262           int64_t f6f6_19 = f6 * (int64_t) f6_19;
1215 262           int64_t f6f7_38 = f6 * (int64_t) f7_38;
1216 262           int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
1217 262           int64_t f6f9_38 = f6 * (int64_t) f9_38;
1218 262           int64_t f7f7_38 = f7 * (int64_t) f7_38;
1219 262           int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
1220 262           int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
1221 262           int64_t f8f8_19 = f8 * (int64_t) f8_19;
1222 262           int64_t f8f9_38 = f8 * (int64_t) f9_38;
1223 262           int64_t f9f9_38 = f9 * (int64_t) f9_38;
1224 262           int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1225 262           int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1226 262           int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1227 262           int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1228 262           int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1229 262           int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1230 262           int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1231 262           int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1232 262           int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1233 262           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 262           h0 += h0;
1245 262           h1 += h1;
1246 262           h2 += h2;
1247 262           h3 += h3;
1248 262           h4 += h4;
1249 262           h5 += h5;
1250 262           h6 += h6;
1251 262           h7 += h7;
1252 262           h8 += h8;
1253 262           h9 += h9;
1254 262           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1255 262           h1 += carry0;
1256 262           h0 -= carry0 << 26;
1257 262           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1258 262           h5 += carry4;
1259 262           h4 -= carry4 << 26;
1260 262           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
1261 262           h2 += carry1;
1262 262           h1 -= carry1 << 25;
1263 262           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
1264 262           h6 += carry5;
1265 262           h5 -= carry5 << 25;
1266 262           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
1267 262           h3 += carry2;
1268 262           h2 -= carry2 << 26;
1269 262           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
1270 262           h7 += carry6;
1271 262           h6 -= carry6 << 26;
1272 262           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
1273 262           h4 += carry3;
1274 262           h3 -= carry3 << 25;
1275 262           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
1276 262           h8 += carry7;
1277 262           h7 -= carry7 << 25;
1278 262           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1279 262           h5 += carry4;
1280 262           h4 -= carry4 << 26;
1281 262           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
1282 262           h9 += carry8;
1283 262           h8 -= carry8 << 26;
1284 262           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
1285 262           h0 += carry9 * 19;
1286 262           h9 -= carry9 << 25;
1287 262           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1288 262           h1 += carry0;
1289 262           h0 -= carry0 << 26;
1290 262           h[0] = (int32_t) h0;
1291 262           h[1] = (int32_t) h1;
1292 262           h[2] = (int32_t) h2;
1293 262           h[3] = (int32_t) h3;
1294 262           h[4] = (int32_t) h4;
1295 262           h[5] = (int32_t) h5;
1296 262           h[6] = (int32_t) h6;
1297 262           h[7] = (int32_t) h7;
1298 262           h[8] = (int32_t) h8;
1299 262           h[9] = (int32_t) h9;
1300 262           }
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 1456           void fe_sub(fe h, const fe f, const fe g) {
1316 1456           int32_t f0 = f[0];
1317 1456           int32_t f1 = f[1];
1318 1456           int32_t f2 = f[2];
1319 1456           int32_t f3 = f[3];
1320 1456           int32_t f4 = f[4];
1321 1456           int32_t f5 = f[5];
1322 1456           int32_t f6 = f[6];
1323 1456           int32_t f7 = f[7];
1324 1456           int32_t f8 = f[8];
1325 1456           int32_t f9 = f[9];
1326 1456           int32_t g0 = g[0];
1327 1456           int32_t g1 = g[1];
1328 1456           int32_t g2 = g[2];
1329 1456           int32_t g3 = g[3];
1330 1456           int32_t g4 = g[4];
1331 1456           int32_t g5 = g[5];
1332 1456           int32_t g6 = g[6];
1333 1456           int32_t g7 = g[7];
1334 1456           int32_t g8 = g[8];
1335 1456           int32_t g9 = g[9];
1336 1456           int32_t h0 = f0 - g0;
1337 1456           int32_t h1 = f1 - g1;
1338 1456           int32_t h2 = f2 - g2;
1339 1456           int32_t h3 = f3 - g3;
1340 1456           int32_t h4 = f4 - g4;
1341 1456           int32_t h5 = f5 - g5;
1342 1456           int32_t h6 = f6 - g6;
1343 1456           int32_t h7 = f7 - g7;
1344 1456           int32_t h8 = f8 - g8;
1345 1456           int32_t h9 = f9 - g9;
1346              
1347 1456           h[0] = h0;
1348 1456           h[1] = h1;
1349 1456           h[2] = h2;
1350 1456           h[3] = h3;
1351 1456           h[4] = h4;
1352 1456           h[5] = h5;
1353 1456           h[6] = h6;
1354 1456           h[7] = h7;
1355 1456           h[8] = h8;
1356 1456           h[9] = h9;
1357 1456           }
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 9           void fe_tobytes(unsigned char *s, const fe h) {
1387 9           int32_t h0 = h[0];
1388 9           int32_t h1 = h[1];
1389 9           int32_t h2 = h[2];
1390 9           int32_t h3 = h[3];
1391 9           int32_t h4 = h[4];
1392 9           int32_t h5 = h[5];
1393 9           int32_t h6 = h[6];
1394 9           int32_t h7 = h[7];
1395 9           int32_t h8 = h[8];
1396 9           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 9           q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
1409 9           q = (h0 + q) >> 26;
1410 9           q = (h1 + q) >> 25;
1411 9           q = (h2 + q) >> 26;
1412 9           q = (h3 + q) >> 25;
1413 9           q = (h4 + q) >> 26;
1414 9           q = (h5 + q) >> 25;
1415 9           q = (h6 + q) >> 26;
1416 9           q = (h7 + q) >> 25;
1417 9           q = (h8 + q) >> 26;
1418 9           q = (h9 + q) >> 25;
1419             /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
1420 9           h0 += 19 * q;
1421             /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
1422 9           carry0 = h0 >> 26;
1423 9           h1 += carry0;
1424 9           h0 -= carry0 << 26;
1425 9           carry1 = h1 >> 25;
1426 9           h2 += carry1;
1427 9           h1 -= carry1 << 25;
1428 9           carry2 = h2 >> 26;
1429 9           h3 += carry2;
1430 9           h2 -= carry2 << 26;
1431 9           carry3 = h3 >> 25;
1432 9           h4 += carry3;
1433 9           h3 -= carry3 << 25;
1434 9           carry4 = h4 >> 26;
1435 9           h5 += carry4;
1436 9           h4 -= carry4 << 26;
1437 9           carry5 = h5 >> 25;
1438 9           h6 += carry5;
1439 9           h5 -= carry5 << 25;
1440 9           carry6 = h6 >> 26;
1441 9           h7 += carry6;
1442 9           h6 -= carry6 << 26;
1443 9           carry7 = h7 >> 25;
1444 9           h8 += carry7;
1445 9           h7 -= carry7 << 25;
1446 9           carry8 = h8 >> 26;
1447 9           h9 += carry8;
1448 9           h8 -= carry8 << 26;
1449 9           carry9 = h9 >> 25;
1450 9           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 9           s[0] = (unsigned char) (h0 >> 0);
1460 9           s[1] = (unsigned char) (h0 >> 8);
1461 9           s[2] = (unsigned char) (h0 >> 16);
1462 9           s[3] = (unsigned char) ((h0 >> 24) | (h1 << 2));
1463 9           s[4] = (unsigned char) (h1 >> 6);
1464 9           s[5] = (unsigned char) (h1 >> 14);
1465 9           s[6] = (unsigned char) ((h1 >> 22) | (h2 << 3));
1466 9           s[7] = (unsigned char) (h2 >> 5);
1467 9           s[8] = (unsigned char) (h2 >> 13);
1468 9           s[9] = (unsigned char) ((h2 >> 21) | (h3 << 5));
1469 9           s[10] = (unsigned char) (h3 >> 3);
1470 9           s[11] = (unsigned char) (h3 >> 11);
1471 9           s[12] = (unsigned char) ((h3 >> 19) | (h4 << 6));
1472 9           s[13] = (unsigned char) (h4 >> 2);
1473 9           s[14] = (unsigned char) (h4 >> 10);
1474 9           s[15] = (unsigned char) (h4 >> 18);
1475 9           s[16] = (unsigned char) (h5 >> 0);
1476 9           s[17] = (unsigned char) (h5 >> 8);
1477 9           s[18] = (unsigned char) (h5 >> 16);
1478 9           s[19] = (unsigned char) ((h5 >> 24) | (h6 << 1));
1479 9           s[20] = (unsigned char) (h6 >> 7);
1480 9           s[21] = (unsigned char) (h6 >> 15);
1481 9           s[22] = (unsigned char) ((h6 >> 23) | (h7 << 3));
1482 9           s[23] = (unsigned char) (h7 >> 5);
1483 9           s[24] = (unsigned char) (h7 >> 13);
1484 9           s[25] = (unsigned char) ((h7 >> 21) | (h8 << 4));
1485 9           s[26] = (unsigned char) (h8 >> 4);
1486 9           s[27] = (unsigned char) (h8 >> 12);
1487 9           s[28] = (unsigned char) ((h8 >> 20) | (h9 << 6));
1488 9           s[29] = (unsigned char) (h9 >> 2);
1489 9           s[30] = (unsigned char) (h9 >> 10);
1490 9           s[31] = (unsigned char) (h9 >> 18);
1491 9           }