File Coverage

ed25519/src/ge.c
Criterion Covered Total %
statement 268 269 99.6
branch 47 50 94.0
condition n/a
subroutine n/a
pod n/a
total 315 319 98.7


line stmt bran cond sub pod time code
1             #include "ge.h"
2             #include "precomp_data.h"
3              
4              
5             /*
6             r = p + q
7             */
8              
9 44610           void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
10             fe t0;
11 44610           fe_add(r->X, p->Y, p->X);
12 44610           fe_sub(r->Y, p->Y, p->X);
13 44610           fe_mul(r->Z, r->X, q->YplusX);
14 44610           fe_mul(r->Y, r->Y, q->YminusX);
15 44610           fe_mul(r->T, q->T2d, p->T);
16 44610           fe_mul(r->X, p->Z, q->Z);
17 44610           fe_add(t0, r->X, r->X);
18 44610           fe_sub(r->X, r->Z, r->Y);
19 44610           fe_add(r->Y, r->Z, r->Y);
20 44610           fe_add(r->Z, t0, r->T);
21 44610           fe_sub(r->T, t0, r->T);
22 44610           }
23              
24              
25 3128           static void slide(signed char *r, const unsigned char *a) {
26             int i;
27             int b;
28             int k;
29              
30 803896 100         for (i = 0; i < 256; ++i) {
31 800768           r[i] = 1 & (a[i >> 3] >> (i & 7));
32             }
33              
34 803896 100         for (i = 0; i < 256; ++i)
35 800768 100         if (r[i]) {
36 763239 100         for (b = 1; b <= 6 && i + b < 256; ++b) {
    100          
37 727925 100         if (r[i + b]) {
38 358239 100         if (r[i] + (r[i + b] << b) <= 15) {
39 195819           r[i] += r[i + b] << b;
40 195819           r[i + b] = 0;
41 162420 100         } else if (r[i] - (r[i + b] << b) >= -15) {
42 65166           r[i] -= r[i + b] << b;
43              
44 260866 50         for (k = i + b; k < 256; ++k) {
45 195700 100         if (!r[k]) {
46 65166           r[k] = 1;
47 65166           break;
48             }
49              
50 130534           r[k] = 0;
51             }
52             } else {
53 97254           break;
54             }
55             }
56             }
57             }
58 3128           }
59              
60             /*
61             r = a * A + b * B
62             where a = a[0]+256*a[1]+...+256^31 a[31].
63             and b = b[0]+256*b[1]+...+256^31 b[31].
64             B is the Ed25519 base point (x,4/5) with x positive.
65             */
66              
67 1564           void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) {
68             signed char aslide[256];
69             signed char bslide[256];
70             ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
71             ge_p1p1 t;
72             ge_p3 u;
73             ge_p3 A2;
74             int i;
75 1564           slide(aslide, a);
76 1564           slide(bslide, b);
77 1564           ge_p3_to_cached(&Ai[0], A);
78 1564           ge_p3_dbl(&t, A);
79 1564           ge_p1p1_to_p3(&A2, &t);
80 1564           ge_add(&t, &A2, &Ai[0]);
81 1564           ge_p1p1_to_p3(&u, &t);
82 1564           ge_p3_to_cached(&Ai[1], &u);
83 1564           ge_add(&t, &A2, &Ai[1]);
84 1564           ge_p1p1_to_p3(&u, &t);
85 1564           ge_p3_to_cached(&Ai[2], &u);
86 1564           ge_add(&t, &A2, &Ai[2]);
87 1564           ge_p1p1_to_p3(&u, &t);
88 1564           ge_p3_to_cached(&Ai[3], &u);
89 1564           ge_add(&t, &A2, &Ai[3]);
90 1564           ge_p1p1_to_p3(&u, &t);
91 1564           ge_p3_to_cached(&Ai[4], &u);
92 1564           ge_add(&t, &A2, &Ai[4]);
93 1564           ge_p1p1_to_p3(&u, &t);
94 1564           ge_p3_to_cached(&Ai[5], &u);
95 1564           ge_add(&t, &A2, &Ai[5]);
96 1564           ge_p1p1_to_p3(&u, &t);
97 1564           ge_p3_to_cached(&Ai[6], &u);
98 1564           ge_add(&t, &A2, &Ai[6]);
99 1564           ge_p1p1_to_p3(&u, &t);
100 1564           ge_p3_to_cached(&Ai[7], &u);
101 1564           ge_p2_0(r);
102              
103 8769 50         for (i = 255; i >= 0; --i) {
104 8769 100         if (aslide[i] || bslide[i]) {
    100          
105             break;
106             }
107             }
108              
109 394743 100         for (; i >= 0; --i) {
110 393179           ge_p2_dbl(&t, r);
111              
112 393179 100         if (aslide[i] > 0) {
113 33662           ge_p1p1_to_p3(&u, &t);
114 33662           ge_add(&t, &u, &Ai[aslide[i] / 2]);
115 359517 100         } else if (aslide[i] < 0) {
116 32670           ge_p1p1_to_p3(&u, &t);
117 32670           ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
118             }
119              
120 393179 100         if (bslide[i] > 0) {
121 33740           ge_p1p1_to_p3(&u, &t);
122 33740           ge_madd(&t, &u, &Bi[bslide[i] / 2]);
123 359439 100         } else if (bslide[i] < 0) {
124 32496           ge_p1p1_to_p3(&u, &t);
125 32496           ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
126             }
127              
128 393179           ge_p1p1_to_p2(r, &t);
129             }
130 1564           }
131              
132              
133             static const fe d = {
134             -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
135             };
136              
137             static const fe sqrtm1 = {
138             -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
139             };
140              
141 1564           int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) {
142             fe u;
143             fe v;
144             fe v3;
145             fe vxx;
146             fe check;
147 1564           fe_frombytes(h->Y, s);
148 1564           fe_1(h->Z);
149 1564           fe_sq(u, h->Y);
150 1564           fe_mul(v, u, d);
151 1564           fe_sub(u, u, h->Z); /* u = y^2-1 */
152 1564           fe_add(v, v, h->Z); /* v = dy^2+1 */
153 1564           fe_sq(v3, v);
154 1564           fe_mul(v3, v3, v); /* v3 = v^3 */
155 1564           fe_sq(h->X, v3);
156 1564           fe_mul(h->X, h->X, v);
157 1564           fe_mul(h->X, h->X, u); /* x = uv^7 */
158 1564           fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
159 1564           fe_mul(h->X, h->X, v3);
160 1564           fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
161 1564           fe_sq(vxx, h->X);
162 1564           fe_mul(vxx, vxx, v);
163 1564           fe_sub(check, vxx, u); /* vx^2-u */
164              
165 1564 100         if (fe_isnonzero(check)) {
166 788           fe_add(check, vxx, u); /* vx^2+u */
167              
168 788 50         if (fe_isnonzero(check)) {
169 0           return -1;
170             }
171              
172 788           fe_mul(h->X, h->X, sqrtm1);
173             }
174              
175 1564 100         if (fe_isnegative(h->X) == (s[31] >> 7)) {
176 796           fe_neg(h->X, h->X);
177             }
178              
179 1564           fe_mul(h->T, h->X, h->Y);
180 1564           return 0;
181             }
182              
183              
184             /*
185             r = p + q
186             */
187              
188 201164           void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
189             fe t0;
190 201164           fe_add(r->X, p->Y, p->X);
191 201164           fe_sub(r->Y, p->Y, p->X);
192 201164           fe_mul(r->Z, r->X, q->yplusx);
193 201164           fe_mul(r->Y, r->Y, q->yminusx);
194 201164           fe_mul(r->T, q->xy2d, p->T);
195 201164           fe_add(t0, p->Z, p->Z);
196 201164           fe_sub(r->X, r->Z, r->Y);
197 201164           fe_add(r->Y, r->Z, r->Y);
198 201164           fe_add(r->Z, t0, r->T);
199 201164           fe_sub(r->T, t0, r->T);
200 201164           }
201              
202              
203             /*
204             r = p - q
205             */
206              
207 32496           void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
208             fe t0;
209              
210 32496           fe_add(r->X, p->Y, p->X);
211 32496           fe_sub(r->Y, p->Y, p->X);
212 32496           fe_mul(r->Z, r->X, q->yminusx);
213 32496           fe_mul(r->Y, r->Y, q->yplusx);
214 32496           fe_mul(r->T, q->xy2d, p->T);
215 32496           fe_add(t0, p->Z, p->Z);
216 32496           fe_sub(r->X, r->Z, r->Y);
217 32496           fe_add(r->Y, r->Z, r->Y);
218 32496           fe_sub(r->Z, t0, r->T);
219 32496           fe_add(r->T, t0, r->T);
220 32496           }
221              
222              
223             /*
224             r = p
225             */
226              
227 401027           void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
228 401027           fe_mul(r->X, p->X, p->T);
229 401027           fe_mul(r->Y, p->Y, p->Z);
230 401027           fe_mul(r->Z, p->Z, p->T);
231 401027           }
232              
233              
234              
235             /*
236             r = p
237             */
238              
239 315120           void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
240 315120           fe_mul(r->X, p->X, p->T);
241 315120           fe_mul(r->Y, p->Y, p->Z);
242 315120           fe_mul(r->Z, p->Z, p->T);
243 315120           fe_mul(r->T, p->X, p->Y);
244 315120           }
245              
246              
247 1564           void ge_p2_0(ge_p2 *h) {
248 1564           fe_0(h->X);
249 1564           fe_1(h->Y);
250 1564           fe_1(h->Z);
251 1564           }
252              
253              
254              
255             /*
256             r = 2 * p
257             */
258              
259 405207           void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
260             fe t0;
261              
262 405207           fe_sq(r->X, p->X);
263 405207           fe_sq(r->Z, p->Y);
264 405207           fe_sq2(r->T, p->Z);
265 405207           fe_add(r->Y, p->X, p->Y);
266 405207           fe_sq(t0, r->Y);
267 405207           fe_add(r->Y, r->Z, r->X);
268 405207           fe_sub(r->Z, r->Z, r->X);
269 405207           fe_sub(r->X, t0, r->Y);
270 405207           fe_sub(r->T, r->T, r->Z);
271 405207           }
272              
273              
274 2616           void ge_p3_0(ge_p3 *h) {
275 2616           fe_0(h->X);
276 2616           fe_1(h->Y);
277 2616           fe_1(h->Z);
278 2616           fe_0(h->T);
279 2616           }
280              
281              
282             /*
283             r = 2 * p
284             */
285              
286 4180           void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
287             ge_p2 q;
288 4180           ge_p3_to_p2(&q, p);
289 4180           ge_p2_dbl(r, &q);
290 4180           }
291              
292              
293              
294             /*
295             r = p
296             */
297              
298             static const fe d2 = {
299             -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199
300             };
301              
302 12512           void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
303 12512           fe_add(r->YplusX, p->Y, p->X);
304 12512           fe_sub(r->YminusX, p->Y, p->X);
305 12512           fe_copy(r->Z, p->Z);
306 12512           fe_mul(r->T2d, p->T, d2);
307 12512           }
308              
309              
310             /*
311             r = p
312             */
313              
314 4180           void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
315 4180           fe_copy(r->X, p->X);
316 4180           fe_copy(r->Y, p->Y);
317 4180           fe_copy(r->Z, p->Z);
318 4180           }
319              
320              
321 2616           void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) {
322             fe recip;
323             fe x;
324             fe y;
325 2616           fe_invert(recip, h->Z);
326 2616           fe_mul(x, h->X, recip);
327 2616           fe_mul(y, h->Y, recip);
328 2616           fe_tobytes(s, y);
329 2616           s[31] ^= fe_isnegative(x) << 7;
330 2616           }
331              
332              
333 1339392           static unsigned char equal(signed char b, signed char c) {
334 1339392           unsigned char ub = b;
335 1339392           unsigned char uc = c;
336 1339392           unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
337 1339392           uint64_t y = x; /* 0: yes; 1..255: no */
338 1339392           y -= 1; /* large: yes; 0..254: no */
339 1339392           y >>= 63; /* 1: yes; 0: no */
340 1339392           return (unsigned char) y;
341             }
342              
343 167424           static unsigned char negative(signed char b) {
344 167424           uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
345 167424           x >>= 63; /* 1: yes; 0: no */
346 167424           return (unsigned char) x;
347             }
348              
349 1506816           static void cmov(ge_precomp *t, const ge_precomp *u, unsigned char b) {
350 1506816           fe_cmov(t->yplusx, u->yplusx, b);
351 1506816           fe_cmov(t->yminusx, u->yminusx, b);
352 1506816           fe_cmov(t->xy2d, u->xy2d, b);
353 1506816           }
354              
355              
356 167424           static void select(ge_precomp *t, int pos, signed char b) {
357             ge_precomp minust;
358 167424           unsigned char bnegative = negative(b);
359 167424           unsigned char babs = b - (((-bnegative) & b) << 1);
360 167424           fe_1(t->yplusx);
361 167424           fe_1(t->yminusx);
362 167424           fe_0(t->xy2d);
363 167424           cmov(t, &base[pos][0], equal(babs, 1));
364 167424           cmov(t, &base[pos][1], equal(babs, 2));
365 167424           cmov(t, &base[pos][2], equal(babs, 3));
366 167424           cmov(t, &base[pos][3], equal(babs, 4));
367 167424           cmov(t, &base[pos][4], equal(babs, 5));
368 167424           cmov(t, &base[pos][5], equal(babs, 6));
369 167424           cmov(t, &base[pos][6], equal(babs, 7));
370 167424           cmov(t, &base[pos][7], equal(babs, 8));
371 167424           fe_copy(minust.yplusx, t->yminusx);
372 167424           fe_copy(minust.yminusx, t->yplusx);
373 167424           fe_neg(minust.xy2d, t->xy2d);
374 167424           cmov(t, &minust, bnegative);
375 167424           }
376              
377             /*
378             h = a * B
379             where a = a[0]+256*a[1]+...+256^31 a[31]
380             B is the Ed25519 base point (x,4/5) with x positive.
381              
382             Preconditions:
383             a[31] <= 127
384             */
385              
386 2616           void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) {
387             signed char e[64];
388             signed char carry;
389             ge_p1p1 r;
390             ge_p2 s;
391             ge_precomp t;
392             int i;
393              
394 86328 100         for (i = 0; i < 32; ++i) {
395 83712           e[2 * i + 0] = (a[i] >> 0) & 15;
396 83712           e[2 * i + 1] = (a[i] >> 4) & 15;
397             }
398              
399             /* each e[i] is between 0 and 15 */
400             /* e[63] is between 0 and 7 */
401 2616           carry = 0;
402              
403 167424 100         for (i = 0; i < 63; ++i) {
404 164808           e[i] += carry;
405 164808           carry = e[i] + 8;
406 164808           carry >>= 4;
407 164808           e[i] -= carry << 4;
408             }
409              
410 2616           e[63] += carry;
411             /* each e[i] is between -8 and 8 */
412 2616           ge_p3_0(h);
413              
414 86328 100         for (i = 1; i < 64; i += 2) {
415 83712           select(&t, i / 2, e[i]);
416 83712           ge_madd(&r, h, &t);
417 83712           ge_p1p1_to_p3(h, &r);
418             }
419              
420 2616           ge_p3_dbl(&r, h);
421 2616           ge_p1p1_to_p2(&s, &r);
422 2616           ge_p2_dbl(&r, &s);
423 2616           ge_p1p1_to_p2(&s, &r);
424 2616           ge_p2_dbl(&r, &s);
425 2616           ge_p1p1_to_p2(&s, &r);
426 2616           ge_p2_dbl(&r, &s);
427 2616           ge_p1p1_to_p3(h, &r);
428              
429 86328 100         for (i = 0; i < 64; i += 2) {
430 83712           select(&t, i / 2, e[i]);
431 83712           ge_madd(&r, h, &t);
432 83712           ge_p1p1_to_p3(h, &r);
433             }
434 2616           }
435              
436              
437             /*
438             r = p - q
439             */
440              
441 32670           void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
442             fe t0;
443            
444 32670           fe_add(r->X, p->Y, p->X);
445 32670           fe_sub(r->Y, p->Y, p->X);
446 32670           fe_mul(r->Z, r->X, q->YminusX);
447 32670           fe_mul(r->Y, r->Y, q->YplusX);
448 32670           fe_mul(r->T, q->T2d, p->T);
449 32670           fe_mul(r->X, p->Z, q->Z);
450 32670           fe_add(t0, r->X, r->X);
451 32670           fe_sub(r->X, r->Z, r->Y);
452 32670           fe_add(r->Y, r->Z, r->Y);
453 32670           fe_sub(r->Z, t0, r->T);
454 32670           fe_add(r->T, t0, r->T);
455 32670           }
456              
457              
458 1564           void ge_tobytes(unsigned char *s, const ge_p2 *h) {
459             fe recip;
460             fe x;
461             fe y;
462 1564           fe_invert(recip, h->Z);
463 1564           fe_mul(x, h->X, recip);
464 1564           fe_mul(y, h->Y, recip);
465 1564           fe_tobytes(s, y);
466 1564           s[31] ^= fe_isnegative(x) << 7;
467 1564           }