ec.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506
  1. /* ec.c - Elliptic Curve functions
  2. * Copyright (C) 2007 Free Software Foundation, Inc.
  3. * Copyright (C) 2013 g10 Code GmbH
  4. *
  5. * This file is part of Libgcrypt.
  6. *
  7. * Libgcrypt is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * Libgcrypt is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "mpi-internal.h"
  21. #include "longlong.h"
  22. #define point_init(a) mpi_point_init((a))
  23. #define point_free(a) mpi_point_free_parts((a))
  24. #define log_error(fmt, ...) pr_err(fmt, ##__VA_ARGS__)
  25. #define log_fatal(fmt, ...) pr_err(fmt, ##__VA_ARGS__)
  26. #define DIM(v) (sizeof(v)/sizeof((v)[0]))
  27. /* Create a new point option. NBITS gives the size in bits of one
  28. * coordinate; it is only used to pre-allocate some resources and
  29. * might also be passed as 0 to use a default value.
  30. */
  31. MPI_POINT mpi_point_new(unsigned int nbits)
  32. {
  33. MPI_POINT p;
  34. (void)nbits; /* Currently not used. */
  35. p = kmalloc(sizeof(*p), GFP_KERNEL);
  36. if (p)
  37. mpi_point_init(p);
  38. return p;
  39. }
  40. EXPORT_SYMBOL_GPL(mpi_point_new);
  41. /* Release the point object P. P may be NULL. */
  42. void mpi_point_release(MPI_POINT p)
  43. {
  44. if (p) {
  45. mpi_point_free_parts(p);
  46. kfree(p);
  47. }
  48. }
  49. EXPORT_SYMBOL_GPL(mpi_point_release);
  50. /* Initialize the fields of a point object. gcry_mpi_point_free_parts
  51. * may be used to release the fields.
  52. */
  53. void mpi_point_init(MPI_POINT p)
  54. {
  55. p->x = mpi_new(0);
  56. p->y = mpi_new(0);
  57. p->z = mpi_new(0);
  58. }
  59. EXPORT_SYMBOL_GPL(mpi_point_init);
  60. /* Release the parts of a point object. */
  61. void mpi_point_free_parts(MPI_POINT p)
  62. {
  63. mpi_free(p->x); p->x = NULL;
  64. mpi_free(p->y); p->y = NULL;
  65. mpi_free(p->z); p->z = NULL;
  66. }
  67. EXPORT_SYMBOL_GPL(mpi_point_free_parts);
  68. /* Set the value from S into D. */
  69. static void point_set(MPI_POINT d, MPI_POINT s)
  70. {
  71. mpi_set(d->x, s->x);
  72. mpi_set(d->y, s->y);
  73. mpi_set(d->z, s->z);
  74. }
  75. static void point_resize(MPI_POINT p, struct mpi_ec_ctx *ctx)
  76. {
  77. size_t nlimbs = ctx->p->nlimbs;
  78. mpi_resize(p->x, nlimbs);
  79. p->x->nlimbs = nlimbs;
  80. mpi_resize(p->z, nlimbs);
  81. p->z->nlimbs = nlimbs;
  82. if (ctx->model != MPI_EC_MONTGOMERY) {
  83. mpi_resize(p->y, nlimbs);
  84. p->y->nlimbs = nlimbs;
  85. }
  86. }
  87. static void point_swap_cond(MPI_POINT d, MPI_POINT s, unsigned long swap,
  88. struct mpi_ec_ctx *ctx)
  89. {
  90. mpi_swap_cond(d->x, s->x, swap);
  91. if (ctx->model != MPI_EC_MONTGOMERY)
  92. mpi_swap_cond(d->y, s->y, swap);
  93. mpi_swap_cond(d->z, s->z, swap);
  94. }
  95. /* W = W mod P. */
  96. static void ec_mod(MPI w, struct mpi_ec_ctx *ec)
  97. {
  98. if (ec->t.p_barrett)
  99. mpi_mod_barrett(w, w, ec->t.p_barrett);
  100. else
  101. mpi_mod(w, w, ec->p);
  102. }
  103. static void ec_addm(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  104. {
  105. mpi_add(w, u, v);
  106. ec_mod(w, ctx);
  107. }
  108. static void ec_subm(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ec)
  109. {
  110. mpi_sub(w, u, v);
  111. while (w->sign)
  112. mpi_add(w, w, ec->p);
  113. /*ec_mod(w, ec);*/
  114. }
  115. static void ec_mulm(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  116. {
  117. mpi_mul(w, u, v);
  118. ec_mod(w, ctx);
  119. }
  120. /* W = 2 * U mod P. */
  121. static void ec_mul2(MPI w, MPI u, struct mpi_ec_ctx *ctx)
  122. {
  123. mpi_lshift(w, u, 1);
  124. ec_mod(w, ctx);
  125. }
  126. static void ec_powm(MPI w, const MPI b, const MPI e,
  127. struct mpi_ec_ctx *ctx)
  128. {
  129. mpi_powm(w, b, e, ctx->p);
  130. /* mpi_abs(w); */
  131. }
  132. /* Shortcut for
  133. * ec_powm(B, B, mpi_const(MPI_C_TWO), ctx);
  134. * for easier optimization.
  135. */
  136. static void ec_pow2(MPI w, const MPI b, struct mpi_ec_ctx *ctx)
  137. {
  138. /* Using mpi_mul is slightly faster (at least on amd64). */
  139. /* mpi_powm(w, b, mpi_const(MPI_C_TWO), ctx->p); */
  140. ec_mulm(w, b, b, ctx);
  141. }
  142. /* Shortcut for
  143. * ec_powm(B, B, mpi_const(MPI_C_THREE), ctx);
  144. * for easier optimization.
  145. */
  146. static void ec_pow3(MPI w, const MPI b, struct mpi_ec_ctx *ctx)
  147. {
  148. mpi_powm(w, b, mpi_const(MPI_C_THREE), ctx->p);
  149. }
  150. static void ec_invm(MPI x, MPI a, struct mpi_ec_ctx *ctx)
  151. {
  152. if (!mpi_invm(x, a, ctx->p))
  153. log_error("ec_invm: inverse does not exist:\n");
  154. }
  155. static void mpih_set_cond(mpi_ptr_t wp, mpi_ptr_t up,
  156. mpi_size_t usize, unsigned long set)
  157. {
  158. mpi_size_t i;
  159. mpi_limb_t mask = ((mpi_limb_t)0) - set;
  160. mpi_limb_t x;
  161. for (i = 0; i < usize; i++) {
  162. x = mask & (wp[i] ^ up[i]);
  163. wp[i] = wp[i] ^ x;
  164. }
  165. }
  166. /* Routines for 2^255 - 19. */
  167. #define LIMB_SIZE_25519 ((256+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB)
  168. static void ec_addm_25519(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  169. {
  170. mpi_ptr_t wp, up, vp;
  171. mpi_size_t wsize = LIMB_SIZE_25519;
  172. mpi_limb_t n[LIMB_SIZE_25519];
  173. mpi_limb_t borrow;
  174. if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
  175. log_bug("addm_25519: different sizes\n");
  176. memset(n, 0, sizeof(n));
  177. up = u->d;
  178. vp = v->d;
  179. wp = w->d;
  180. mpihelp_add_n(wp, up, vp, wsize);
  181. borrow = mpihelp_sub_n(wp, wp, ctx->p->d, wsize);
  182. mpih_set_cond(n, ctx->p->d, wsize, (borrow != 0UL));
  183. mpihelp_add_n(wp, wp, n, wsize);
  184. wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
  185. }
  186. static void ec_subm_25519(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  187. {
  188. mpi_ptr_t wp, up, vp;
  189. mpi_size_t wsize = LIMB_SIZE_25519;
  190. mpi_limb_t n[LIMB_SIZE_25519];
  191. mpi_limb_t borrow;
  192. if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
  193. log_bug("subm_25519: different sizes\n");
  194. memset(n, 0, sizeof(n));
  195. up = u->d;
  196. vp = v->d;
  197. wp = w->d;
  198. borrow = mpihelp_sub_n(wp, up, vp, wsize);
  199. mpih_set_cond(n, ctx->p->d, wsize, (borrow != 0UL));
  200. mpihelp_add_n(wp, wp, n, wsize);
  201. wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
  202. }
  203. static void ec_mulm_25519(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  204. {
  205. mpi_ptr_t wp, up, vp;
  206. mpi_size_t wsize = LIMB_SIZE_25519;
  207. mpi_limb_t n[LIMB_SIZE_25519*2];
  208. mpi_limb_t m[LIMB_SIZE_25519+1];
  209. mpi_limb_t cy;
  210. int msb;
  211. (void)ctx;
  212. if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
  213. log_bug("mulm_25519: different sizes\n");
  214. up = u->d;
  215. vp = v->d;
  216. wp = w->d;
  217. mpihelp_mul_n(n, up, vp, wsize);
  218. memcpy(wp, n, wsize * BYTES_PER_MPI_LIMB);
  219. wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
  220. memcpy(m, n+LIMB_SIZE_25519-1, (wsize+1) * BYTES_PER_MPI_LIMB);
  221. mpihelp_rshift(m, m, LIMB_SIZE_25519+1, (255 % BITS_PER_MPI_LIMB));
  222. memcpy(n, m, wsize * BYTES_PER_MPI_LIMB);
  223. cy = mpihelp_lshift(m, m, LIMB_SIZE_25519, 4);
  224. m[LIMB_SIZE_25519] = cy;
  225. cy = mpihelp_add_n(m, m, n, wsize);
  226. m[LIMB_SIZE_25519] += cy;
  227. cy = mpihelp_add_n(m, m, n, wsize);
  228. m[LIMB_SIZE_25519] += cy;
  229. cy = mpihelp_add_n(m, m, n, wsize);
  230. m[LIMB_SIZE_25519] += cy;
  231. cy = mpihelp_add_n(wp, wp, m, wsize);
  232. m[LIMB_SIZE_25519] += cy;
  233. memset(m, 0, wsize * BYTES_PER_MPI_LIMB);
  234. msb = (wp[LIMB_SIZE_25519-1] >> (255 % BITS_PER_MPI_LIMB));
  235. m[0] = (m[LIMB_SIZE_25519] * 2 + msb) * 19;
  236. wp[LIMB_SIZE_25519-1] &= ~((mpi_limb_t)1 << (255 % BITS_PER_MPI_LIMB));
  237. mpihelp_add_n(wp, wp, m, wsize);
  238. m[0] = 0;
  239. cy = mpihelp_sub_n(wp, wp, ctx->p->d, wsize);
  240. mpih_set_cond(m, ctx->p->d, wsize, (cy != 0UL));
  241. mpihelp_add_n(wp, wp, m, wsize);
  242. }
  243. static void ec_mul2_25519(MPI w, MPI u, struct mpi_ec_ctx *ctx)
  244. {
  245. ec_addm_25519(w, u, u, ctx);
  246. }
  247. static void ec_pow2_25519(MPI w, const MPI b, struct mpi_ec_ctx *ctx)
  248. {
  249. ec_mulm_25519(w, b, b, ctx);
  250. }
  251. /* Routines for 2^448 - 2^224 - 1. */
  252. #define LIMB_SIZE_448 ((448+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB)
  253. #define LIMB_SIZE_HALF_448 ((LIMB_SIZE_448+1)/2)
  254. static void ec_addm_448(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  255. {
  256. mpi_ptr_t wp, up, vp;
  257. mpi_size_t wsize = LIMB_SIZE_448;
  258. mpi_limb_t n[LIMB_SIZE_448];
  259. mpi_limb_t cy;
  260. if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
  261. log_bug("addm_448: different sizes\n");
  262. memset(n, 0, sizeof(n));
  263. up = u->d;
  264. vp = v->d;
  265. wp = w->d;
  266. cy = mpihelp_add_n(wp, up, vp, wsize);
  267. mpih_set_cond(n, ctx->p->d, wsize, (cy != 0UL));
  268. mpihelp_sub_n(wp, wp, n, wsize);
  269. }
  270. static void ec_subm_448(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  271. {
  272. mpi_ptr_t wp, up, vp;
  273. mpi_size_t wsize = LIMB_SIZE_448;
  274. mpi_limb_t n[LIMB_SIZE_448];
  275. mpi_limb_t borrow;
  276. if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
  277. log_bug("subm_448: different sizes\n");
  278. memset(n, 0, sizeof(n));
  279. up = u->d;
  280. vp = v->d;
  281. wp = w->d;
  282. borrow = mpihelp_sub_n(wp, up, vp, wsize);
  283. mpih_set_cond(n, ctx->p->d, wsize, (borrow != 0UL));
  284. mpihelp_add_n(wp, wp, n, wsize);
  285. }
  286. static void ec_mulm_448(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx)
  287. {
  288. mpi_ptr_t wp, up, vp;
  289. mpi_size_t wsize = LIMB_SIZE_448;
  290. mpi_limb_t n[LIMB_SIZE_448*2];
  291. mpi_limb_t a2[LIMB_SIZE_HALF_448];
  292. mpi_limb_t a3[LIMB_SIZE_HALF_448];
  293. mpi_limb_t b0[LIMB_SIZE_HALF_448];
  294. mpi_limb_t b1[LIMB_SIZE_HALF_448];
  295. mpi_limb_t cy;
  296. int i;
  297. #if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
  298. mpi_limb_t b1_rest, a3_rest;
  299. #endif
  300. if (w->nlimbs != wsize || u->nlimbs != wsize || v->nlimbs != wsize)
  301. log_bug("mulm_448: different sizes\n");
  302. up = u->d;
  303. vp = v->d;
  304. wp = w->d;
  305. mpihelp_mul_n(n, up, vp, wsize);
  306. for (i = 0; i < (wsize + 1) / 2; i++) {
  307. b0[i] = n[i];
  308. b1[i] = n[i+wsize/2];
  309. a2[i] = n[i+wsize];
  310. a3[i] = n[i+wsize+wsize/2];
  311. }
  312. #if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
  313. b0[LIMB_SIZE_HALF_448-1] &= ((mpi_limb_t)1UL << 32)-1;
  314. a2[LIMB_SIZE_HALF_448-1] &= ((mpi_limb_t)1UL << 32)-1;
  315. b1_rest = 0;
  316. a3_rest = 0;
  317. for (i = (wsize + 1) / 2 - 1; i >= 0; i--) {
  318. mpi_limb_t b1v, a3v;
  319. b1v = b1[i];
  320. a3v = a3[i];
  321. b1[i] = (b1_rest << 32) | (b1v >> 32);
  322. a3[i] = (a3_rest << 32) | (a3v >> 32);
  323. b1_rest = b1v & (((mpi_limb_t)1UL << 32)-1);
  324. a3_rest = a3v & (((mpi_limb_t)1UL << 32)-1);
  325. }
  326. #endif
  327. cy = mpihelp_add_n(b0, b0, a2, LIMB_SIZE_HALF_448);
  328. cy += mpihelp_add_n(b0, b0, a3, LIMB_SIZE_HALF_448);
  329. for (i = 0; i < (wsize + 1) / 2; i++)
  330. wp[i] = b0[i];
  331. #if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
  332. wp[LIMB_SIZE_HALF_448-1] &= (((mpi_limb_t)1UL << 32)-1);
  333. #endif
  334. #if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
  335. cy = b0[LIMB_SIZE_HALF_448-1] >> 32;
  336. #endif
  337. cy = mpihelp_add_1(b1, b1, LIMB_SIZE_HALF_448, cy);
  338. cy += mpihelp_add_n(b1, b1, a2, LIMB_SIZE_HALF_448);
  339. cy += mpihelp_add_n(b1, b1, a3, LIMB_SIZE_HALF_448);
  340. cy += mpihelp_add_n(b1, b1, a3, LIMB_SIZE_HALF_448);
  341. #if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
  342. b1_rest = 0;
  343. for (i = (wsize + 1) / 2 - 1; i >= 0; i--) {
  344. mpi_limb_t b1v = b1[i];
  345. b1[i] = (b1_rest << 32) | (b1v >> 32);
  346. b1_rest = b1v & (((mpi_limb_t)1UL << 32)-1);
  347. }
  348. wp[LIMB_SIZE_HALF_448-1] |= (b1_rest << 32);
  349. #endif
  350. for (i = 0; i < wsize / 2; i++)
  351. wp[i+(wsize + 1) / 2] = b1[i];
  352. #if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
  353. cy = b1[LIMB_SIZE_HALF_448-1];
  354. #endif
  355. memset(n, 0, wsize * BYTES_PER_MPI_LIMB);
  356. #if (LIMB_SIZE_HALF_448 > LIMB_SIZE_448/2)
  357. n[LIMB_SIZE_HALF_448-1] = cy << 32;
  358. #else
  359. n[LIMB_SIZE_HALF_448] = cy;
  360. #endif
  361. n[0] = cy;
  362. mpihelp_add_n(wp, wp, n, wsize);
  363. memset(n, 0, wsize * BYTES_PER_MPI_LIMB);
  364. cy = mpihelp_sub_n(wp, wp, ctx->p->d, wsize);
  365. mpih_set_cond(n, ctx->p->d, wsize, (cy != 0UL));
  366. mpihelp_add_n(wp, wp, n, wsize);
  367. }
  368. static void ec_mul2_448(MPI w, MPI u, struct mpi_ec_ctx *ctx)
  369. {
  370. ec_addm_448(w, u, u, ctx);
  371. }
  372. static void ec_pow2_448(MPI w, const MPI b, struct mpi_ec_ctx *ctx)
  373. {
  374. ec_mulm_448(w, b, b, ctx);
  375. }
  376. struct field_table {
  377. const char *p;
  378. /* computation routines for the field. */
  379. void (*addm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx);
  380. void (*subm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx);
  381. void (*mulm)(MPI w, MPI u, MPI v, struct mpi_ec_ctx *ctx);
  382. void (*mul2)(MPI w, MPI u, struct mpi_ec_ctx *ctx);
  383. void (*pow2)(MPI w, const MPI b, struct mpi_ec_ctx *ctx);
  384. };
  385. static const struct field_table field_table[] = {
  386. {
  387. "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
  388. ec_addm_25519,
  389. ec_subm_25519,
  390. ec_mulm_25519,
  391. ec_mul2_25519,
  392. ec_pow2_25519
  393. },
  394. {
  395. "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
  396. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
  397. ec_addm_448,
  398. ec_subm_448,
  399. ec_mulm_448,
  400. ec_mul2_448,
  401. ec_pow2_448
  402. },
  403. { NULL, NULL, NULL, NULL, NULL, NULL },
  404. };
  405. /* Force recomputation of all helper variables. */
  406. static void mpi_ec_get_reset(struct mpi_ec_ctx *ec)
  407. {
  408. ec->t.valid.a_is_pminus3 = 0;
  409. ec->t.valid.two_inv_p = 0;
  410. }
  411. /* Accessor for helper variable. */
  412. static int ec_get_a_is_pminus3(struct mpi_ec_ctx *ec)
  413. {
  414. MPI tmp;
  415. if (!ec->t.valid.a_is_pminus3) {
  416. ec->t.valid.a_is_pminus3 = 1;
  417. tmp = mpi_alloc_like(ec->p);
  418. mpi_sub_ui(tmp, ec->p, 3);
  419. ec->t.a_is_pminus3 = !mpi_cmp(ec->a, tmp);
  420. mpi_free(tmp);
  421. }
  422. return ec->t.a_is_pminus3;
  423. }
  424. /* Accessor for helper variable. */
  425. static MPI ec_get_two_inv_p(struct mpi_ec_ctx *ec)
  426. {
  427. if (!ec->t.valid.two_inv_p) {
  428. ec->t.valid.two_inv_p = 1;
  429. if (!ec->t.two_inv_p)
  430. ec->t.two_inv_p = mpi_alloc(0);
  431. ec_invm(ec->t.two_inv_p, mpi_const(MPI_C_TWO), ec);
  432. }
  433. return ec->t.two_inv_p;
  434. }
  435. static const char *const curve25519_bad_points[] = {
  436. "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",
  437. "0x0000000000000000000000000000000000000000000000000000000000000000",
  438. "0x0000000000000000000000000000000000000000000000000000000000000001",
  439. "0x00b8495f16056286fdb1329ceb8d09da6ac49ff1fae35616aeb8413b7c7aebe0",
  440. "0x57119fd0dd4e22d8868e1c58c45c44045bef839c55b1d0b1248c50a3bc959c5f",
  441. "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec",
  442. "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee",
  443. NULL
  444. };
  445. static const char *const curve448_bad_points[] = {
  446. "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  447. "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  448. "0x00000000000000000000000000000000000000000000000000000000"
  449. "00000000000000000000000000000000000000000000000000000000",
  450. "0x00000000000000000000000000000000000000000000000000000000"
  451. "00000000000000000000000000000000000000000000000000000001",
  452. "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
  453. "fffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
  454. "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
  455. "00000000000000000000000000000000000000000000000000000000",
  456. NULL
  457. };
  458. static const char *const *bad_points_table[] = {
  459. curve25519_bad_points,
  460. curve448_bad_points,
  461. };
  462. static void mpi_ec_coefficient_normalize(MPI a, MPI p)
  463. {
  464. if (a->sign) {
  465. mpi_resize(a, p->nlimbs);
  466. mpihelp_sub_n(a->d, p->d, a->d, p->nlimbs);
  467. a->nlimbs = p->nlimbs;
  468. a->sign = 0;
  469. }
  470. }
  471. /* This function initialized a context for elliptic curve based on the
  472. * field GF(p). P is the prime specifying this field, A is the first
  473. * coefficient. CTX is expected to be zeroized.
  474. */
  475. void mpi_ec_init(struct mpi_ec_ctx *ctx, enum gcry_mpi_ec_models model,
  476. enum ecc_dialects dialect,
  477. int flags, MPI p, MPI a, MPI b)
  478. {
  479. int i;
  480. static int use_barrett = -1 /* TODO: 1 or -1 */;
  481. mpi_ec_coefficient_normalize(a, p);
  482. mpi_ec_coefficient_normalize(b, p);
  483. /* Fixme: Do we want to check some constraints? e.g. a < p */
  484. ctx->model = model;
  485. ctx->dialect = dialect;
  486. ctx->flags = flags;
  487. if (dialect == ECC_DIALECT_ED25519)
  488. ctx->nbits = 256;
  489. else
  490. ctx->nbits = mpi_get_nbits(p);
  491. ctx->p = mpi_copy(p);
  492. ctx->a = mpi_copy(a);
  493. ctx->b = mpi_copy(b);
  494. ctx->t.p_barrett = use_barrett > 0 ? mpi_barrett_init(ctx->p, 0) : NULL;
  495. mpi_ec_get_reset(ctx);
  496. if (model == MPI_EC_MONTGOMERY) {
  497. for (i = 0; i < DIM(bad_points_table); i++) {
  498. MPI p_candidate = mpi_scanval(bad_points_table[i][0]);
  499. int match_p = !mpi_cmp(ctx->p, p_candidate);
  500. int j;
  501. mpi_free(p_candidate);
  502. if (!match_p)
  503. continue;
  504. for (j = 0; i < DIM(ctx->t.scratch) && bad_points_table[i][j]; j++)
  505. ctx->t.scratch[j] = mpi_scanval(bad_points_table[i][j]);
  506. }
  507. } else {
  508. /* Allocate scratch variables. */
  509. for (i = 0; i < DIM(ctx->t.scratch); i++)
  510. ctx->t.scratch[i] = mpi_alloc_like(ctx->p);
  511. }
  512. ctx->addm = ec_addm;
  513. ctx->subm = ec_subm;
  514. ctx->mulm = ec_mulm;
  515. ctx->mul2 = ec_mul2;
  516. ctx->pow2 = ec_pow2;
  517. for (i = 0; field_table[i].p; i++) {
  518. MPI f_p;
  519. f_p = mpi_scanval(field_table[i].p);
  520. if (!f_p)
  521. break;
  522. if (!mpi_cmp(p, f_p)) {
  523. ctx->addm = field_table[i].addm;
  524. ctx->subm = field_table[i].subm;
  525. ctx->mulm = field_table[i].mulm;
  526. ctx->mul2 = field_table[i].mul2;
  527. ctx->pow2 = field_table[i].pow2;
  528. mpi_free(f_p);
  529. mpi_resize(ctx->a, ctx->p->nlimbs);
  530. ctx->a->nlimbs = ctx->p->nlimbs;
  531. mpi_resize(ctx->b, ctx->p->nlimbs);
  532. ctx->b->nlimbs = ctx->p->nlimbs;
  533. for (i = 0; i < DIM(ctx->t.scratch) && ctx->t.scratch[i]; i++)
  534. ctx->t.scratch[i]->nlimbs = ctx->p->nlimbs;
  535. break;
  536. }
  537. mpi_free(f_p);
  538. }
  539. }
  540. EXPORT_SYMBOL_GPL(mpi_ec_init);
  541. void mpi_ec_deinit(struct mpi_ec_ctx *ctx)
  542. {
  543. int i;
  544. mpi_barrett_free(ctx->t.p_barrett);
  545. /* Domain parameter. */
  546. mpi_free(ctx->p);
  547. mpi_free(ctx->a);
  548. mpi_free(ctx->b);
  549. mpi_point_release(ctx->G);
  550. mpi_free(ctx->n);
  551. /* The key. */
  552. mpi_point_release(ctx->Q);
  553. mpi_free(ctx->d);
  554. /* Private data of ec.c. */
  555. mpi_free(ctx->t.two_inv_p);
  556. for (i = 0; i < DIM(ctx->t.scratch); i++)
  557. mpi_free(ctx->t.scratch[i]);
  558. }
  559. EXPORT_SYMBOL_GPL(mpi_ec_deinit);
  560. /* Compute the affine coordinates from the projective coordinates in
  561. * POINT. Set them into X and Y. If one coordinate is not required,
  562. * X or Y may be passed as NULL. CTX is the usual context. Returns: 0
  563. * on success or !0 if POINT is at infinity.
  564. */
  565. int mpi_ec_get_affine(MPI x, MPI y, MPI_POINT point, struct mpi_ec_ctx *ctx)
  566. {
  567. if (!mpi_cmp_ui(point->z, 0))
  568. return -1;
  569. switch (ctx->model) {
  570. case MPI_EC_WEIERSTRASS: /* Using Jacobian coordinates. */
  571. {
  572. MPI z1, z2, z3;
  573. z1 = mpi_new(0);
  574. z2 = mpi_new(0);
  575. ec_invm(z1, point->z, ctx); /* z1 = z^(-1) mod p */
  576. ec_mulm(z2, z1, z1, ctx); /* z2 = z^(-2) mod p */
  577. if (x)
  578. ec_mulm(x, point->x, z2, ctx);
  579. if (y) {
  580. z3 = mpi_new(0);
  581. ec_mulm(z3, z2, z1, ctx); /* z3 = z^(-3) mod p */
  582. ec_mulm(y, point->y, z3, ctx);
  583. mpi_free(z3);
  584. }
  585. mpi_free(z2);
  586. mpi_free(z1);
  587. }
  588. return 0;
  589. case MPI_EC_MONTGOMERY:
  590. {
  591. if (x)
  592. mpi_set(x, point->x);
  593. if (y) {
  594. log_fatal("%s: Getting Y-coordinate on %s is not supported\n",
  595. "mpi_ec_get_affine", "Montgomery");
  596. return -1;
  597. }
  598. }
  599. return 0;
  600. case MPI_EC_EDWARDS:
  601. {
  602. MPI z;
  603. z = mpi_new(0);
  604. ec_invm(z, point->z, ctx);
  605. mpi_resize(z, ctx->p->nlimbs);
  606. z->nlimbs = ctx->p->nlimbs;
  607. if (x) {
  608. mpi_resize(x, ctx->p->nlimbs);
  609. x->nlimbs = ctx->p->nlimbs;
  610. ctx->mulm(x, point->x, z, ctx);
  611. }
  612. if (y) {
  613. mpi_resize(y, ctx->p->nlimbs);
  614. y->nlimbs = ctx->p->nlimbs;
  615. ctx->mulm(y, point->y, z, ctx);
  616. }
  617. mpi_free(z);
  618. }
  619. return 0;
  620. default:
  621. return -1;
  622. }
  623. }
  624. EXPORT_SYMBOL_GPL(mpi_ec_get_affine);
  625. /* RESULT = 2 * POINT (Weierstrass version). */
  626. static void dup_point_weierstrass(MPI_POINT result,
  627. MPI_POINT point, struct mpi_ec_ctx *ctx)
  628. {
  629. #define x3 (result->x)
  630. #define y3 (result->y)
  631. #define z3 (result->z)
  632. #define t1 (ctx->t.scratch[0])
  633. #define t2 (ctx->t.scratch[1])
  634. #define t3 (ctx->t.scratch[2])
  635. #define l1 (ctx->t.scratch[3])
  636. #define l2 (ctx->t.scratch[4])
  637. #define l3 (ctx->t.scratch[5])
  638. if (!mpi_cmp_ui(point->y, 0) || !mpi_cmp_ui(point->z, 0)) {
  639. /* P_y == 0 || P_z == 0 => [1:1:0] */
  640. mpi_set_ui(x3, 1);
  641. mpi_set_ui(y3, 1);
  642. mpi_set_ui(z3, 0);
  643. } else {
  644. if (ec_get_a_is_pminus3(ctx)) {
  645. /* Use the faster case. */
  646. /* L1 = 3(X - Z^2)(X + Z^2) */
  647. /* T1: used for Z^2. */
  648. /* T2: used for the right term. */
  649. ec_pow2(t1, point->z, ctx);
  650. ec_subm(l1, point->x, t1, ctx);
  651. ec_mulm(l1, l1, mpi_const(MPI_C_THREE), ctx);
  652. ec_addm(t2, point->x, t1, ctx);
  653. ec_mulm(l1, l1, t2, ctx);
  654. } else {
  655. /* Standard case. */
  656. /* L1 = 3X^2 + aZ^4 */
  657. /* T1: used for aZ^4. */
  658. ec_pow2(l1, point->x, ctx);
  659. ec_mulm(l1, l1, mpi_const(MPI_C_THREE), ctx);
  660. ec_powm(t1, point->z, mpi_const(MPI_C_FOUR), ctx);
  661. ec_mulm(t1, t1, ctx->a, ctx);
  662. ec_addm(l1, l1, t1, ctx);
  663. }
  664. /* Z3 = 2YZ */
  665. ec_mulm(z3, point->y, point->z, ctx);
  666. ec_mul2(z3, z3, ctx);
  667. /* L2 = 4XY^2 */
  668. /* T2: used for Y2; required later. */
  669. ec_pow2(t2, point->y, ctx);
  670. ec_mulm(l2, t2, point->x, ctx);
  671. ec_mulm(l2, l2, mpi_const(MPI_C_FOUR), ctx);
  672. /* X3 = L1^2 - 2L2 */
  673. /* T1: used for L2^2. */
  674. ec_pow2(x3, l1, ctx);
  675. ec_mul2(t1, l2, ctx);
  676. ec_subm(x3, x3, t1, ctx);
  677. /* L3 = 8Y^4 */
  678. /* T2: taken from above. */
  679. ec_pow2(t2, t2, ctx);
  680. ec_mulm(l3, t2, mpi_const(MPI_C_EIGHT), ctx);
  681. /* Y3 = L1(L2 - X3) - L3 */
  682. ec_subm(y3, l2, x3, ctx);
  683. ec_mulm(y3, y3, l1, ctx);
  684. ec_subm(y3, y3, l3, ctx);
  685. }
  686. #undef x3
  687. #undef y3
  688. #undef z3
  689. #undef t1
  690. #undef t2
  691. #undef t3
  692. #undef l1
  693. #undef l2
  694. #undef l3
  695. }
  696. /* RESULT = 2 * POINT (Montgomery version). */
  697. static void dup_point_montgomery(MPI_POINT result,
  698. MPI_POINT point, struct mpi_ec_ctx *ctx)
  699. {
  700. (void)result;
  701. (void)point;
  702. (void)ctx;
  703. log_fatal("%s: %s not yet supported\n",
  704. "mpi_ec_dup_point", "Montgomery");
  705. }
  706. /* RESULT = 2 * POINT (Twisted Edwards version). */
  707. static void dup_point_edwards(MPI_POINT result,
  708. MPI_POINT point, struct mpi_ec_ctx *ctx)
  709. {
  710. #define X1 (point->x)
  711. #define Y1 (point->y)
  712. #define Z1 (point->z)
  713. #define X3 (result->x)
  714. #define Y3 (result->y)
  715. #define Z3 (result->z)
  716. #define B (ctx->t.scratch[0])
  717. #define C (ctx->t.scratch[1])
  718. #define D (ctx->t.scratch[2])
  719. #define E (ctx->t.scratch[3])
  720. #define F (ctx->t.scratch[4])
  721. #define H (ctx->t.scratch[5])
  722. #define J (ctx->t.scratch[6])
  723. /* Compute: (X_3 : Y_3 : Z_3) = 2( X_1 : Y_1 : Z_1 ) */
  724. /* B = (X_1 + Y_1)^2 */
  725. ctx->addm(B, X1, Y1, ctx);
  726. ctx->pow2(B, B, ctx);
  727. /* C = X_1^2 */
  728. /* D = Y_1^2 */
  729. ctx->pow2(C, X1, ctx);
  730. ctx->pow2(D, Y1, ctx);
  731. /* E = aC */
  732. if (ctx->dialect == ECC_DIALECT_ED25519)
  733. ctx->subm(E, ctx->p, C, ctx);
  734. else
  735. ctx->mulm(E, ctx->a, C, ctx);
  736. /* F = E + D */
  737. ctx->addm(F, E, D, ctx);
  738. /* H = Z_1^2 */
  739. ctx->pow2(H, Z1, ctx);
  740. /* J = F - 2H */
  741. ctx->mul2(J, H, ctx);
  742. ctx->subm(J, F, J, ctx);
  743. /* X_3 = (B - C - D) · J */
  744. ctx->subm(X3, B, C, ctx);
  745. ctx->subm(X3, X3, D, ctx);
  746. ctx->mulm(X3, X3, J, ctx);
  747. /* Y_3 = F · (E - D) */
  748. ctx->subm(Y3, E, D, ctx);
  749. ctx->mulm(Y3, Y3, F, ctx);
  750. /* Z_3 = F · J */
  751. ctx->mulm(Z3, F, J, ctx);
  752. #undef X1
  753. #undef Y1
  754. #undef Z1
  755. #undef X3
  756. #undef Y3
  757. #undef Z3
  758. #undef B
  759. #undef C
  760. #undef D
  761. #undef E
  762. #undef F
  763. #undef H
  764. #undef J
  765. }
  766. /* RESULT = 2 * POINT */
  767. static void
  768. mpi_ec_dup_point(MPI_POINT result, MPI_POINT point, struct mpi_ec_ctx *ctx)
  769. {
  770. switch (ctx->model) {
  771. case MPI_EC_WEIERSTRASS:
  772. dup_point_weierstrass(result, point, ctx);
  773. break;
  774. case MPI_EC_MONTGOMERY:
  775. dup_point_montgomery(result, point, ctx);
  776. break;
  777. case MPI_EC_EDWARDS:
  778. dup_point_edwards(result, point, ctx);
  779. break;
  780. }
  781. }
  782. /* RESULT = P1 + P2 (Weierstrass version).*/
  783. static void add_points_weierstrass(MPI_POINT result,
  784. MPI_POINT p1, MPI_POINT p2,
  785. struct mpi_ec_ctx *ctx)
  786. {
  787. #define x1 (p1->x)
  788. #define y1 (p1->y)
  789. #define z1 (p1->z)
  790. #define x2 (p2->x)
  791. #define y2 (p2->y)
  792. #define z2 (p2->z)
  793. #define x3 (result->x)
  794. #define y3 (result->y)
  795. #define z3 (result->z)
  796. #define l1 (ctx->t.scratch[0])
  797. #define l2 (ctx->t.scratch[1])
  798. #define l3 (ctx->t.scratch[2])
  799. #define l4 (ctx->t.scratch[3])
  800. #define l5 (ctx->t.scratch[4])
  801. #define l6 (ctx->t.scratch[5])
  802. #define l7 (ctx->t.scratch[6])
  803. #define l8 (ctx->t.scratch[7])
  804. #define l9 (ctx->t.scratch[8])
  805. #define t1 (ctx->t.scratch[9])
  806. #define t2 (ctx->t.scratch[10])
  807. if ((!mpi_cmp(x1, x2)) && (!mpi_cmp(y1, y2)) && (!mpi_cmp(z1, z2))) {
  808. /* Same point; need to call the duplicate function. */
  809. mpi_ec_dup_point(result, p1, ctx);
  810. } else if (!mpi_cmp_ui(z1, 0)) {
  811. /* P1 is at infinity. */
  812. mpi_set(x3, p2->x);
  813. mpi_set(y3, p2->y);
  814. mpi_set(z3, p2->z);
  815. } else if (!mpi_cmp_ui(z2, 0)) {
  816. /* P2 is at infinity. */
  817. mpi_set(x3, p1->x);
  818. mpi_set(y3, p1->y);
  819. mpi_set(z3, p1->z);
  820. } else {
  821. int z1_is_one = !mpi_cmp_ui(z1, 1);
  822. int z2_is_one = !mpi_cmp_ui(z2, 1);
  823. /* l1 = x1 z2^2 */
  824. /* l2 = x2 z1^2 */
  825. if (z2_is_one)
  826. mpi_set(l1, x1);
  827. else {
  828. ec_pow2(l1, z2, ctx);
  829. ec_mulm(l1, l1, x1, ctx);
  830. }
  831. if (z1_is_one)
  832. mpi_set(l2, x2);
  833. else {
  834. ec_pow2(l2, z1, ctx);
  835. ec_mulm(l2, l2, x2, ctx);
  836. }
  837. /* l3 = l1 - l2 */
  838. ec_subm(l3, l1, l2, ctx);
  839. /* l4 = y1 z2^3 */
  840. ec_powm(l4, z2, mpi_const(MPI_C_THREE), ctx);
  841. ec_mulm(l4, l4, y1, ctx);
  842. /* l5 = y2 z1^3 */
  843. ec_powm(l5, z1, mpi_const(MPI_C_THREE), ctx);
  844. ec_mulm(l5, l5, y2, ctx);
  845. /* l6 = l4 - l5 */
  846. ec_subm(l6, l4, l5, ctx);
  847. if (!mpi_cmp_ui(l3, 0)) {
  848. if (!mpi_cmp_ui(l6, 0)) {
  849. /* P1 and P2 are the same - use duplicate function. */
  850. mpi_ec_dup_point(result, p1, ctx);
  851. } else {
  852. /* P1 is the inverse of P2. */
  853. mpi_set_ui(x3, 1);
  854. mpi_set_ui(y3, 1);
  855. mpi_set_ui(z3, 0);
  856. }
  857. } else {
  858. /* l7 = l1 + l2 */
  859. ec_addm(l7, l1, l2, ctx);
  860. /* l8 = l4 + l5 */
  861. ec_addm(l8, l4, l5, ctx);
  862. /* z3 = z1 z2 l3 */
  863. ec_mulm(z3, z1, z2, ctx);
  864. ec_mulm(z3, z3, l3, ctx);
  865. /* x3 = l6^2 - l7 l3^2 */
  866. ec_pow2(t1, l6, ctx);
  867. ec_pow2(t2, l3, ctx);
  868. ec_mulm(t2, t2, l7, ctx);
  869. ec_subm(x3, t1, t2, ctx);
  870. /* l9 = l7 l3^2 - 2 x3 */
  871. ec_mul2(t1, x3, ctx);
  872. ec_subm(l9, t2, t1, ctx);
  873. /* y3 = (l9 l6 - l8 l3^3)/2 */
  874. ec_mulm(l9, l9, l6, ctx);
  875. ec_powm(t1, l3, mpi_const(MPI_C_THREE), ctx); /* fixme: Use saved value*/
  876. ec_mulm(t1, t1, l8, ctx);
  877. ec_subm(y3, l9, t1, ctx);
  878. ec_mulm(y3, y3, ec_get_two_inv_p(ctx), ctx);
  879. }
  880. }
  881. #undef x1
  882. #undef y1
  883. #undef z1
  884. #undef x2
  885. #undef y2
  886. #undef z2
  887. #undef x3
  888. #undef y3
  889. #undef z3
  890. #undef l1
  891. #undef l2
  892. #undef l3
  893. #undef l4
  894. #undef l5
  895. #undef l6
  896. #undef l7
  897. #undef l8
  898. #undef l9
  899. #undef t1
  900. #undef t2
  901. }
  902. /* RESULT = P1 + P2 (Montgomery version).*/
  903. static void add_points_montgomery(MPI_POINT result,
  904. MPI_POINT p1, MPI_POINT p2,
  905. struct mpi_ec_ctx *ctx)
  906. {
  907. (void)result;
  908. (void)p1;
  909. (void)p2;
  910. (void)ctx;
  911. log_fatal("%s: %s not yet supported\n",
  912. "mpi_ec_add_points", "Montgomery");
  913. }
  914. /* RESULT = P1 + P2 (Twisted Edwards version).*/
  915. static void add_points_edwards(MPI_POINT result,
  916. MPI_POINT p1, MPI_POINT p2,
  917. struct mpi_ec_ctx *ctx)
  918. {
  919. #define X1 (p1->x)
  920. #define Y1 (p1->y)
  921. #define Z1 (p1->z)
  922. #define X2 (p2->x)
  923. #define Y2 (p2->y)
  924. #define Z2 (p2->z)
  925. #define X3 (result->x)
  926. #define Y3 (result->y)
  927. #define Z3 (result->z)
  928. #define A (ctx->t.scratch[0])
  929. #define B (ctx->t.scratch[1])
  930. #define C (ctx->t.scratch[2])
  931. #define D (ctx->t.scratch[3])
  932. #define E (ctx->t.scratch[4])
  933. #define F (ctx->t.scratch[5])
  934. #define G (ctx->t.scratch[6])
  935. #define tmp (ctx->t.scratch[7])
  936. point_resize(result, ctx);
  937. /* Compute: (X_3 : Y_3 : Z_3) = (X_1 : Y_1 : Z_1) + (X_2 : Y_2 : Z_3) */
  938. /* A = Z1 · Z2 */
  939. ctx->mulm(A, Z1, Z2, ctx);
  940. /* B = A^2 */
  941. ctx->pow2(B, A, ctx);
  942. /* C = X1 · X2 */
  943. ctx->mulm(C, X1, X2, ctx);
  944. /* D = Y1 · Y2 */
  945. ctx->mulm(D, Y1, Y2, ctx);
  946. /* E = d · C · D */
  947. ctx->mulm(E, ctx->b, C, ctx);
  948. ctx->mulm(E, E, D, ctx);
  949. /* F = B - E */
  950. ctx->subm(F, B, E, ctx);
  951. /* G = B + E */
  952. ctx->addm(G, B, E, ctx);
  953. /* X_3 = A · F · ((X_1 + Y_1) · (X_2 + Y_2) - C - D) */
  954. ctx->addm(tmp, X1, Y1, ctx);
  955. ctx->addm(X3, X2, Y2, ctx);
  956. ctx->mulm(X3, X3, tmp, ctx);
  957. ctx->subm(X3, X3, C, ctx);
  958. ctx->subm(X3, X3, D, ctx);
  959. ctx->mulm(X3, X3, F, ctx);
  960. ctx->mulm(X3, X3, A, ctx);
  961. /* Y_3 = A · G · (D - aC) */
  962. if (ctx->dialect == ECC_DIALECT_ED25519) {
  963. ctx->addm(Y3, D, C, ctx);
  964. } else {
  965. ctx->mulm(Y3, ctx->a, C, ctx);
  966. ctx->subm(Y3, D, Y3, ctx);
  967. }
  968. ctx->mulm(Y3, Y3, G, ctx);
  969. ctx->mulm(Y3, Y3, A, ctx);
  970. /* Z_3 = F · G */
  971. ctx->mulm(Z3, F, G, ctx);
  972. #undef X1
  973. #undef Y1
  974. #undef Z1
  975. #undef X2
  976. #undef Y2
  977. #undef Z2
  978. #undef X3
  979. #undef Y3
  980. #undef Z3
  981. #undef A
  982. #undef B
  983. #undef C
  984. #undef D
  985. #undef E
  986. #undef F
  987. #undef G
  988. #undef tmp
  989. }
  990. /* Compute a step of Montgomery Ladder (only use X and Z in the point).
  991. * Inputs: P1, P2, and x-coordinate of DIF = P1 - P1.
  992. * Outputs: PRD = 2 * P1 and SUM = P1 + P2.
  993. */
  994. static void montgomery_ladder(MPI_POINT prd, MPI_POINT sum,
  995. MPI_POINT p1, MPI_POINT p2, MPI dif_x,
  996. struct mpi_ec_ctx *ctx)
  997. {
  998. ctx->addm(sum->x, p2->x, p2->z, ctx);
  999. ctx->subm(p2->z, p2->x, p2->z, ctx);
  1000. ctx->addm(prd->x, p1->x, p1->z, ctx);
  1001. ctx->subm(p1->z, p1->x, p1->z, ctx);
  1002. ctx->mulm(p2->x, p1->z, sum->x, ctx);
  1003. ctx->mulm(p2->z, prd->x, p2->z, ctx);
  1004. ctx->pow2(p1->x, prd->x, ctx);
  1005. ctx->pow2(p1->z, p1->z, ctx);
  1006. ctx->addm(sum->x, p2->x, p2->z, ctx);
  1007. ctx->subm(p2->z, p2->x, p2->z, ctx);
  1008. ctx->mulm(prd->x, p1->x, p1->z, ctx);
  1009. ctx->subm(p1->z, p1->x, p1->z, ctx);
  1010. ctx->pow2(sum->x, sum->x, ctx);
  1011. ctx->pow2(sum->z, p2->z, ctx);
  1012. ctx->mulm(prd->z, p1->z, ctx->a, ctx); /* CTX->A: (a-2)/4 */
  1013. ctx->mulm(sum->z, sum->z, dif_x, ctx);
  1014. ctx->addm(prd->z, p1->x, prd->z, ctx);
  1015. ctx->mulm(prd->z, prd->z, p1->z, ctx);
  1016. }
  1017. /* RESULT = P1 + P2 */
  1018. void mpi_ec_add_points(MPI_POINT result,
  1019. MPI_POINT p1, MPI_POINT p2,
  1020. struct mpi_ec_ctx *ctx)
  1021. {
  1022. switch (ctx->model) {
  1023. case MPI_EC_WEIERSTRASS:
  1024. add_points_weierstrass(result, p1, p2, ctx);
  1025. break;
  1026. case MPI_EC_MONTGOMERY:
  1027. add_points_montgomery(result, p1, p2, ctx);
  1028. break;
  1029. case MPI_EC_EDWARDS:
  1030. add_points_edwards(result, p1, p2, ctx);
  1031. break;
  1032. }
  1033. }
  1034. EXPORT_SYMBOL_GPL(mpi_ec_add_points);
  1035. /* Scalar point multiplication - the main function for ECC. If takes
  1036. * an integer SCALAR and a POINT as well as the usual context CTX.
  1037. * RESULT will be set to the resulting point.
  1038. */
  1039. void mpi_ec_mul_point(MPI_POINT result,
  1040. MPI scalar, MPI_POINT point,
  1041. struct mpi_ec_ctx *ctx)
  1042. {
  1043. MPI x1, y1, z1, k, h, yy;
  1044. unsigned int i, loops;
  1045. struct gcry_mpi_point p1, p2, p1inv;
  1046. if (ctx->model == MPI_EC_EDWARDS) {
  1047. /* Simple left to right binary method. Algorithm 3.27 from
  1048. * {author={Hankerson, Darrel and Menezes, Alfred J. and Vanstone, Scott},
  1049. * title = {Guide to Elliptic Curve Cryptography},
  1050. * year = {2003}, isbn = {038795273X},
  1051. * url = {http://www.cacr.math.uwaterloo.ca/ecc/},
  1052. * publisher = {Springer-Verlag New York, Inc.}}
  1053. */
  1054. unsigned int nbits;
  1055. int j;
  1056. if (mpi_cmp(scalar, ctx->p) >= 0)
  1057. nbits = mpi_get_nbits(scalar);
  1058. else
  1059. nbits = mpi_get_nbits(ctx->p);
  1060. mpi_set_ui(result->x, 0);
  1061. mpi_set_ui(result->y, 1);
  1062. mpi_set_ui(result->z, 1);
  1063. point_resize(point, ctx);
  1064. point_resize(result, ctx);
  1065. point_resize(point, ctx);
  1066. for (j = nbits-1; j >= 0; j--) {
  1067. mpi_ec_dup_point(result, result, ctx);
  1068. if (mpi_test_bit(scalar, j))
  1069. mpi_ec_add_points(result, result, point, ctx);
  1070. }
  1071. return;
  1072. } else if (ctx->model == MPI_EC_MONTGOMERY) {
  1073. unsigned int nbits;
  1074. int j;
  1075. struct gcry_mpi_point p1_, p2_;
  1076. MPI_POINT q1, q2, prd, sum;
  1077. unsigned long sw;
  1078. mpi_size_t rsize;
  1079. /* Compute scalar point multiplication with Montgomery Ladder.
  1080. * Note that we don't use Y-coordinate in the points at all.
  1081. * RESULT->Y will be filled by zero.
  1082. */
  1083. nbits = mpi_get_nbits(scalar);
  1084. point_init(&p1);
  1085. point_init(&p2);
  1086. point_init(&p1_);
  1087. point_init(&p2_);
  1088. mpi_set_ui(p1.x, 1);
  1089. mpi_free(p2.x);
  1090. p2.x = mpi_copy(point->x);
  1091. mpi_set_ui(p2.z, 1);
  1092. point_resize(&p1, ctx);
  1093. point_resize(&p2, ctx);
  1094. point_resize(&p1_, ctx);
  1095. point_resize(&p2_, ctx);
  1096. mpi_resize(point->x, ctx->p->nlimbs);
  1097. point->x->nlimbs = ctx->p->nlimbs;
  1098. q1 = &p1;
  1099. q2 = &p2;
  1100. prd = &p1_;
  1101. sum = &p2_;
  1102. for (j = nbits-1; j >= 0; j--) {
  1103. MPI_POINT t;
  1104. sw = mpi_test_bit(scalar, j);
  1105. point_swap_cond(q1, q2, sw, ctx);
  1106. montgomery_ladder(prd, sum, q1, q2, point->x, ctx);
  1107. point_swap_cond(prd, sum, sw, ctx);
  1108. t = q1; q1 = prd; prd = t;
  1109. t = q2; q2 = sum; sum = t;
  1110. }
  1111. mpi_clear(result->y);
  1112. sw = (nbits & 1);
  1113. point_swap_cond(&p1, &p1_, sw, ctx);
  1114. rsize = p1.z->nlimbs;
  1115. MPN_NORMALIZE(p1.z->d, rsize);
  1116. if (rsize == 0) {
  1117. mpi_set_ui(result->x, 1);
  1118. mpi_set_ui(result->z, 0);
  1119. } else {
  1120. z1 = mpi_new(0);
  1121. ec_invm(z1, p1.z, ctx);
  1122. ec_mulm(result->x, p1.x, z1, ctx);
  1123. mpi_set_ui(result->z, 1);
  1124. mpi_free(z1);
  1125. }
  1126. point_free(&p1);
  1127. point_free(&p2);
  1128. point_free(&p1_);
  1129. point_free(&p2_);
  1130. return;
  1131. }
  1132. x1 = mpi_alloc_like(ctx->p);
  1133. y1 = mpi_alloc_like(ctx->p);
  1134. h = mpi_alloc_like(ctx->p);
  1135. k = mpi_copy(scalar);
  1136. yy = mpi_copy(point->y);
  1137. if (mpi_has_sign(k)) {
  1138. k->sign = 0;
  1139. ec_invm(yy, yy, ctx);
  1140. }
  1141. if (!mpi_cmp_ui(point->z, 1)) {
  1142. mpi_set(x1, point->x);
  1143. mpi_set(y1, yy);
  1144. } else {
  1145. MPI z2, z3;
  1146. z2 = mpi_alloc_like(ctx->p);
  1147. z3 = mpi_alloc_like(ctx->p);
  1148. ec_mulm(z2, point->z, point->z, ctx);
  1149. ec_mulm(z3, point->z, z2, ctx);
  1150. ec_invm(z2, z2, ctx);
  1151. ec_mulm(x1, point->x, z2, ctx);
  1152. ec_invm(z3, z3, ctx);
  1153. ec_mulm(y1, yy, z3, ctx);
  1154. mpi_free(z2);
  1155. mpi_free(z3);
  1156. }
  1157. z1 = mpi_copy(mpi_const(MPI_C_ONE));
  1158. mpi_mul(h, k, mpi_const(MPI_C_THREE)); /* h = 3k */
  1159. loops = mpi_get_nbits(h);
  1160. if (loops < 2) {
  1161. /* If SCALAR is zero, the above mpi_mul sets H to zero and thus
  1162. * LOOPs will be zero. To avoid an underflow of I in the main
  1163. * loop we set LOOP to 2 and the result to (0,0,0).
  1164. */
  1165. loops = 2;
  1166. mpi_clear(result->x);
  1167. mpi_clear(result->y);
  1168. mpi_clear(result->z);
  1169. } else {
  1170. mpi_set(result->x, point->x);
  1171. mpi_set(result->y, yy);
  1172. mpi_set(result->z, point->z);
  1173. }
  1174. mpi_free(yy); yy = NULL;
  1175. p1.x = x1; x1 = NULL;
  1176. p1.y = y1; y1 = NULL;
  1177. p1.z = z1; z1 = NULL;
  1178. point_init(&p2);
  1179. point_init(&p1inv);
  1180. /* Invert point: y = p - y mod p */
  1181. point_set(&p1inv, &p1);
  1182. ec_subm(p1inv.y, ctx->p, p1inv.y, ctx);
  1183. for (i = loops-2; i > 0; i--) {
  1184. mpi_ec_dup_point(result, result, ctx);
  1185. if (mpi_test_bit(h, i) == 1 && mpi_test_bit(k, i) == 0) {
  1186. point_set(&p2, result);
  1187. mpi_ec_add_points(result, &p2, &p1, ctx);
  1188. }
  1189. if (mpi_test_bit(h, i) == 0 && mpi_test_bit(k, i) == 1) {
  1190. point_set(&p2, result);
  1191. mpi_ec_add_points(result, &p2, &p1inv, ctx);
  1192. }
  1193. }
  1194. point_free(&p1);
  1195. point_free(&p2);
  1196. point_free(&p1inv);
  1197. mpi_free(h);
  1198. mpi_free(k);
  1199. }
  1200. EXPORT_SYMBOL_GPL(mpi_ec_mul_point);
  1201. /* Return true if POINT is on the curve described by CTX. */
  1202. int mpi_ec_curve_point(MPI_POINT point, struct mpi_ec_ctx *ctx)
  1203. {
  1204. int res = 0;
  1205. MPI x, y, w;
  1206. x = mpi_new(0);
  1207. y = mpi_new(0);
  1208. w = mpi_new(0);
  1209. /* Check that the point is in range. This needs to be done here and
  1210. * not after conversion to affine coordinates.
  1211. */
  1212. if (mpi_cmpabs(point->x, ctx->p) >= 0)
  1213. goto leave;
  1214. if (mpi_cmpabs(point->y, ctx->p) >= 0)
  1215. goto leave;
  1216. if (mpi_cmpabs(point->z, ctx->p) >= 0)
  1217. goto leave;
  1218. switch (ctx->model) {
  1219. case MPI_EC_WEIERSTRASS:
  1220. {
  1221. MPI xxx;
  1222. if (mpi_ec_get_affine(x, y, point, ctx))
  1223. goto leave;
  1224. xxx = mpi_new(0);
  1225. /* y^2 == x^3 + a·x + b */
  1226. ec_pow2(y, y, ctx);
  1227. ec_pow3(xxx, x, ctx);
  1228. ec_mulm(w, ctx->a, x, ctx);
  1229. ec_addm(w, w, ctx->b, ctx);
  1230. ec_addm(w, w, xxx, ctx);
  1231. if (!mpi_cmp(y, w))
  1232. res = 1;
  1233. mpi_free(xxx);
  1234. }
  1235. break;
  1236. case MPI_EC_MONTGOMERY:
  1237. {
  1238. #define xx y
  1239. /* With Montgomery curve, only X-coordinate is valid. */
  1240. if (mpi_ec_get_affine(x, NULL, point, ctx))
  1241. goto leave;
  1242. /* The equation is: b * y^2 == x^3 + a · x^2 + x */
  1243. /* We check if right hand is quadratic residue or not by
  1244. * Euler's criterion.
  1245. */
  1246. /* CTX->A has (a-2)/4 and CTX->B has b^-1 */
  1247. ec_mulm(w, ctx->a, mpi_const(MPI_C_FOUR), ctx);
  1248. ec_addm(w, w, mpi_const(MPI_C_TWO), ctx);
  1249. ec_mulm(w, w, x, ctx);
  1250. ec_pow2(xx, x, ctx);
  1251. ec_addm(w, w, xx, ctx);
  1252. ec_addm(w, w, mpi_const(MPI_C_ONE), ctx);
  1253. ec_mulm(w, w, x, ctx);
  1254. ec_mulm(w, w, ctx->b, ctx);
  1255. #undef xx
  1256. /* Compute Euler's criterion: w^(p-1)/2 */
  1257. #define p_minus1 y
  1258. ec_subm(p_minus1, ctx->p, mpi_const(MPI_C_ONE), ctx);
  1259. mpi_rshift(p_minus1, p_minus1, 1);
  1260. ec_powm(w, w, p_minus1, ctx);
  1261. res = !mpi_cmp_ui(w, 1);
  1262. #undef p_minus1
  1263. }
  1264. break;
  1265. case MPI_EC_EDWARDS:
  1266. {
  1267. if (mpi_ec_get_affine(x, y, point, ctx))
  1268. goto leave;
  1269. mpi_resize(w, ctx->p->nlimbs);
  1270. w->nlimbs = ctx->p->nlimbs;
  1271. /* a · x^2 + y^2 - 1 - b · x^2 · y^2 == 0 */
  1272. ctx->pow2(x, x, ctx);
  1273. ctx->pow2(y, y, ctx);
  1274. if (ctx->dialect == ECC_DIALECT_ED25519)
  1275. ctx->subm(w, ctx->p, x, ctx);
  1276. else
  1277. ctx->mulm(w, ctx->a, x, ctx);
  1278. ctx->addm(w, w, y, ctx);
  1279. ctx->mulm(x, x, y, ctx);
  1280. ctx->mulm(x, x, ctx->b, ctx);
  1281. ctx->subm(w, w, x, ctx);
  1282. if (!mpi_cmp_ui(w, 1))
  1283. res = 1;
  1284. }
  1285. break;
  1286. }
  1287. leave:
  1288. mpi_free(w);
  1289. mpi_free(x);
  1290. mpi_free(y);
  1291. return res;
  1292. }
  1293. EXPORT_SYMBOL_GPL(mpi_ec_curve_point);