1 | #include "ge.h" |
2 | |
3 | static void slide(signed char *r,const unsigned char *a) |
4 | { |
5 | int i; |
6 | int b; |
7 | int k; |
8 | |
9 | for (i = 0;i < 256;++i) |
10 | r[i] = 1 & (a[i >> 3] >> (i & 7)); |
11 | |
12 | for (i = 0;i < 256;++i) |
13 | if (r[i]) { |
14 | for (b = 1;b <= 6 && i + b < 256;++b) { |
15 | if (r[i + b]) { |
16 | if (r[i] + (r[i + b] << b) <= 15) { |
17 | r[i] += r[i + b] << b; r[i + b] = 0; |
18 | } else if (r[i] - (r[i + b] << b) >= -15) { |
19 | r[i] -= r[i + b] << b; |
20 | for (k = i + b;k < 256;++k) { |
21 | if (!r[k]) { |
22 | r[k] = 1; |
23 | break; |
24 | } |
25 | r[k] = 0; |
26 | } |
27 | } else |
28 | break; |
29 | } |
30 | } |
31 | } |
32 | |
33 | } |
34 | |
35 | static ge_precomp Bi[8] = { |
36 | #include "base2.h" |
37 | } ; |
38 | |
39 | /* |
40 | r = a * A + b * B |
41 | where a = a[0]+256*a[1]+...+256^31 a[31]. |
42 | and b = b[0]+256*b[1]+...+256^31 b[31]. |
43 | B is the Ed25519 base point (x,4/5) with x positive. |
44 | */ |
45 | |
46 | void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b) |
47 | { |
48 | signed char aslide[256]; |
49 | signed char bslide[256]; |
50 | ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ |
51 | ge_p1p1 t; |
52 | ge_p3 u; |
53 | ge_p3 A2; |
54 | int i; |
55 | |
56 | slide(aslide,a); |
57 | slide(bslide,b); |
58 | |
59 | ge_p3_to_cached(&Ai[0],A); |
60 | ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); |
61 | ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); |
62 | ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); |
63 | ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); |
64 | ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); |
65 | ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); |
66 | ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); |
67 | ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); |
68 | |
69 | ge_p2_0(r); |
70 | |
71 | for (i = 255;i >= 0;--i) { |
72 | if (aslide[i] || bslide[i]) break; |
73 | } |
74 | |
75 | for (;i >= 0;--i) { |
76 | ge_p2_dbl(&t,r); |
77 | |
78 | if (aslide[i] > 0) { |
79 | ge_p1p1_to_p3(&u,&t); |
80 | ge_add(&t,&u,&Ai[aslide[i]/2]); |
81 | } else if (aslide[i] < 0) { |
82 | ge_p1p1_to_p3(&u,&t); |
83 | ge_sub(&t,&u,&Ai[(-aslide[i])/2]); |
84 | } |
85 | |
86 | if (bslide[i] > 0) { |
87 | ge_p1p1_to_p3(&u,&t); |
88 | ge_madd(&t,&u,&Bi[bslide[i]/2]); |
89 | } else if (bslide[i] < 0) { |
90 | ge_p1p1_to_p3(&u,&t); |
91 | ge_msub(&t,&u,&Bi[(-bslide[i])/2]); |
92 | } |
93 | |
94 | ge_p1p1_to_p2(r,&t); |
95 | } |
96 | } |
97 | |