ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Crypt-Ed25519/ed25519/src/ge.c
Revision: 1.2
Committed: Tue Feb 28 19:53:08 2017 UTC (9 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_04, rel-1_05, HEAD
Changes since 1.1: +1 -1 lines
Log Message:
1.04

File Contents

# User Rev Content
1 root 1.1 #include "ge.h"
2     #include "precomp_data.h"
3    
4    
5     /*
6     r = p + q
7     */
8    
9     void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
10     fe t0;
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);
22     }
23    
24    
25     static void slide(signed char *r, const unsigned char *a) {
26     int i;
27     int b;
28     int k;
29    
30     for (i = 0; i < 256; ++i) {
31     r[i] = 1 & (a[i >> 3] >> (i & 7));
32     }
33    
34     for (i = 0; i < 256; ++i)
35     if (r[i]) {
36     for (b = 1; b <= 6 && i + b < 256; ++b) {
37     if (r[i + b]) {
38     if (r[i] + (r[i + b] << b) <= 15) {
39     r[i] += r[i + b] << b;
40     r[i + b] = 0;
41     } else if (r[i] - (r[i + b] << b) >= -15) {
42     r[i] -= r[i + b] << b;
43    
44     for (k = i + b; k < 256; ++k) {
45     if (!r[k]) {
46     r[k] = 1;
47     break;
48     }
49    
50     r[k] = 0;
51     }
52     } else {
53     break;
54     }
55     }
56     }
57     }
58     }
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     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     slide(aslide, a);
76     slide(bslide, b);
77     ge_p3_to_cached(&Ai[0], A);
78     ge_p3_dbl(&t, 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);
101     ge_p2_0(r);
102    
103     for (i = 255; i >= 0; --i) {
104     if (aslide[i] || bslide[i]) {
105     break;
106     }
107     }
108    
109     for (; i >= 0; --i) {
110     ge_p2_dbl(&t, r);
111    
112     if (aslide[i] > 0) {
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]);
118     }
119    
120     if (bslide[i] > 0) {
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]);
126     }
127    
128     ge_p1p1_to_p2(r, &t);
129     }
130     }
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     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     fe_frombytes(h->Y, s);
148     fe_1(h->Z);
149     fe_sq(u, h->Y);
150     fe_mul(v, u, d);
151     fe_sub(u, u, h->Z); /* u = y^2-1 */
152     fe_add(v, v, h->Z); /* v = dy^2+1 */
153     fe_sq(v3, v);
154     fe_mul(v3, v3, v); /* v3 = v^3 */
155     fe_sq(h->X, v3);
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) */
161     fe_sq(vxx, h->X);
162     fe_mul(vxx, vxx, v);
163     fe_sub(check, vxx, u); /* vx^2-u */
164    
165     if (fe_isnonzero(check)) {
166     fe_add(check, vxx, u); /* vx^2+u */
167    
168     if (fe_isnonzero(check)) {
169     return -1;
170     }
171    
172     fe_mul(h->X, h->X, sqrtm1);
173     }
174    
175     if (fe_isnegative(h->X) == (s[31] >> 7)) {
176     fe_neg(h->X, h->X);
177     }
178    
179     fe_mul(h->T, h->X, h->Y);
180     return 0;
181     }
182    
183    
184     /*
185     r = p + q
186     */
187    
188     void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
189     fe t0;
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);
200     }
201    
202    
203     /*
204     r = p - q
205     */
206    
207     void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
208     fe t0;
209    
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);
220     }
221    
222    
223     /*
224     r = p
225     */
226    
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);
231     }
232    
233    
234    
235     /*
236     r = p
237     */
238    
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);
244     }
245    
246    
247     void ge_p2_0(ge_p2 *h) {
248     fe_0(h->X);
249     fe_1(h->Y);
250     fe_1(h->Z);
251     }
252    
253    
254    
255     /*
256     r = 2 * p
257     */
258    
259     void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
260     fe t0;
261    
262     fe_sq(r->X, p->X);
263     fe_sq(r->Z, p->Y);
264     fe_sq2(r->T, p->Z);
265     fe_add(r->Y, p->X, p->Y);
266     fe_sq(t0, r->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);
271     }
272    
273    
274     void ge_p3_0(ge_p3 *h) {
275     fe_0(h->X);
276     fe_1(h->Y);
277     fe_1(h->Z);
278     fe_0(h->T);
279     }
280    
281    
282     /*
283     r = 2 * p
284     */
285    
286     void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
287     ge_p2 q;
288     ge_p3_to_p2(&q, p);
289     ge_p2_dbl(r, &q);
290     }
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     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);
305     fe_copy(r->Z, p->Z);
306     fe_mul(r->T2d, p->T, d2);
307     }
308    
309    
310     /*
311     r = p
312     */
313    
314     void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
315     fe_copy(r->X, p->X);
316     fe_copy(r->Y, p->Y);
317     fe_copy(r->Z, p->Z);
318     }
319    
320    
321     void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) {
322     fe recip;
323     fe x;
324     fe y;
325     fe_invert(recip, h->Z);
326     fe_mul(x, h->X, recip);
327     fe_mul(y, h->Y, recip);
328     fe_tobytes(s, y);
329     s[31] ^= fe_isnegative(x) << 7;
330     }
331    
332    
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;
341     }
342    
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;
347     }
348    
349 root 1.2 static void cmov(ge_precomp *t, const ge_precomp *u, unsigned char b) {
350 root 1.1 fe_cmov(t->yplusx, u->yplusx, b);
351     fe_cmov(t->yminusx, u->yminusx, b);
352     fe_cmov(t->xy2d, u->xy2d, b);
353     }
354    
355    
356     static void select(ge_precomp *t, int pos, signed char b) {
357     ge_precomp minust;
358     unsigned char bnegative = negative(b);
359     unsigned char babs = b - (((-bnegative) & b) << 1);
360     fe_1(t->yplusx);
361     fe_1(t->yminusx);
362     fe_0(t->xy2d);
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);
375     }
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     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     for (i = 0; i < 32; ++i) {
395     e[2 * i + 0] = (a[i] >> 0) & 15;
396     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     carry = 0;
402    
403     for (i = 0; i < 63; ++i) {
404     e[i] += carry;
405     carry = e[i] + 8;
406     carry >>= 4;
407     e[i] -= carry << 4;
408     }
409    
410     e[63] += carry;
411     /* each e[i] is between -8 and 8 */
412     ge_p3_0(h);
413    
414     for (i = 1; i < 64; i += 2) {
415     select(&t, i / 2, e[i]);
416     ge_madd(&r, h, &t);
417     ge_p1p1_to_p3(h, &r);
418     }
419    
420     ge_p3_dbl(&r, h);
421     ge_p1p1_to_p2(&s, &r);
422     ge_p2_dbl(&r, &s);
423     ge_p1p1_to_p2(&s, &r);
424     ge_p2_dbl(&r, &s);
425     ge_p1p1_to_p2(&s, &r);
426     ge_p2_dbl(&r, &s);
427     ge_p1p1_to_p3(h, &r);
428    
429     for (i = 0; i < 64; i += 2) {
430     select(&t, i / 2, e[i]);
431     ge_madd(&r, h, &t);
432     ge_p1p1_to_p3(h, &r);
433     }
434     }
435    
436    
437     /*
438     r = p - q
439     */
440    
441     void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
442     fe t0;
443    
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);
455     }
456    
457    
458     void ge_tobytes(unsigned char *s, const ge_p2 *h) {
459     fe recip;
460     fe x;
461     fe y;
462     fe_invert(recip, h->Z);
463     fe_mul(x, h->X, recip);
464     fe_mul(y, h->Y, recip);
465     fe_tobytes(s, y);
466     s[31] ^= fe_isnegative(x) << 7;
467     }