ge.c 10 KB

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