2 #include "precomp_data.h"
9 void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
11 fe_add(r->X, p->Y, p->X);
12 fe_sub(r->Y, p->Y, p->X);
13 fe_mul(r->Z, r->X, q->YplusX);
14 fe_mul(r->Y, r->Y, q->YminusX);
15 fe_mul(r->T, q->T2d, p->T);
16 fe_mul(r->X, p->Z, q->Z);
17 fe_add(t0, r->X, r->X);
18 fe_sub(r->X, r->Z, r->Y);
19 fe_add(r->Y, r->Z, r->Y);
20 fe_add(r->Z, t0, r->T);
21 fe_sub(r->T, t0, r->T);
25 static void slide(signed char *r, const unsigned char *a) {
30 for(i = 0; i < 256; ++i) {
31 r[i] = 1 & (a[i >> 3] >> (i & 7));
34 for(i = 0; i < 256; ++i)
36 for(b = 1; b <= 6 && i + b < 256; ++b) {
38 if(r[i] + (r[i + b] << b) <= 15) {
39 r[i] += r[i + b] << b;
41 } else if(r[i] - (r[i + b] << b) >= -15) {
42 r[i] -= r[i + b] << b;
44 for(k = i + b; k < 256; ++k) {
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.
67 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 */
77 ge_p3_to_cached(&Ai[0], A);
79 ge_p1p1_to_p3(&A2, &t);
80 ge_add(&t, &A2, &Ai[0]);
81 ge_p1p1_to_p3(&u, &t);
82 ge_p3_to_cached(&Ai[1], &u);
83 ge_add(&t, &A2, &Ai[1]);
84 ge_p1p1_to_p3(&u, &t);
85 ge_p3_to_cached(&Ai[2], &u);
86 ge_add(&t, &A2, &Ai[2]);
87 ge_p1p1_to_p3(&u, &t);
88 ge_p3_to_cached(&Ai[3], &u);
89 ge_add(&t, &A2, &Ai[3]);
90 ge_p1p1_to_p3(&u, &t);
91 ge_p3_to_cached(&Ai[4], &u);
92 ge_add(&t, &A2, &Ai[4]);
93 ge_p1p1_to_p3(&u, &t);
94 ge_p3_to_cached(&Ai[5], &u);
95 ge_add(&t, &A2, &Ai[5]);
96 ge_p1p1_to_p3(&u, &t);
97 ge_p3_to_cached(&Ai[6], &u);
98 ge_add(&t, &A2, &Ai[6]);
99 ge_p1p1_to_p3(&u, &t);
100 ge_p3_to_cached(&Ai[7], &u);
103 for(i = 255; i >= 0; --i) {
104 if(aslide[i] || bslide[i]) {
113 ge_p1p1_to_p3(&u, &t);
114 ge_add(&t, &u, &Ai[aslide[i] / 2]);
115 } else if(aslide[i] < 0) {
116 ge_p1p1_to_p3(&u, &t);
117 ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
121 ge_p1p1_to_p3(&u, &t);
122 ge_madd(&t, &u, &Bi[bslide[i] / 2]);
123 } else if(bslide[i] < 0) {
124 ge_p1p1_to_p3(&u, &t);
125 ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
128 ge_p1p1_to_p2(r, &t);
133 static const fe d = {
134 -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
137 static const fe sqrtm1 = {
138 -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
141 int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) {
147 fe_frombytes(h->Y, s);
151 fe_sub(u, u, h->Z); /* u = y^2-1 */
152 fe_add(v, v, h->Z); /* v = dy^2+1 */
154 fe_mul(v3, v3, v); /* v3 = v^3 */
156 fe_mul(h->X, h->X, v);
157 fe_mul(h->X, h->X, u); /* x = uv^7 */
158 fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
159 fe_mul(h->X, h->X, v3);
160 fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
163 fe_sub(check, vxx, u); /* vx^2-u */
165 if(fe_isnonzero(check)) {
166 fe_add(check, vxx, u); /* vx^2+u */
168 if(fe_isnonzero(check)) {
172 fe_mul(h->X, h->X, sqrtm1);
175 if(fe_isnegative(h->X) == (s[31] >> 7)) {
179 fe_mul(h->T, h->X, h->Y);
188 void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
190 fe_add(r->X, p->Y, p->X);
191 fe_sub(r->Y, p->Y, p->X);
192 fe_mul(r->Z, r->X, q->yplusx);
193 fe_mul(r->Y, r->Y, q->yminusx);
194 fe_mul(r->T, q->xy2d, p->T);
195 fe_add(t0, p->Z, p->Z);
196 fe_sub(r->X, r->Z, r->Y);
197 fe_add(r->Y, r->Z, r->Y);
198 fe_add(r->Z, t0, r->T);
199 fe_sub(r->T, t0, r->T);
207 void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
210 fe_add(r->X, p->Y, p->X);
211 fe_sub(r->Y, p->Y, p->X);
212 fe_mul(r->Z, r->X, q->yminusx);
213 fe_mul(r->Y, r->Y, q->yplusx);
214 fe_mul(r->T, q->xy2d, p->T);
215 fe_add(t0, p->Z, p->Z);
216 fe_sub(r->X, r->Z, r->Y);
217 fe_add(r->Y, r->Z, r->Y);
218 fe_sub(r->Z, t0, r->T);
219 fe_add(r->T, t0, r->T);
227 void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
228 fe_mul(r->X, p->X, p->T);
229 fe_mul(r->Y, p->Y, p->Z);
230 fe_mul(r->Z, p->Z, p->T);
239 void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
240 fe_mul(r->X, p->X, p->T);
241 fe_mul(r->Y, p->Y, p->Z);
242 fe_mul(r->Z, p->Z, p->T);
243 fe_mul(r->T, p->X, p->Y);
247 void ge_p2_0(ge_p2 *h) {
259 void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
265 fe_add(r->Y, p->X, p->Y);
267 fe_add(r->Y, r->Z, r->X);
268 fe_sub(r->Z, r->Z, r->X);
269 fe_sub(r->X, t0, r->Y);
270 fe_sub(r->T, r->T, r->Z);
274 void ge_p3_0(ge_p3 *h) {
286 void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
298 static const fe d2 = {
299 -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199
302 void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
303 fe_add(r->YplusX, p->Y, p->X);
304 fe_sub(r->YminusX, p->Y, p->X);
306 fe_mul(r->T2d, p->T, d2);
314 void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
321 void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) {
325 fe_invert(recip, h->Z);
326 fe_mul(x, h->X, recip);
327 fe_mul(y, h->Y, recip);
329 s[31] ^= fe_isnegative(x) << 7;
333 static unsigned char equal(signed char b, signed char c) {
334 unsigned char ub = b;
335 unsigned char uc = c;
336 unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
337 uint64_t y = x; /* 0: yes; 1..255: no */
338 y -= 1; /* large: yes; 0..254: no */
339 y >>= 63; /* 1: yes; 0: no */
340 return (unsigned char) y;
343 static unsigned char negative(signed char b) {
344 uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
345 x >>= 63; /* 1: yes; 0: no */
346 return (unsigned char) x;
349 static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) {
350 fe_cmov(t->yplusx, u->yplusx, b);
351 fe_cmov(t->yminusx, u->yminusx, b);
352 fe_cmov(t->xy2d, u->xy2d, b);
356 static void select(ge_precomp *t, int pos, signed char b) {
358 unsigned char bnegative = negative(b);
359 unsigned char babs = b - shlu8(((-bnegative) & b), 1);
363 cmov(t, &base[pos][0], equal(babs, 1));
364 cmov(t, &base[pos][1], equal(babs, 2));
365 cmov(t, &base[pos][2], equal(babs, 3));
366 cmov(t, &base[pos][3], equal(babs, 4));
367 cmov(t, &base[pos][4], equal(babs, 5));
368 cmov(t, &base[pos][5], equal(babs, 6));
369 cmov(t, &base[pos][6], equal(babs, 7));
370 cmov(t, &base[pos][7], equal(babs, 8));
371 fe_copy(minust.yplusx, t->yminusx);
372 fe_copy(minust.yminusx, t->yplusx);
373 fe_neg(minust.xy2d, t->xy2d);
374 cmov(t, &minust, bnegative);
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.
386 void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) {
394 for(i = 0; i < 32; ++i) {
395 e[2 * i + 0] = (a[i] >> 0) & 15;
396 e[2 * i + 1] = (a[i] >> 4) & 15;
399 /* each e[i] is between 0 and 15 */
400 /* e[63] is between 0 and 7 */
403 for(i = 0; i < 63; ++i) {
407 e[i] -= shl32(carry, 4);
411 /* each e[i] is between -8 and 8 */
414 for(i = 1; i < 64; i += 2) {
415 select(&t, i / 2, e[i]);
417 ge_p1p1_to_p3(h, &r);
421 ge_p1p1_to_p2(&s, &r);
423 ge_p1p1_to_p2(&s, &r);
425 ge_p1p1_to_p2(&s, &r);
427 ge_p1p1_to_p3(h, &r);
429 for(i = 0; i < 64; i += 2) {
430 select(&t, i / 2, e[i]);
432 ge_p1p1_to_p3(h, &r);
441 void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
444 fe_add(r->X, p->Y, p->X);
445 fe_sub(r->Y, p->Y, p->X);
446 fe_mul(r->Z, r->X, q->YminusX);
447 fe_mul(r->Y, r->Y, q->YplusX);
448 fe_mul(r->T, q->T2d, p->T);
449 fe_mul(r->X, p->Z, q->Z);
450 fe_add(t0, r->X, r->X);
451 fe_sub(r->X, r->Z, r->Y);
452 fe_add(r->Y, r->Z, r->Y);
453 fe_sub(r->Z, t0, r->T);
454 fe_add(r->T, t0, r->T);
458 void ge_tobytes(unsigned char *s, const ge_p2 *h) {
462 fe_invert(recip, h->Z);
463 fe_mul(x, h->X, recip);
464 fe_mul(y, h->Y, recip);
466 s[31] ^= fe_isnegative(x) << 7;