| 1 | #include "ge.h" |
| 2 | #include "crypto_uint32.h" |
| 3 | |
| 4 | static unsigned char equal(signed char b,signed char c) |
| 5 | { |
| 6 | unsigned char ub = b; |
| 7 | unsigned char uc = c; |
| 8 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ |
| 9 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ |
| 10 | y -= 1; /* 4294967295: yes; 0..254: no */ |
| 11 | y >>= 31; /* 1: yes; 0: no */ |
| 12 | return y; |
| 13 | } |
| 14 | |
| 15 | static unsigned char negative(signed char b) |
| 16 | { |
| 17 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ |
| 18 | x >>= 63; /* 1: yes; 0: no */ |
| 19 | return x; |
| 20 | } |
| 21 | |
| 22 | static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b) |
| 23 | { |
| 24 | fe_cmov(t->yplusx,u->yplusx,b); |
| 25 | fe_cmov(t->yminusx,u->yminusx,b); |
| 26 | fe_cmov(t->xy2d,u->xy2d,b); |
| 27 | } |
| 28 | |
| 29 | /* base[i][j] = (j+1)*256^i*B */ |
| 30 | static ge_precomp base[32][8] = { |
| 31 | #include "base.h" |
| 32 | } ; |
| 33 | |
| 34 | static void select(ge_precomp *t,int pos,signed char b) |
| 35 | { |
| 36 | ge_precomp minust; |
| 37 | unsigned char bnegative = negative(b); |
| 38 | unsigned char babs = b - (((-bnegative) & b) << 1); |
| 39 | |
| 40 | ge_precomp_0(t); |
| 41 | cmov(t,&base[pos][0],equal(babs,1)); |
| 42 | cmov(t,&base[pos][1],equal(babs,2)); |
| 43 | cmov(t,&base[pos][2],equal(babs,3)); |
| 44 | cmov(t,&base[pos][3],equal(babs,4)); |
| 45 | cmov(t,&base[pos][4],equal(babs,5)); |
| 46 | cmov(t,&base[pos][5],equal(babs,6)); |
| 47 | cmov(t,&base[pos][6],equal(babs,7)); |
| 48 | cmov(t,&base[pos][7],equal(babs,8)); |
| 49 | fe_copy(minust.yplusx,t->yminusx); |
| 50 | fe_copy(minust.yminusx,t->yplusx); |
| 51 | fe_neg(minust.xy2d,t->xy2d); |
| 52 | cmov(t,&minust,bnegative); |
| 53 | } |
| 54 | |
| 55 | /* |
| 56 | h = a * B |
| 57 | where a = a[0]+256*a[1]+...+256^31 a[31] |
| 58 | B is the Ed25519 base point (x,4/5) with x positive. |
| 59 | |
| 60 | Preconditions: |
| 61 | a[31] <= 127 |
| 62 | */ |
| 63 | |
| 64 | void ge_scalarmult_base(ge_p3 *h,const unsigned char *a) |
| 65 | { |
| 66 | signed char e[64]; |
| 67 | signed char carry; |
| 68 | ge_p1p1 r; |
| 69 | ge_p2 s; |
| 70 | ge_precomp t; |
| 71 | int i; |
| 72 | |
| 73 | for (i = 0;i < 32;++i) { |
| 74 | e[2 * i + 0] = (a[i] >> 0) & 15; |
| 75 | e[2 * i + 1] = (a[i] >> 4) & 15; |
| 76 | } |
| 77 | /* each e[i] is between 0 and 15 */ |
| 78 | /* e[63] is between 0 and 7 */ |
| 79 | |
| 80 | carry = 0; |
| 81 | for (i = 0;i < 63;++i) { |
| 82 | e[i] += carry; |
| 83 | carry = e[i] + 8; |
| 84 | carry >>= 4; |
| 85 | e[i] -= carry << 4; |
| 86 | } |
| 87 | e[63] += carry; |
| 88 | /* each e[i] is between -8 and 8 */ |
| 89 | |
| 90 | ge_p3_0(h); |
| 91 | for (i = 1;i < 64;i += 2) { |
| 92 | select(&t,i / 2,e[i]); |
| 93 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); |
| 94 | } |
| 95 | |
| 96 | ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r); |
| 97 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); |
| 98 | ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r); |
| 99 | ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r); |
| 100 | |
| 101 | for (i = 0;i < 64;i += 2) { |
| 102 | select(&t,i / 2,e[i]); |
| 103 | ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r); |
| 104 | } |
| 105 | } |
| 106 | |