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