File Coverage

ed25519/src/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 12512           static uint64_t load_3(const unsigned char *in) {
9             uint64_t result;
10              
11 12512           result = (uint64_t) in[0];
12 12512           result |= ((uint64_t) in[1]) << 8;
13 12512           result |= ((uint64_t) in[2]) << 16;
14              
15 12512           return result;
16             }
17              
18 3128           static uint64_t load_4(const unsigned char *in) {
19             uint64_t result;
20              
21 3128           result = (uint64_t) in[0];
22 3128           result |= ((uint64_t) in[1]) << 8;
23 3128           result |= ((uint64_t) in[2]) << 16;
24 3128           result |= ((uint64_t) in[3]) << 24;
25            
26 3128           return result;
27             }
28              
29              
30              
31             /*
32             h = 0
33             */
34              
35 174220           void fe_0(fe h) {
36 174220           h[0] = 0;
37 174220           h[1] = 0;
38 174220           h[2] = 0;
39 174220           h[3] = 0;
40 174220           h[4] = 0;
41 174220           h[5] = 0;
42 174220           h[6] = 0;
43 174220           h[7] = 0;
44 174220           h[8] = 0;
45 174220           h[9] = 0;
46 174220           }
47              
48              
49              
50             /*
51             h = 1
52             */
53              
54 344772           void fe_1(fe h) {
55 344772           h[0] = 1;
56 344772           h[1] = 0;
57 344772           h[2] = 0;
58 344772           h[3] = 0;
59 344772           h[4] = 0;
60 344772           h[5] = 0;
61 344772           h[6] = 0;
62 344772           h[7] = 0;
63 344772           h[8] = 0;
64 344772           h[9] = 0;
65 344772           }
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 2069038           void fe_add(fe h, const fe f, const fe g) {
82 2069038           int32_t f0 = f[0];
83 2069038           int32_t f1 = f[1];
84 2069038           int32_t f2 = f[2];
85 2069038           int32_t f3 = f[3];
86 2069038           int32_t f4 = f[4];
87 2069038           int32_t f5 = f[5];
88 2069038           int32_t f6 = f[6];
89 2069038           int32_t f7 = f[7];
90 2069038           int32_t f8 = f[8];
91 2069038           int32_t f9 = f[9];
92 2069038           int32_t g0 = g[0];
93 2069038           int32_t g1 = g[1];
94 2069038           int32_t g2 = g[2];
95 2069038           int32_t g3 = g[3];
96 2069038           int32_t g4 = g[4];
97 2069038           int32_t g5 = g[5];
98 2069038           int32_t g6 = g[6];
99 2069038           int32_t g7 = g[7];
100 2069038           int32_t g8 = g[8];
101 2069038           int32_t g9 = g[9];
102 2069038           int32_t h0 = f0 + g0;
103 2069038           int32_t h1 = f1 + g1;
104 2069038           int32_t h2 = f2 + g2;
105 2069038           int32_t h3 = f3 + g3;
106 2069038           int32_t h4 = f4 + g4;
107 2069038           int32_t h5 = f5 + g5;
108 2069038           int32_t h6 = f6 + g6;
109 2069038           int32_t h7 = f7 + g7;
110 2069038           int32_t h8 = f8 + g8;
111 2069038           int32_t h9 = f9 + g9;
112            
113 2069038           h[0] = h0;
114 2069038           h[1] = h1;
115 2069038           h[2] = h2;
116 2069038           h[3] = h3;
117 2069038           h[4] = h4;
118 2069038           h[5] = h5;
119 2069038           h[6] = h6;
120 2069038           h[7] = h7;
121 2069038           h[8] = h8;
122 2069038           h[9] = h9;
123 2069038           }
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 4520448           void fe_cmov(fe f, const fe g, unsigned int b) {
135 4520448           int32_t f0 = f[0];
136 4520448           int32_t f1 = f[1];
137 4520448           int32_t f2 = f[2];
138 4520448           int32_t f3 = f[3];
139 4520448           int32_t f4 = f[4];
140 4520448           int32_t f5 = f[5];
141 4520448           int32_t f6 = f[6];
142 4520448           int32_t f7 = f[7];
143 4520448           int32_t f8 = f[8];
144 4520448           int32_t f9 = f[9];
145 4520448           int32_t g0 = g[0];
146 4520448           int32_t g1 = g[1];
147 4520448           int32_t g2 = g[2];
148 4520448           int32_t g3 = g[3];
149 4520448           int32_t g4 = g[4];
150 4520448           int32_t g5 = g[5];
151 4520448           int32_t g6 = g[6];
152 4520448           int32_t g7 = g[7];
153 4520448           int32_t g8 = g[8];
154 4520448           int32_t g9 = g[9];
155 4520448           int32_t x0 = f0 ^ g0;
156 4520448           int32_t x1 = f1 ^ g1;
157 4520448           int32_t x2 = f2 ^ g2;
158 4520448           int32_t x3 = f3 ^ g3;
159 4520448           int32_t x4 = f4 ^ g4;
160 4520448           int32_t x5 = f5 ^ g5;
161 4520448           int32_t x6 = f6 ^ g6;
162 4520448           int32_t x7 = f7 ^ g7;
163 4520448           int32_t x8 = f8 ^ g8;
164 4520448           int32_t x9 = f9 ^ g9;
165              
166 4520448           b = (unsigned int) (- (int) b); /* silence warning */
167 4520448           x0 &= b;
168 4520448           x1 &= b;
169 4520448           x2 &= b;
170 4520448           x3 &= b;
171 4520448           x4 &= b;
172 4520448           x5 &= b;
173 4520448           x6 &= b;
174 4520448           x7 &= b;
175 4520448           x8 &= b;
176 4520448           x9 &= b;
177            
178 4520448           f[0] = f0 ^ x0;
179 4520448           f[1] = f1 ^ x1;
180 4520448           f[2] = f2 ^ x2;
181 4520448           f[3] = f3 ^ x3;
182 4520448           f[4] = f4 ^ x4;
183 4520448           f[5] = f5 ^ x5;
184 4520448           f[6] = f6 ^ x6;
185 4520448           f[7] = f7 ^ x7;
186 4520448           f[8] = f8 ^ x8;
187 4520448           f[9] = f9 ^ x9;
188 4520448           }
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 359900           void fe_copy(fe h, const fe f) {
268 359900           int32_t f0 = f[0];
269 359900           int32_t f1 = f[1];
270 359900           int32_t f2 = f[2];
271 359900           int32_t f3 = f[3];
272 359900           int32_t f4 = f[4];
273 359900           int32_t f5 = f[5];
274 359900           int32_t f6 = f[6];
275 359900           int32_t f7 = f[7];
276 359900           int32_t f8 = f[8];
277 359900           int32_t f9 = f[9];
278            
279 359900           h[0] = f0;
280 359900           h[1] = f1;
281 359900           h[2] = f2;
282 359900           h[3] = f3;
283 359900           h[4] = f4;
284 359900           h[5] = f5;
285 359900           h[6] = f6;
286 359900           h[7] = f7;
287 359900           h[8] = f8;
288 359900           h[9] = f9;
289 359900           }
290              
291              
292              
293             /*
294             Ignores top bit of h.
295             */
296              
297 1564           void fe_frombytes(fe h, const unsigned char *s) {
298 1564           int64_t h0 = load_4(s);
299 1564           int64_t h1 = load_3(s + 4) << 6;
300 1564           int64_t h2 = load_3(s + 7) << 5;
301 1564           int64_t h3 = load_3(s + 10) << 3;
302 1564           int64_t h4 = load_3(s + 13) << 2;
303 1564           int64_t h5 = load_4(s + 16);
304 1564           int64_t h6 = load_3(s + 20) << 7;
305 1564           int64_t h7 = load_3(s + 23) << 5;
306 1564           int64_t h8 = load_3(s + 26) << 4;
307 1564           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 1564           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
320 1564           h0 += carry9 * 19;
321 1564           h9 -= carry9 << 25;
322 1564           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
323 1564           h2 += carry1;
324 1564           h1 -= carry1 << 25;
325 1564           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
326 1564           h4 += carry3;
327 1564           h3 -= carry3 << 25;
328 1564           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
329 1564           h6 += carry5;
330 1564           h5 -= carry5 << 25;
331 1564           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
332 1564           h8 += carry7;
333 1564           h7 -= carry7 << 25;
334 1564           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
335 1564           h1 += carry0;
336 1564           h0 -= carry0 << 26;
337 1564           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
338 1564           h3 += carry2;
339 1564           h2 -= carry2 << 26;
340 1564           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
341 1564           h5 += carry4;
342 1564           h4 -= carry4 << 26;
343 1564           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
344 1564           h7 += carry6;
345 1564           h6 -= carry6 << 26;
346 1564           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
347 1564           h9 += carry8;
348 1564           h8 -= carry8 << 26;
349              
350 1564           h[0] = (int32_t) h0;
351 1564           h[1] = (int32_t) h1;
352 1564           h[2] = (int32_t) h2;
353 1564           h[3] = (int32_t) h3;
354 1564           h[4] = (int32_t) h4;
355 1564           h[5] = (int32_t) h5;
356 1564           h[6] = (int32_t) h6;
357 1564           h[7] = (int32_t) h7;
358 1564           h[8] = (int32_t) h8;
359 1564           h[9] = (int32_t) h9;
360 1564           }
361              
362              
363              
364 4180           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 4180           fe_sq(t0, z);
372              
373 4180 50         for (i = 1; i < 1; ++i) {
374 0           fe_sq(t0, t0);
375             }
376              
377 4180           fe_sq(t1, t0);
378              
379 8360 100         for (i = 1; i < 2; ++i) {
380 4180           fe_sq(t1, t1);
381             }
382              
383 4180           fe_mul(t1, z, t1);
384 4180           fe_mul(t0, t0, t1);
385 4180           fe_sq(t2, t0);
386              
387 4180 50         for (i = 1; i < 1; ++i) {
388 0           fe_sq(t2, t2);
389             }
390              
391 4180           fe_mul(t1, t1, t2);
392 4180           fe_sq(t2, t1);
393              
394 20900 100         for (i = 1; i < 5; ++i) {
395 16720           fe_sq(t2, t2);
396             }
397              
398 4180           fe_mul(t1, t2, t1);
399 4180           fe_sq(t2, t1);
400              
401 41800 100         for (i = 1; i < 10; ++i) {
402 37620           fe_sq(t2, t2);
403             }
404              
405 4180           fe_mul(t2, t2, t1);
406 4180           fe_sq(t3, t2);
407              
408 83600 100         for (i = 1; i < 20; ++i) {
409 79420           fe_sq(t3, t3);
410             }
411              
412 4180           fe_mul(t2, t3, t2);
413 4180           fe_sq(t2, t2);
414              
415 41800 100         for (i = 1; i < 10; ++i) {
416 37620           fe_sq(t2, t2);
417             }
418              
419 4180           fe_mul(t1, t2, t1);
420 4180           fe_sq(t2, t1);
421              
422 209000 100         for (i = 1; i < 50; ++i) {
423 204820           fe_sq(t2, t2);
424             }
425              
426 4180           fe_mul(t2, t2, t1);
427 4180           fe_sq(t3, t2);
428              
429 418000 100         for (i = 1; i < 100; ++i) {
430 413820           fe_sq(t3, t3);
431             }
432              
433 4180           fe_mul(t2, t3, t2);
434 4180           fe_sq(t2, t2);
435              
436 209000 100         for (i = 1; i < 50; ++i) {
437 204820           fe_sq(t2, t2);
438             }
439              
440 4180           fe_mul(t1, t2, t1);
441 4180           fe_sq(t1, t1);
442              
443 20900 100         for (i = 1; i < 5; ++i) {
444 16720           fe_sq(t1, t1);
445             }
446              
447 4180           fe_mul(out, t1, t0);
448 4180           }
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 5744           int fe_isnegative(const fe f) {
461             unsigned char s[32];
462              
463 5744           fe_tobytes(s, f);
464            
465 5744           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 2352           int fe_isnonzero(const fe f) {
479             unsigned char s[32];
480             unsigned char r;
481              
482 2352           fe_tobytes(s, f);
483              
484 2352           r = s[0];
485             #define F(i) r |= s[i]
486 2352           F(1);
487 2352           F(2);
488 2352           F(3);
489 2352           F(4);
490 2352           F(5);
491 2352           F(6);
492 2352           F(7);
493 2352           F(8);
494 2352           F(9);
495 2352           F(10);
496 2352           F(11);
497 2352           F(12);
498 2352           F(13);
499 2352           F(14);
500 2352           F(15);
501 2352           F(16);
502 2352           F(17);
503 2352           F(18);
504 2352           F(19);
505 2352           F(20);
506 2352           F(21);
507 2352           F(22);
508 2352           F(23);
509 2352           F(24);
510 2352           F(25);
511 2352           F(26);
512 2352           F(27);
513 2352           F(28);
514 2352           F(29);
515 2352           F(30);
516 2352           F(31);
517             #undef F
518              
519 2352           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 3571017           void fe_mul(fe h, const fe f, const fe g) {
557 3571017           int32_t f0 = f[0];
558 3571017           int32_t f1 = f[1];
559 3571017           int32_t f2 = f[2];
560 3571017           int32_t f3 = f[3];
561 3571017           int32_t f4 = f[4];
562 3571017           int32_t f5 = f[5];
563 3571017           int32_t f6 = f[6];
564 3571017           int32_t f7 = f[7];
565 3571017           int32_t f8 = f[8];
566 3571017           int32_t f9 = f[9];
567 3571017           int32_t g0 = g[0];
568 3571017           int32_t g1 = g[1];
569 3571017           int32_t g2 = g[2];
570 3571017           int32_t g3 = g[3];
571 3571017           int32_t g4 = g[4];
572 3571017           int32_t g5 = g[5];
573 3571017           int32_t g6 = g[6];
574 3571017           int32_t g7 = g[7];
575 3571017           int32_t g8 = g[8];
576 3571017           int32_t g9 = g[9];
577 3571017           int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
578 3571017           int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
579 3571017           int32_t g3_19 = 19 * g3;
580 3571017           int32_t g4_19 = 19 * g4;
581 3571017           int32_t g5_19 = 19 * g5;
582 3571017           int32_t g6_19 = 19 * g6;
583 3571017           int32_t g7_19 = 19 * g7;
584 3571017           int32_t g8_19 = 19 * g8;
585 3571017           int32_t g9_19 = 19 * g9;
586 3571017           int32_t f1_2 = 2 * f1;
587 3571017           int32_t f3_2 = 2 * f3;
588 3571017           int32_t f5_2 = 2 * f5;
589 3571017           int32_t f7_2 = 2 * f7;
590 3571017           int32_t f9_2 = 2 * f9;
591 3571017           int64_t f0g0 = f0 * (int64_t) g0;
592 3571017           int64_t f0g1 = f0 * (int64_t) g1;
593 3571017           int64_t f0g2 = f0 * (int64_t) g2;
594 3571017           int64_t f0g3 = f0 * (int64_t) g3;
595 3571017           int64_t f0g4 = f0 * (int64_t) g4;
596 3571017           int64_t f0g5 = f0 * (int64_t) g5;
597 3571017           int64_t f0g6 = f0 * (int64_t) g6;
598 3571017           int64_t f0g7 = f0 * (int64_t) g7;
599 3571017           int64_t f0g8 = f0 * (int64_t) g8;
600 3571017           int64_t f0g9 = f0 * (int64_t) g9;
601 3571017           int64_t f1g0 = f1 * (int64_t) g0;
602 3571017           int64_t f1g1_2 = f1_2 * (int64_t) g1;
603 3571017           int64_t f1g2 = f1 * (int64_t) g2;
604 3571017           int64_t f1g3_2 = f1_2 * (int64_t) g3;
605 3571017           int64_t f1g4 = f1 * (int64_t) g4;
606 3571017           int64_t f1g5_2 = f1_2 * (int64_t) g5;
607 3571017           int64_t f1g6 = f1 * (int64_t) g6;
608 3571017           int64_t f1g7_2 = f1_2 * (int64_t) g7;
609 3571017           int64_t f1g8 = f1 * (int64_t) g8;
610 3571017           int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
611 3571017           int64_t f2g0 = f2 * (int64_t) g0;
612 3571017           int64_t f2g1 = f2 * (int64_t) g1;
613 3571017           int64_t f2g2 = f2 * (int64_t) g2;
614 3571017           int64_t f2g3 = f2 * (int64_t) g3;
615 3571017           int64_t f2g4 = f2 * (int64_t) g4;
616 3571017           int64_t f2g5 = f2 * (int64_t) g5;
617 3571017           int64_t f2g6 = f2 * (int64_t) g6;
618 3571017           int64_t f2g7 = f2 * (int64_t) g7;
619 3571017           int64_t f2g8_19 = f2 * (int64_t) g8_19;
620 3571017           int64_t f2g9_19 = f2 * (int64_t) g9_19;
621 3571017           int64_t f3g0 = f3 * (int64_t) g0;
622 3571017           int64_t f3g1_2 = f3_2 * (int64_t) g1;
623 3571017           int64_t f3g2 = f3 * (int64_t) g2;
624 3571017           int64_t f3g3_2 = f3_2 * (int64_t) g3;
625 3571017           int64_t f3g4 = f3 * (int64_t) g4;
626 3571017           int64_t f3g5_2 = f3_2 * (int64_t) g5;
627 3571017           int64_t f3g6 = f3 * (int64_t) g6;
628 3571017           int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
629 3571017           int64_t f3g8_19 = f3 * (int64_t) g8_19;
630 3571017           int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
631 3571017           int64_t f4g0 = f4 * (int64_t) g0;
632 3571017           int64_t f4g1 = f4 * (int64_t) g1;
633 3571017           int64_t f4g2 = f4 * (int64_t) g2;
634 3571017           int64_t f4g3 = f4 * (int64_t) g3;
635 3571017           int64_t f4g4 = f4 * (int64_t) g4;
636 3571017           int64_t f4g5 = f4 * (int64_t) g5;
637 3571017           int64_t f4g6_19 = f4 * (int64_t) g6_19;
638 3571017           int64_t f4g7_19 = f4 * (int64_t) g7_19;
639 3571017           int64_t f4g8_19 = f4 * (int64_t) g8_19;
640 3571017           int64_t f4g9_19 = f4 * (int64_t) g9_19;
641 3571017           int64_t f5g0 = f5 * (int64_t) g0;
642 3571017           int64_t f5g1_2 = f5_2 * (int64_t) g1;
643 3571017           int64_t f5g2 = f5 * (int64_t) g2;
644 3571017           int64_t f5g3_2 = f5_2 * (int64_t) g3;
645 3571017           int64_t f5g4 = f5 * (int64_t) g4;
646 3571017           int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
647 3571017           int64_t f5g6_19 = f5 * (int64_t) g6_19;
648 3571017           int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
649 3571017           int64_t f5g8_19 = f5 * (int64_t) g8_19;
650 3571017           int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
651 3571017           int64_t f6g0 = f6 * (int64_t) g0;
652 3571017           int64_t f6g1 = f6 * (int64_t) g1;
653 3571017           int64_t f6g2 = f6 * (int64_t) g2;
654 3571017           int64_t f6g3 = f6 * (int64_t) g3;
655 3571017           int64_t f6g4_19 = f6 * (int64_t) g4_19;
656 3571017           int64_t f6g5_19 = f6 * (int64_t) g5_19;
657 3571017           int64_t f6g6_19 = f6 * (int64_t) g6_19;
658 3571017           int64_t f6g7_19 = f6 * (int64_t) g7_19;
659 3571017           int64_t f6g8_19 = f6 * (int64_t) g8_19;
660 3571017           int64_t f6g9_19 = f6 * (int64_t) g9_19;
661 3571017           int64_t f7g0 = f7 * (int64_t) g0;
662 3571017           int64_t f7g1_2 = f7_2 * (int64_t) g1;
663 3571017           int64_t f7g2 = f7 * (int64_t) g2;
664 3571017           int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
665 3571017           int64_t f7g4_19 = f7 * (int64_t) g4_19;
666 3571017           int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
667 3571017           int64_t f7g6_19 = f7 * (int64_t) g6_19;
668 3571017           int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
669 3571017           int64_t f7g8_19 = f7 * (int64_t) g8_19;
670 3571017           int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
671 3571017           int64_t f8g0 = f8 * (int64_t) g0;
672 3571017           int64_t f8g1 = f8 * (int64_t) g1;
673 3571017           int64_t f8g2_19 = f8 * (int64_t) g2_19;
674 3571017           int64_t f8g3_19 = f8 * (int64_t) g3_19;
675 3571017           int64_t f8g4_19 = f8 * (int64_t) g4_19;
676 3571017           int64_t f8g5_19 = f8 * (int64_t) g5_19;
677 3571017           int64_t f8g6_19 = f8 * (int64_t) g6_19;
678 3571017           int64_t f8g7_19 = f8 * (int64_t) g7_19;
679 3571017           int64_t f8g8_19 = f8 * (int64_t) g8_19;
680 3571017           int64_t f8g9_19 = f8 * (int64_t) g9_19;
681 3571017           int64_t f9g0 = f9 * (int64_t) g0;
682 3571017           int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
683 3571017           int64_t f9g2_19 = f9 * (int64_t) g2_19;
684 3571017           int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
685 3571017           int64_t f9g4_19 = f9 * (int64_t) g4_19;
686 3571017           int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
687 3571017           int64_t f9g6_19 = f9 * (int64_t) g6_19;
688 3571017           int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
689 3571017           int64_t f9g8_19 = f9 * (int64_t) g8_19;
690 3571017           int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
691 3571017           int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38;
692 3571017           int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19;
693 3571017           int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38;
694 3571017           int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19;
695 3571017           int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38;
696 3571017           int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19;
697 3571017           int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38;
698 3571017           int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19;
699 3571017           int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38;
700 3571017           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 3571017           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
713 3571017           h1 += carry0;
714 3571017           h0 -= carry0 << 26;
715 3571017           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
716 3571017           h5 += carry4;
717 3571017           h4 -= carry4 << 26;
718              
719 3571017           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
720 3571017           h2 += carry1;
721 3571017           h1 -= carry1 << 25;
722 3571017           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
723 3571017           h6 += carry5;
724 3571017           h5 -= carry5 << 25;
725              
726 3571017           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
727 3571017           h3 += carry2;
728 3571017           h2 -= carry2 << 26;
729 3571017           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
730 3571017           h7 += carry6;
731 3571017           h6 -= carry6 << 26;
732              
733 3571017           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
734 3571017           h4 += carry3;
735 3571017           h3 -= carry3 << 25;
736 3571017           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
737 3571017           h8 += carry7;
738 3571017           h7 -= carry7 << 25;
739              
740 3571017           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
741 3571017           h5 += carry4;
742 3571017           h4 -= carry4 << 26;
743 3571017           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
744 3571017           h9 += carry8;
745 3571017           h8 -= carry8 << 26;
746              
747 3571017           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
748 3571017           h0 += carry9 * 19;
749 3571017           h9 -= carry9 << 25;
750              
751 3571017           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
752 3571017           h1 += carry0;
753 3571017           h0 -= carry0 << 26;
754              
755 3571017           h[0] = (int32_t) h0;
756 3571017           h[1] = (int32_t) h1;
757 3571017           h[2] = (int32_t) h2;
758 3571017           h[3] = (int32_t) h3;
759 3571017           h[4] = (int32_t) h4;
760 3571017           h[5] = (int32_t) h5;
761 3571017           h[6] = (int32_t) h6;
762 3571017           h[7] = (int32_t) h7;
763 3571017           h[8] = (int32_t) h8;
764 3571017           h[9] = (int32_t) h9;
765 3571017           }
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] = (int32_t) h0;
824 0           h[1] = (int32_t) h1;
825 0           h[2] = (int32_t) h2;
826 0           h[3] = (int32_t) h3;
827 0           h[4] = (int32_t) h4;
828 0           h[5] = (int32_t) h5;
829 0           h[6] = (int32_t) h6;
830 0           h[7] = (int32_t) h7;
831 0           h[8] = (int32_t) h8;
832 0           h[9] = (int32_t) 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 168220           void fe_neg(fe h, const fe f) {
847 168220           int32_t f0 = f[0];
848 168220           int32_t f1 = f[1];
849 168220           int32_t f2 = f[2];
850 168220           int32_t f3 = f[3];
851 168220           int32_t f4 = f[4];
852 168220           int32_t f5 = f[5];
853 168220           int32_t f6 = f[6];
854 168220           int32_t f7 = f[7];
855 168220           int32_t f8 = f[8];
856 168220           int32_t f9 = f[9];
857 168220           int32_t h0 = -f0;
858 168220           int32_t h1 = -f1;
859 168220           int32_t h2 = -f2;
860 168220           int32_t h3 = -f3;
861 168220           int32_t h4 = -f4;
862 168220           int32_t h5 = -f5;
863 168220           int32_t h6 = -f6;
864 168220           int32_t h7 = -f7;
865 168220           int32_t h8 = -f8;
866 168220           int32_t h9 = -f9;
867              
868 168220           h[0] = h0;
869 168220           h[1] = h1;
870 168220           h[2] = h2;
871 168220           h[3] = h3;
872 168220           h[4] = h4;
873 168220           h[5] = h5;
874 168220           h[6] = h6;
875 168220           h[7] = h7;
876 168220           h[8] = h8;
877 168220           h[9] = h9;
878 168220           }
879              
880              
881 1564           void fe_pow22523(fe out, const fe z) {
882             fe t0;
883             fe t1;
884             fe t2;
885             int i;
886 1564           fe_sq(t0, z);
887              
888 1564 50         for (i = 1; i < 1; ++i) {
889 0           fe_sq(t0, t0);
890             }
891              
892 1564           fe_sq(t1, t0);
893              
894 3128 100         for (i = 1; i < 2; ++i) {
895 1564           fe_sq(t1, t1);
896             }
897              
898 1564           fe_mul(t1, z, t1);
899 1564           fe_mul(t0, t0, t1);
900 1564           fe_sq(t0, t0);
901              
902 1564 50         for (i = 1; i < 1; ++i) {
903 0           fe_sq(t0, t0);
904             }
905              
906 1564           fe_mul(t0, t1, t0);
907 1564           fe_sq(t1, t0);
908              
909 7820 100         for (i = 1; i < 5; ++i) {
910 6256           fe_sq(t1, t1);
911             }
912              
913 1564           fe_mul(t0, t1, t0);
914 1564           fe_sq(t1, t0);
915              
916 15640 100         for (i = 1; i < 10; ++i) {
917 14076           fe_sq(t1, t1);
918             }
919              
920 1564           fe_mul(t1, t1, t0);
921 1564           fe_sq(t2, t1);
922              
923 31280 100         for (i = 1; i < 20; ++i) {
924 29716           fe_sq(t2, t2);
925             }
926              
927 1564           fe_mul(t1, t2, t1);
928 1564           fe_sq(t1, t1);
929              
930 15640 100         for (i = 1; i < 10; ++i) {
931 14076           fe_sq(t1, t1);
932             }
933              
934 1564           fe_mul(t0, t1, t0);
935 1564           fe_sq(t1, t0);
936              
937 78200 100         for (i = 1; i < 50; ++i) {
938 76636           fe_sq(t1, t1);
939             }
940              
941 1564           fe_mul(t1, t1, t0);
942 1564           fe_sq(t2, t1);
943              
944 156400 100         for (i = 1; i < 100; ++i) {
945 154836           fe_sq(t2, t2);
946             }
947              
948 1564           fe_mul(t1, t2, t1);
949 1564           fe_sq(t1, t1);
950              
951 78200 100         for (i = 1; i < 50; ++i) {
952 76636           fe_sq(t1, t1);
953             }
954              
955 1564           fe_mul(t0, t1, t0);
956 1564           fe_sq(t0, t0);
957              
958 3128 100         for (i = 1; i < 2; ++i) {
959 1564           fe_sq(t0, t0);
960             }
961              
962 1564           fe_mul(out, t0, z);
963 1564           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 2676161           void fe_sq(fe h, const fe f) {
983 2676161           int32_t f0 = f[0];
984 2676161           int32_t f1 = f[1];
985 2676161           int32_t f2 = f[2];
986 2676161           int32_t f3 = f[3];
987 2676161           int32_t f4 = f[4];
988 2676161           int32_t f5 = f[5];
989 2676161           int32_t f6 = f[6];
990 2676161           int32_t f7 = f[7];
991 2676161           int32_t f8 = f[8];
992 2676161           int32_t f9 = f[9];
993 2676161           int32_t f0_2 = 2 * f0;
994 2676161           int32_t f1_2 = 2 * f1;
995 2676161           int32_t f2_2 = 2 * f2;
996 2676161           int32_t f3_2 = 2 * f3;
997 2676161           int32_t f4_2 = 2 * f4;
998 2676161           int32_t f5_2 = 2 * f5;
999 2676161           int32_t f6_2 = 2 * f6;
1000 2676161           int32_t f7_2 = 2 * f7;
1001 2676161           int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
1002 2676161           int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
1003 2676161           int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
1004 2676161           int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
1005 2676161           int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
1006 2676161           int64_t f0f0 = f0 * (int64_t) f0;
1007 2676161           int64_t f0f1_2 = f0_2 * (int64_t) f1;
1008 2676161           int64_t f0f2_2 = f0_2 * (int64_t) f2;
1009 2676161           int64_t f0f3_2 = f0_2 * (int64_t) f3;
1010 2676161           int64_t f0f4_2 = f0_2 * (int64_t) f4;
1011 2676161           int64_t f0f5_2 = f0_2 * (int64_t) f5;
1012 2676161           int64_t f0f6_2 = f0_2 * (int64_t) f6;
1013 2676161           int64_t f0f7_2 = f0_2 * (int64_t) f7;
1014 2676161           int64_t f0f8_2 = f0_2 * (int64_t) f8;
1015 2676161           int64_t f0f9_2 = f0_2 * (int64_t) f9;
1016 2676161           int64_t f1f1_2 = f1_2 * (int64_t) f1;
1017 2676161           int64_t f1f2_2 = f1_2 * (int64_t) f2;
1018 2676161           int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
1019 2676161           int64_t f1f4_2 = f1_2 * (int64_t) f4;
1020 2676161           int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
1021 2676161           int64_t f1f6_2 = f1_2 * (int64_t) f6;
1022 2676161           int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
1023 2676161           int64_t f1f8_2 = f1_2 * (int64_t) f8;
1024 2676161           int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
1025 2676161           int64_t f2f2 = f2 * (int64_t) f2;
1026 2676161           int64_t f2f3_2 = f2_2 * (int64_t) f3;
1027 2676161           int64_t f2f4_2 = f2_2 * (int64_t) f4;
1028 2676161           int64_t f2f5_2 = f2_2 * (int64_t) f5;
1029 2676161           int64_t f2f6_2 = f2_2 * (int64_t) f6;
1030 2676161           int64_t f2f7_2 = f2_2 * (int64_t) f7;
1031 2676161           int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
1032 2676161           int64_t f2f9_38 = f2 * (int64_t) f9_38;
1033 2676161           int64_t f3f3_2 = f3_2 * (int64_t) f3;
1034 2676161           int64_t f3f4_2 = f3_2 * (int64_t) f4;
1035 2676161           int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
1036 2676161           int64_t f3f6_2 = f3_2 * (int64_t) f6;
1037 2676161           int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
1038 2676161           int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
1039 2676161           int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
1040 2676161           int64_t f4f4 = f4 * (int64_t) f4;
1041 2676161           int64_t f4f5_2 = f4_2 * (int64_t) f5;
1042 2676161           int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
1043 2676161           int64_t f4f7_38 = f4 * (int64_t) f7_38;
1044 2676161           int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
1045 2676161           int64_t f4f9_38 = f4 * (int64_t) f9_38;
1046 2676161           int64_t f5f5_38 = f5 * (int64_t) f5_38;
1047 2676161           int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
1048 2676161           int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
1049 2676161           int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
1050 2676161           int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
1051 2676161           int64_t f6f6_19 = f6 * (int64_t) f6_19;
1052 2676161           int64_t f6f7_38 = f6 * (int64_t) f7_38;
1053 2676161           int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
1054 2676161           int64_t f6f9_38 = f6 * (int64_t) f9_38;
1055 2676161           int64_t f7f7_38 = f7 * (int64_t) f7_38;
1056 2676161           int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
1057 2676161           int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
1058 2676161           int64_t f8f8_19 = f8 * (int64_t) f8_19;
1059 2676161           int64_t f8f9_38 = f8 * (int64_t) f9_38;
1060 2676161           int64_t f9f9_38 = f9 * (int64_t) f9_38;
1061 2676161           int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1062 2676161           int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1063 2676161           int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1064 2676161           int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1065 2676161           int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1066 2676161           int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1067 2676161           int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1068 2676161           int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1069 2676161           int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1070 2676161           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 2676161           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1082 2676161           h1 += carry0;
1083 2676161           h0 -= carry0 << 26;
1084 2676161           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1085 2676161           h5 += carry4;
1086 2676161           h4 -= carry4 << 26;
1087 2676161           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
1088 2676161           h2 += carry1;
1089 2676161           h1 -= carry1 << 25;
1090 2676161           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
1091 2676161           h6 += carry5;
1092 2676161           h5 -= carry5 << 25;
1093 2676161           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
1094 2676161           h3 += carry2;
1095 2676161           h2 -= carry2 << 26;
1096 2676161           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
1097 2676161           h7 += carry6;
1098 2676161           h6 -= carry6 << 26;
1099 2676161           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
1100 2676161           h4 += carry3;
1101 2676161           h3 -= carry3 << 25;
1102 2676161           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
1103 2676161           h8 += carry7;
1104 2676161           h7 -= carry7 << 25;
1105 2676161           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1106 2676161           h5 += carry4;
1107 2676161           h4 -= carry4 << 26;
1108 2676161           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
1109 2676161           h9 += carry8;
1110 2676161           h8 -= carry8 << 26;
1111 2676161           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
1112 2676161           h0 += carry9 * 19;
1113 2676161           h9 -= carry9 << 25;
1114 2676161           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1115 2676161           h1 += carry0;
1116 2676161           h0 -= carry0 << 26;
1117 2676161           h[0] = (int32_t) h0;
1118 2676161           h[1] = (int32_t) h1;
1119 2676161           h[2] = (int32_t) h2;
1120 2676161           h[3] = (int32_t) h3;
1121 2676161           h[4] = (int32_t) h4;
1122 2676161           h[5] = (int32_t) h5;
1123 2676161           h[6] = (int32_t) h6;
1124 2676161           h[7] = (int32_t) h7;
1125 2676161           h[8] = (int32_t) h8;
1126 2676161           h[9] = (int32_t) h9;
1127 2676161           }
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 405207           void fe_sq2(fe h, const fe f) {
1146 405207           int32_t f0 = f[0];
1147 405207           int32_t f1 = f[1];
1148 405207           int32_t f2 = f[2];
1149 405207           int32_t f3 = f[3];
1150 405207           int32_t f4 = f[4];
1151 405207           int32_t f5 = f[5];
1152 405207           int32_t f6 = f[6];
1153 405207           int32_t f7 = f[7];
1154 405207           int32_t f8 = f[8];
1155 405207           int32_t f9 = f[9];
1156 405207           int32_t f0_2 = 2 * f0;
1157 405207           int32_t f1_2 = 2 * f1;
1158 405207           int32_t f2_2 = 2 * f2;
1159 405207           int32_t f3_2 = 2 * f3;
1160 405207           int32_t f4_2 = 2 * f4;
1161 405207           int32_t f5_2 = 2 * f5;
1162 405207           int32_t f6_2 = 2 * f6;
1163 405207           int32_t f7_2 = 2 * f7;
1164 405207           int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
1165 405207           int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
1166 405207           int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
1167 405207           int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
1168 405207           int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
1169 405207           int64_t f0f0 = f0 * (int64_t) f0;
1170 405207           int64_t f0f1_2 = f0_2 * (int64_t) f1;
1171 405207           int64_t f0f2_2 = f0_2 * (int64_t) f2;
1172 405207           int64_t f0f3_2 = f0_2 * (int64_t) f3;
1173 405207           int64_t f0f4_2 = f0_2 * (int64_t) f4;
1174 405207           int64_t f0f5_2 = f0_2 * (int64_t) f5;
1175 405207           int64_t f0f6_2 = f0_2 * (int64_t) f6;
1176 405207           int64_t f0f7_2 = f0_2 * (int64_t) f7;
1177 405207           int64_t f0f8_2 = f0_2 * (int64_t) f8;
1178 405207           int64_t f0f9_2 = f0_2 * (int64_t) f9;
1179 405207           int64_t f1f1_2 = f1_2 * (int64_t) f1;
1180 405207           int64_t f1f2_2 = f1_2 * (int64_t) f2;
1181 405207           int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
1182 405207           int64_t f1f4_2 = f1_2 * (int64_t) f4;
1183 405207           int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
1184 405207           int64_t f1f6_2 = f1_2 * (int64_t) f6;
1185 405207           int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
1186 405207           int64_t f1f8_2 = f1_2 * (int64_t) f8;
1187 405207           int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
1188 405207           int64_t f2f2 = f2 * (int64_t) f2;
1189 405207           int64_t f2f3_2 = f2_2 * (int64_t) f3;
1190 405207           int64_t f2f4_2 = f2_2 * (int64_t) f4;
1191 405207           int64_t f2f5_2 = f2_2 * (int64_t) f5;
1192 405207           int64_t f2f6_2 = f2_2 * (int64_t) f6;
1193 405207           int64_t f2f7_2 = f2_2 * (int64_t) f7;
1194 405207           int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
1195 405207           int64_t f2f9_38 = f2 * (int64_t) f9_38;
1196 405207           int64_t f3f3_2 = f3_2 * (int64_t) f3;
1197 405207           int64_t f3f4_2 = f3_2 * (int64_t) f4;
1198 405207           int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
1199 405207           int64_t f3f6_2 = f3_2 * (int64_t) f6;
1200 405207           int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
1201 405207           int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
1202 405207           int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
1203 405207           int64_t f4f4 = f4 * (int64_t) f4;
1204 405207           int64_t f4f5_2 = f4_2 * (int64_t) f5;
1205 405207           int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
1206 405207           int64_t f4f7_38 = f4 * (int64_t) f7_38;
1207 405207           int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
1208 405207           int64_t f4f9_38 = f4 * (int64_t) f9_38;
1209 405207           int64_t f5f5_38 = f5 * (int64_t) f5_38;
1210 405207           int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
1211 405207           int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
1212 405207           int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
1213 405207           int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
1214 405207           int64_t f6f6_19 = f6 * (int64_t) f6_19;
1215 405207           int64_t f6f7_38 = f6 * (int64_t) f7_38;
1216 405207           int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
1217 405207           int64_t f6f9_38 = f6 * (int64_t) f9_38;
1218 405207           int64_t f7f7_38 = f7 * (int64_t) f7_38;
1219 405207           int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
1220 405207           int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
1221 405207           int64_t f8f8_19 = f8 * (int64_t) f8_19;
1222 405207           int64_t f8f9_38 = f8 * (int64_t) f9_38;
1223 405207           int64_t f9f9_38 = f9 * (int64_t) f9_38;
1224 405207           int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38;
1225 405207           int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38;
1226 405207           int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19;
1227 405207           int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38;
1228 405207           int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38;
1229 405207           int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38;
1230 405207           int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19;
1231 405207           int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38;
1232 405207           int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38;
1233 405207           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 405207           h0 += h0;
1245 405207           h1 += h1;
1246 405207           h2 += h2;
1247 405207           h3 += h3;
1248 405207           h4 += h4;
1249 405207           h5 += h5;
1250 405207           h6 += h6;
1251 405207           h7 += h7;
1252 405207           h8 += h8;
1253 405207           h9 += h9;
1254 405207           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1255 405207           h1 += carry0;
1256 405207           h0 -= carry0 << 26;
1257 405207           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1258 405207           h5 += carry4;
1259 405207           h4 -= carry4 << 26;
1260 405207           carry1 = (h1 + (int64_t) (1 << 24)) >> 25;
1261 405207           h2 += carry1;
1262 405207           h1 -= carry1 << 25;
1263 405207           carry5 = (h5 + (int64_t) (1 << 24)) >> 25;
1264 405207           h6 += carry5;
1265 405207           h5 -= carry5 << 25;
1266 405207           carry2 = (h2 + (int64_t) (1 << 25)) >> 26;
1267 405207           h3 += carry2;
1268 405207           h2 -= carry2 << 26;
1269 405207           carry6 = (h6 + (int64_t) (1 << 25)) >> 26;
1270 405207           h7 += carry6;
1271 405207           h6 -= carry6 << 26;
1272 405207           carry3 = (h3 + (int64_t) (1 << 24)) >> 25;
1273 405207           h4 += carry3;
1274 405207           h3 -= carry3 << 25;
1275 405207           carry7 = (h7 + (int64_t) (1 << 24)) >> 25;
1276 405207           h8 += carry7;
1277 405207           h7 -= carry7 << 25;
1278 405207           carry4 = (h4 + (int64_t) (1 << 25)) >> 26;
1279 405207           h5 += carry4;
1280 405207           h4 -= carry4 << 26;
1281 405207           carry8 = (h8 + (int64_t) (1 << 25)) >> 26;
1282 405207           h9 += carry8;
1283 405207           h8 -= carry8 << 26;
1284 405207           carry9 = (h9 + (int64_t) (1 << 24)) >> 25;
1285 405207           h0 += carry9 * 19;
1286 405207           h9 -= carry9 << 25;
1287 405207           carry0 = (h0 + (int64_t) (1 << 25)) >> 26;
1288 405207           h1 += carry0;
1289 405207           h0 -= carry0 << 26;
1290 405207           h[0] = (int32_t) h0;
1291 405207           h[1] = (int32_t) h1;
1292 405207           h[2] = (int32_t) h2;
1293 405207           h[3] = (int32_t) h3;
1294 405207           h[4] = (int32_t) h4;
1295 405207           h[5] = (int32_t) h5;
1296 405207           h[6] = (int32_t) h6;
1297 405207           h[7] = (int32_t) h7;
1298 405207           h[8] = (int32_t) h8;
1299 405207           h[9] = (int32_t) h9;
1300 405207           }
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 2164081           void fe_sub(fe h, const fe f, const fe g) {
1316 2164081           int32_t f0 = f[0];
1317 2164081           int32_t f1 = f[1];
1318 2164081           int32_t f2 = f[2];
1319 2164081           int32_t f3 = f[3];
1320 2164081           int32_t f4 = f[4];
1321 2164081           int32_t f5 = f[5];
1322 2164081           int32_t f6 = f[6];
1323 2164081           int32_t f7 = f[7];
1324 2164081           int32_t f8 = f[8];
1325 2164081           int32_t f9 = f[9];
1326 2164081           int32_t g0 = g[0];
1327 2164081           int32_t g1 = g[1];
1328 2164081           int32_t g2 = g[2];
1329 2164081           int32_t g3 = g[3];
1330 2164081           int32_t g4 = g[4];
1331 2164081           int32_t g5 = g[5];
1332 2164081           int32_t g6 = g[6];
1333 2164081           int32_t g7 = g[7];
1334 2164081           int32_t g8 = g[8];
1335 2164081           int32_t g9 = g[9];
1336 2164081           int32_t h0 = f0 - g0;
1337 2164081           int32_t h1 = f1 - g1;
1338 2164081           int32_t h2 = f2 - g2;
1339 2164081           int32_t h3 = f3 - g3;
1340 2164081           int32_t h4 = f4 - g4;
1341 2164081           int32_t h5 = f5 - g5;
1342 2164081           int32_t h6 = f6 - g6;
1343 2164081           int32_t h7 = f7 - g7;
1344 2164081           int32_t h8 = f8 - g8;
1345 2164081           int32_t h9 = f9 - g9;
1346              
1347 2164081           h[0] = h0;
1348 2164081           h[1] = h1;
1349 2164081           h[2] = h2;
1350 2164081           h[3] = h3;
1351 2164081           h[4] = h4;
1352 2164081           h[5] = h5;
1353 2164081           h[6] = h6;
1354 2164081           h[7] = h7;
1355 2164081           h[8] = h8;
1356 2164081           h[9] = h9;
1357 2164081           }
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 12276           void fe_tobytes(unsigned char *s, const fe h) {
1387 12276           int32_t h0 = h[0];
1388 12276           int32_t h1 = h[1];
1389 12276           int32_t h2 = h[2];
1390 12276           int32_t h3 = h[3];
1391 12276           int32_t h4 = h[4];
1392 12276           int32_t h5 = h[5];
1393 12276           int32_t h6 = h[6];
1394 12276           int32_t h7 = h[7];
1395 12276           int32_t h8 = h[8];
1396 12276           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 12276           q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
1409 12276           q = (h0 + q) >> 26;
1410 12276           q = (h1 + q) >> 25;
1411 12276           q = (h2 + q) >> 26;
1412 12276           q = (h3 + q) >> 25;
1413 12276           q = (h4 + q) >> 26;
1414 12276           q = (h5 + q) >> 25;
1415 12276           q = (h6 + q) >> 26;
1416 12276           q = (h7 + q) >> 25;
1417 12276           q = (h8 + q) >> 26;
1418 12276           q = (h9 + q) >> 25;
1419             /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
1420 12276           h0 += 19 * q;
1421             /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
1422 12276           carry0 = h0 >> 26;
1423 12276           h1 += carry0;
1424 12276           h0 -= carry0 << 26;
1425 12276           carry1 = h1 >> 25;
1426 12276           h2 += carry1;
1427 12276           h1 -= carry1 << 25;
1428 12276           carry2 = h2 >> 26;
1429 12276           h3 += carry2;
1430 12276           h2 -= carry2 << 26;
1431 12276           carry3 = h3 >> 25;
1432 12276           h4 += carry3;
1433 12276           h3 -= carry3 << 25;
1434 12276           carry4 = h4 >> 26;
1435 12276           h5 += carry4;
1436 12276           h4 -= carry4 << 26;
1437 12276           carry5 = h5 >> 25;
1438 12276           h6 += carry5;
1439 12276           h5 -= carry5 << 25;
1440 12276           carry6 = h6 >> 26;
1441 12276           h7 += carry6;
1442 12276           h6 -= carry6 << 26;
1443 12276           carry7 = h7 >> 25;
1444 12276           h8 += carry7;
1445 12276           h7 -= carry7 << 25;
1446 12276           carry8 = h8 >> 26;
1447 12276           h9 += carry8;
1448 12276           h8 -= carry8 << 26;
1449 12276           carry9 = h9 >> 25;
1450 12276           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 12276           s[0] = (unsigned char) (h0 >> 0);
1460 12276           s[1] = (unsigned char) (h0 >> 8);
1461 12276           s[2] = (unsigned char) (h0 >> 16);
1462 12276           s[3] = (unsigned char) ((h0 >> 24) | (h1 << 2));
1463 12276           s[4] = (unsigned char) (h1 >> 6);
1464 12276           s[5] = (unsigned char) (h1 >> 14);
1465 12276           s[6] = (unsigned char) ((h1 >> 22) | (h2 << 3));
1466 12276           s[7] = (unsigned char) (h2 >> 5);
1467 12276           s[8] = (unsigned char) (h2 >> 13);
1468 12276           s[9] = (unsigned char) ((h2 >> 21) | (h3 << 5));
1469 12276           s[10] = (unsigned char) (h3 >> 3);
1470 12276           s[11] = (unsigned char) (h3 >> 11);
1471 12276           s[12] = (unsigned char) ((h3 >> 19) | (h4 << 6));
1472 12276           s[13] = (unsigned char) (h4 >> 2);
1473 12276           s[14] = (unsigned char) (h4 >> 10);
1474 12276           s[15] = (unsigned char) (h4 >> 18);
1475 12276           s[16] = (unsigned char) (h5 >> 0);
1476 12276           s[17] = (unsigned char) (h5 >> 8);
1477 12276           s[18] = (unsigned char) (h5 >> 16);
1478 12276           s[19] = (unsigned char) ((h5 >> 24) | (h6 << 1));
1479 12276           s[20] = (unsigned char) (h6 >> 7);
1480 12276           s[21] = (unsigned char) (h6 >> 15);
1481 12276           s[22] = (unsigned char) ((h6 >> 23) | (h7 << 3));
1482 12276           s[23] = (unsigned char) (h7 >> 5);
1483 12276           s[24] = (unsigned char) (h7 >> 13);
1484 12276           s[25] = (unsigned char) ((h7 >> 21) | (h8 << 4));
1485 12276           s[26] = (unsigned char) (h8 >> 4);
1486 12276           s[27] = (unsigned char) (h8 >> 12);
1487 12276           s[28] = (unsigned char) ((h8 >> 20) | (h9 << 6));
1488 12276           s[29] = (unsigned char) (h9 >> 2);
1489 12276           s[30] = (unsigned char) (h9 >> 10);
1490 12276           s[31] = (unsigned char) (h9 >> 18);
1491 12276           }