ecc.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149
  1. #include <assert.h>
  2. #include "ssh.h"
  3. #include "mpint.h"
  4. #include "ecc.h"
  5. /* ----------------------------------------------------------------------
  6. * Weierstrass curves.
  7. */
  8. struct WeierstrassPoint {
  9. /*
  10. * Internally, we represent a point using 'Jacobian coordinates',
  11. * which are three values X,Y,Z whose relation to the affine
  12. * coordinates x,y is that x = X/Z^2 and y = Y/Z^3.
  13. *
  14. * This allows us to do most of our calculations without having to
  15. * take an inverse mod p: every time the obvious affine formulae
  16. * would need you to divide by something, you instead multiply it
  17. * into the 'denominator' coordinate Z. You only have to actually
  18. * take the inverse of Z when you need to get the affine
  19. * coordinates back out, which means you do it once after your
  20. * entire computation instead of at every intermediate step.
  21. *
  22. * The point at infinity is represented by setting all three
  23. * coordinates to zero.
  24. *
  25. * These values are also stored in the Montgomery-multiplication
  26. * transformed representation.
  27. */
  28. mp_int *X, *Y, *Z;
  29. WeierstrassCurve *wc;
  30. };
  31. struct WeierstrassCurve {
  32. /* Prime modulus of the finite field. */
  33. mp_int *p;
  34. /* Persistent Montgomery context for doing arithmetic mod p. */
  35. MontyContext *mc;
  36. /* Modsqrt context for point decompression. NULL if this curve was
  37. * constructed without providing nonsquare_mod_p. */
  38. ModsqrtContext *sc;
  39. /* Parameters of the curve, in Montgomery-multiplication
  40. * transformed form. */
  41. mp_int *a, *b;
  42. };
  43. WeierstrassCurve *ecc_weierstrass_curve(
  44. mp_int *p, mp_int *a, mp_int *b, mp_int *nonsquare_mod_p)
  45. {
  46. WeierstrassCurve *wc = snew(WeierstrassCurve);
  47. wc->p = mp_copy(p);
  48. wc->mc = monty_new(p);
  49. wc->a = monty_import(wc->mc, a);
  50. wc->b = monty_import(wc->mc, b);
  51. if (nonsquare_mod_p)
  52. wc->sc = modsqrt_new(p, nonsquare_mod_p);
  53. else
  54. wc->sc = NULL;
  55. return wc;
  56. }
  57. void ecc_weierstrass_curve_free(WeierstrassCurve *wc)
  58. {
  59. mp_free(wc->p);
  60. mp_free(wc->a);
  61. mp_free(wc->b);
  62. monty_free(wc->mc);
  63. if (wc->sc)
  64. modsqrt_free(wc->sc);
  65. sfree(wc);
  66. }
  67. static WeierstrassPoint *ecc_weierstrass_point_new_empty(WeierstrassCurve *wc)
  68. {
  69. WeierstrassPoint *wp = snew(WeierstrassPoint);
  70. wp->wc = wc;
  71. wp->X = wp->Y = wp->Z = NULL;
  72. return wp;
  73. }
  74. static WeierstrassPoint *ecc_weierstrass_point_new_imported(
  75. WeierstrassCurve *wc, mp_int *monty_x, mp_int *monty_y)
  76. {
  77. WeierstrassPoint *wp = ecc_weierstrass_point_new_empty(wc);
  78. wp->X = monty_x;
  79. wp->Y = monty_y;
  80. wp->Z = mp_copy(monty_identity(wc->mc));
  81. return wp;
  82. }
  83. WeierstrassPoint *ecc_weierstrass_point_new(
  84. WeierstrassCurve *wc, mp_int *x, mp_int *y)
  85. {
  86. return ecc_weierstrass_point_new_imported(
  87. wc, monty_import(wc->mc, x), monty_import(wc->mc, y));
  88. }
  89. WeierstrassPoint *ecc_weierstrass_point_new_identity(WeierstrassCurve *wc)
  90. {
  91. WeierstrassPoint *wp = ecc_weierstrass_point_new_empty(wc);
  92. size_t bits = mp_max_bits(wc->p);
  93. wp->X = mp_new(bits);
  94. wp->Y = mp_new(bits);
  95. wp->Z = mp_new(bits);
  96. return wp;
  97. }
  98. WeierstrassPoint *ecc_weierstrass_point_copy(WeierstrassPoint *orig)
  99. {
  100. WeierstrassPoint *wp = ecc_weierstrass_point_new_empty(orig->wc);
  101. wp->X = mp_copy(orig->X);
  102. wp->Y = mp_copy(orig->Y);
  103. wp->Z = mp_copy(orig->Z);
  104. return wp;
  105. }
  106. void ecc_weierstrass_point_free(WeierstrassPoint *wp)
  107. {
  108. mp_free(wp->X);
  109. mp_free(wp->Y);
  110. mp_free(wp->Z);
  111. smemclr(wp, sizeof(*wp));
  112. sfree(wp);
  113. }
  114. static mp_int *ecc_weierstrass_equation_rhs(
  115. WeierstrassCurve *wc, mp_int *monty_x)
  116. {
  117. mp_int *x2 = monty_mul(wc->mc, monty_x, monty_x);
  118. mp_int *x2_plus_a = monty_add(wc->mc, x2, wc->a);
  119. mp_int *x3_plus_ax = monty_mul(wc->mc, x2_plus_a, monty_x);
  120. mp_int *rhs = monty_add(wc->mc, x3_plus_ax, wc->b);
  121. mp_free(x2);
  122. mp_free(x2_plus_a);
  123. mp_free(x3_plus_ax);
  124. return rhs;
  125. }
  126. WeierstrassPoint *ecc_weierstrass_point_new_from_x(
  127. WeierstrassCurve *wc, mp_int *xorig, unsigned desired_y_parity)
  128. {
  129. pinitassert(wc->sc);
  130. /*
  131. * The curve equation is y^2 = x^3 + ax + b, which is already
  132. * conveniently in a form where we can compute the RHS and take
  133. * the square root of it to get y.
  134. */
  135. unsigned success;
  136. mp_int *x = monty_import(wc->mc, xorig);
  137. mp_int *rhs = ecc_weierstrass_equation_rhs(wc, x);
  138. mp_int *y = monty_modsqrt(wc->sc, rhs, &success);
  139. mp_free(rhs);
  140. if (!success) {
  141. /* Failure! x^3+ax+b worked out to be a number that has no
  142. * square root mod p. In this situation there's no point in
  143. * trying to be time-constant, since the protocol sequence is
  144. * going to diverge anyway when we complain to whoever gave us
  145. * this bogus value. */
  146. mp_free(x);
  147. mp_free(y);
  148. return NULL;
  149. }
  150. /*
  151. * Choose whichever of y and p-y has the specified parity (of its
  152. * lowest positive residue mod p).
  153. */
  154. { // WINSCP
  155. mp_int *tmp = monty_export(wc->mc, y);
  156. unsigned flip = (mp_get_bit(tmp, 0) ^ desired_y_parity) & 1;
  157. mp_sub_into(tmp, wc->p, y);
  158. mp_select_into(y, y, tmp, flip);
  159. mp_free(tmp);
  160. } // WINSCP
  161. return ecc_weierstrass_point_new_imported(wc, x, y);
  162. }
  163. static void ecc_weierstrass_cond_overwrite(
  164. WeierstrassPoint *dest, WeierstrassPoint *src, unsigned overwrite)
  165. {
  166. mp_select_into(dest->X, dest->X, src->X, overwrite);
  167. mp_select_into(dest->Y, dest->Y, src->Y, overwrite);
  168. mp_select_into(dest->Z, dest->Z, src->Z, overwrite);
  169. }
  170. static void ecc_weierstrass_cond_swap(
  171. WeierstrassPoint *P, WeierstrassPoint *Q, unsigned swap)
  172. {
  173. mp_cond_swap(P->X, Q->X, swap);
  174. mp_cond_swap(P->Y, Q->Y, swap);
  175. mp_cond_swap(P->Z, Q->Z, swap);
  176. }
  177. /*
  178. * Shared code between all three of the basic arithmetic functions:
  179. * once we've determined the slope of the line that we're intersecting
  180. * the curve with, this takes care of finding the coordinates of the
  181. * third intersection point (given the two input x-coordinates and one
  182. * of the y-coords) and negating it to generate the output.
  183. */
  184. static inline void ecc_weierstrass_epilogue(
  185. mp_int *Px, mp_int *Qx, mp_int *Py, mp_int *common_Z,
  186. mp_int *lambda_n, mp_int *lambda_d, WeierstrassPoint *out)
  187. {
  188. WeierstrassCurve *wc = out->wc;
  189. /* Powers of the numerator and denominator of the slope lambda */
  190. mp_int *lambda_n2 = monty_mul(wc->mc, lambda_n, lambda_n);
  191. mp_int *lambda_d2 = monty_mul(wc->mc, lambda_d, lambda_d);
  192. mp_int *lambda_d3 = monty_mul(wc->mc, lambda_d, lambda_d2);
  193. /* Make the output x-coordinate */
  194. mp_int *xsum = monty_add(wc->mc, Px, Qx);
  195. mp_int *lambda_d2_xsum = monty_mul(wc->mc, lambda_d2, xsum);
  196. out->X = monty_sub(wc->mc, lambda_n2, lambda_d2_xsum);
  197. /* Make the output y-coordinate */
  198. { // WINSCP
  199. mp_int *lambda_d2_Px = monty_mul(wc->mc, lambda_d2, Px);
  200. mp_int *xdiff = monty_sub(wc->mc, lambda_d2_Px, out->X);
  201. mp_int *lambda_n_xdiff = monty_mul(wc->mc, lambda_n, xdiff);
  202. mp_int *lambda_d3_Py = monty_mul(wc->mc, lambda_d3, Py);
  203. out->Y = monty_sub(wc->mc, lambda_n_xdiff, lambda_d3_Py);
  204. /* Make the output z-coordinate */
  205. out->Z = monty_mul(wc->mc, common_Z, lambda_d);
  206. mp_free(lambda_n2);
  207. mp_free(lambda_d2);
  208. mp_free(lambda_d3);
  209. mp_free(xsum);
  210. mp_free(xdiff);
  211. mp_free(lambda_d2_xsum);
  212. mp_free(lambda_n_xdiff);
  213. mp_free(lambda_d2_Px);
  214. mp_free(lambda_d3_Py);
  215. } // WINSCP
  216. }
  217. /*
  218. * Shared code between add and add_general: put the two input points
  219. * over a common denominator, and determine the slope lambda of the
  220. * line through both of them. If the points have the same
  221. * x-coordinate, then the slope will be returned with a zero
  222. * denominator.
  223. */
  224. static inline void ecc_weierstrass_add_prologue(
  225. WeierstrassPoint *P, WeierstrassPoint *Q,
  226. mp_int **Px, mp_int **Py, mp_int **Qx, mp_int **denom,
  227. mp_int **lambda_n, mp_int **lambda_d)
  228. {
  229. WeierstrassCurve *wc = P->wc;
  230. /* Powers of the points' denominators */
  231. mp_int *Pz2 = monty_mul(wc->mc, P->Z, P->Z);
  232. mp_int *Pz3 = monty_mul(wc->mc, Pz2, P->Z);
  233. mp_int *Qz2 = monty_mul(wc->mc, Q->Z, Q->Z);
  234. mp_int *Qz3 = monty_mul(wc->mc, Qz2, Q->Z);
  235. /* Points' x,y coordinates scaled by the other one's denominator
  236. * (raised to the appropriate power) */
  237. *Px = monty_mul(wc->mc, P->X, Qz2);
  238. *Py = monty_mul(wc->mc, P->Y, Qz3);
  239. *Qx = monty_mul(wc->mc, Q->X, Pz2);
  240. { // WINSCP
  241. mp_int *Qy = monty_mul(wc->mc, Q->Y, Pz3);
  242. /* Common denominator */
  243. *denom = monty_mul(wc->mc, P->Z, Q->Z);
  244. /* Slope of the line through the two points, if P != Q */
  245. *lambda_n = monty_sub(wc->mc, Qy, *Py);
  246. *lambda_d = monty_sub(wc->mc, *Qx, *Px);
  247. mp_free(Pz2);
  248. mp_free(Pz3);
  249. mp_free(Qz2);
  250. mp_free(Qz3);
  251. mp_free(Qy);
  252. } // WINSCP
  253. }
  254. WeierstrassPoint *ecc_weierstrass_add(WeierstrassPoint *P, WeierstrassPoint *Q)
  255. {
  256. WeierstrassCurve *wc = P->wc;
  257. assert(Q->wc == wc);
  258. { // WINSCP
  259. WeierstrassPoint *S = ecc_weierstrass_point_new_empty(wc);
  260. mp_int *Px, *Py, *Qx, *denom, *lambda_n, *lambda_d;
  261. ecc_weierstrass_add_prologue(
  262. P, Q, &Px, &Py, &Qx, &denom, &lambda_n, &lambda_d);
  263. /* Never expect to have received two mutually inverse inputs, or
  264. * two identical ones (which would make this a doubling). In other
  265. * words, the two input x-coordinates (after putting over a common
  266. * denominator) should never have been equal. */
  267. assert(!mp_eq_integer(lambda_n, 0));
  268. /* Now go to the common epilogue code. */
  269. ecc_weierstrass_epilogue(Px, Qx, Py, denom, lambda_n, lambda_d, S);
  270. mp_free(Px);
  271. mp_free(Py);
  272. mp_free(Qx);
  273. mp_free(denom);
  274. mp_free(lambda_n);
  275. mp_free(lambda_d);
  276. return S;
  277. } // WINSCP
  278. }
  279. /*
  280. * Code to determine the slope of the line you need to intersect with
  281. * the curve in the case where you're adding a point to itself. In
  282. * this situation you can't just say "the line through both input
  283. * points" because that's under-determined; instead, you have to take
  284. * the _tangent_ to the curve at the given point, by differentiating
  285. * the curve equation y^2=x^3+ax+b to get 2y dy/dx = 3x^2+a.
  286. */
  287. static inline void ecc_weierstrass_tangent_slope(
  288. WeierstrassPoint *P, mp_int **lambda_n, mp_int **lambda_d)
  289. {
  290. WeierstrassCurve *wc = P->wc;
  291. mp_int *X2 = monty_mul(wc->mc, P->X, P->X);
  292. mp_int *twoX2 = monty_add(wc->mc, X2, X2);
  293. mp_int *threeX2 = monty_add(wc->mc, twoX2, X2);
  294. mp_int *Z2 = monty_mul(wc->mc, P->Z, P->Z);
  295. mp_int *Z4 = monty_mul(wc->mc, Z2, Z2);
  296. mp_int *aZ4 = monty_mul(wc->mc, wc->a, Z4);
  297. *lambda_n = monty_add(wc->mc, threeX2, aZ4);
  298. *lambda_d = monty_add(wc->mc, P->Y, P->Y);
  299. mp_free(X2);
  300. mp_free(twoX2);
  301. mp_free(threeX2);
  302. mp_free(Z2);
  303. mp_free(Z4);
  304. mp_free(aZ4);
  305. }
  306. WeierstrassPoint *ecc_weierstrass_double(WeierstrassPoint *P)
  307. {
  308. WeierstrassCurve *wc = P->wc;
  309. WeierstrassPoint *D = ecc_weierstrass_point_new_empty(wc);
  310. mp_int *lambda_n, *lambda_d;
  311. ecc_weierstrass_tangent_slope(P, &lambda_n, &lambda_d);
  312. ecc_weierstrass_epilogue(P->X, P->X, P->Y, P->Z, lambda_n, lambda_d, D);
  313. mp_free(lambda_n);
  314. mp_free(lambda_d);
  315. return D;
  316. }
  317. static inline void ecc_weierstrass_select_into(
  318. WeierstrassPoint *dest, WeierstrassPoint *P, WeierstrassPoint *Q,
  319. unsigned choose_Q)
  320. {
  321. mp_select_into(dest->X, P->X, Q->X, choose_Q);
  322. mp_select_into(dest->Y, P->Y, Q->Y, choose_Q);
  323. mp_select_into(dest->Z, P->Z, Q->Z, choose_Q);
  324. }
  325. WeierstrassPoint *ecc_weierstrass_add_general(
  326. WeierstrassPoint *P, WeierstrassPoint *Q)
  327. {
  328. WeierstrassCurve *wc = P->wc;
  329. assert(Q->wc == wc);
  330. { // WINSCP
  331. WeierstrassPoint *S = ecc_weierstrass_point_new_empty(wc);
  332. /* Parameters for the epilogue, and slope of the line if P != Q */
  333. mp_int *Px, *Py, *Qx, *denom, *lambda_n, *lambda_d;
  334. ecc_weierstrass_add_prologue(
  335. P, Q, &Px, &Py, &Qx, &denom, &lambda_n, &lambda_d);
  336. /* Slope if P == Q */
  337. { // WINSCP
  338. mp_int *lambda_n_tangent, *lambda_d_tangent;
  339. ecc_weierstrass_tangent_slope(P, &lambda_n_tangent, &lambda_d_tangent);
  340. /* Select between those slopes depending on whether P == Q */
  341. { // WINSCP
  342. unsigned same_x_coord = mp_eq_integer(lambda_d, 0);
  343. unsigned same_y_coord = mp_eq_integer(lambda_n, 0);
  344. unsigned equality = same_x_coord & same_y_coord;
  345. mp_select_into(lambda_n, lambda_n, lambda_n_tangent, equality);
  346. mp_select_into(lambda_d, lambda_d, lambda_d_tangent, equality);
  347. /* Now go to the common code between addition and doubling */
  348. ecc_weierstrass_epilogue(Px, Qx, Py, denom, lambda_n, lambda_d, S);
  349. /* Check for the input identity cases, and overwrite the output if
  350. * necessary. */
  351. ecc_weierstrass_select_into(S, S, Q, mp_eq_integer(P->Z, 0));
  352. ecc_weierstrass_select_into(S, S, P, mp_eq_integer(Q->Z, 0));
  353. /*
  354. * In the case where P == -Q and so the output is the identity,
  355. * we'll have calculated lambda_d = 0 and so the output will have
  356. * z==0 already. Detect that and use it to normalise the other two
  357. * coordinates to zero.
  358. */
  359. { // WINSCP
  360. unsigned output_id = mp_eq_integer(S->Z, 0);
  361. mp_cond_clear(S->X, output_id);
  362. mp_cond_clear(S->Y, output_id);
  363. mp_free(Px);
  364. mp_free(Py);
  365. mp_free(Qx);
  366. mp_free(denom);
  367. mp_free(lambda_n);
  368. mp_free(lambda_d);
  369. mp_free(lambda_n_tangent);
  370. mp_free(lambda_d_tangent);
  371. return S;
  372. } // WINSCP
  373. } // WINSCP
  374. } // WINSCP
  375. } // WINSCP
  376. }
  377. WeierstrassPoint *ecc_weierstrass_multiply(WeierstrassPoint *B, mp_int *n)
  378. {
  379. WeierstrassPoint *two_B = ecc_weierstrass_double(B);
  380. WeierstrassPoint *k_B = ecc_weierstrass_point_copy(B);
  381. WeierstrassPoint *kplus1_B = ecc_weierstrass_point_copy(two_B);
  382. /*
  383. * This multiply routine more or less follows the shape of the
  384. * 'Montgomery ladder' technique that you have to use under the
  385. * extra constraint on addition in Montgomery curves, because it
  386. * was fresh in my mind and easier to just do it the same way. See
  387. * the comment in ecc_montgomery_multiply.
  388. */
  389. unsigned not_started_yet = 1;
  390. size_t bitindex; // WINSCP
  391. for (bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
  392. unsigned nbit = mp_get_bit(n, bitindex);
  393. WeierstrassPoint *sum = ecc_weierstrass_add(k_B, kplus1_B);
  394. ecc_weierstrass_cond_swap(k_B, kplus1_B, nbit);
  395. { // WINSCP
  396. WeierstrassPoint *other = ecc_weierstrass_double(k_B);
  397. ecc_weierstrass_point_free(k_B);
  398. ecc_weierstrass_point_free(kplus1_B);
  399. k_B = other;
  400. kplus1_B = sum;
  401. ecc_weierstrass_cond_swap(k_B, kplus1_B, nbit);
  402. ecc_weierstrass_cond_overwrite(k_B, B, not_started_yet);
  403. ecc_weierstrass_cond_overwrite(kplus1_B, two_B, not_started_yet);
  404. not_started_yet &= ~nbit;
  405. } // WINSCP
  406. }
  407. ecc_weierstrass_point_free(two_B);
  408. ecc_weierstrass_point_free(kplus1_B);
  409. return k_B;
  410. }
  411. unsigned ecc_weierstrass_is_identity(WeierstrassPoint *wp)
  412. {
  413. return mp_eq_integer(wp->Z, 0);
  414. }
  415. /*
  416. * Normalise a point by scaling its Jacobian coordinates so that Z=1.
  417. * This doesn't change what point is represented by the triple, but it
  418. * means the affine x,y can now be easily recovered from X and Y.
  419. */
  420. static void ecc_weierstrass_normalise(WeierstrassPoint *wp)
  421. {
  422. WeierstrassCurve *wc = wp->wc;
  423. mp_int *zinv = monty_invert(wc->mc, wp->Z);
  424. mp_int *zinv2 = monty_mul(wc->mc, zinv, zinv);
  425. mp_int *zinv3 = monty_mul(wc->mc, zinv2, zinv);
  426. monty_mul_into(wc->mc, wp->X, wp->X, zinv2);
  427. monty_mul_into(wc->mc, wp->Y, wp->Y, zinv3);
  428. mp_free(zinv);
  429. mp_free(zinv2);
  430. mp_free(zinv3);
  431. mp_copy_into(wp->Z, monty_identity(wc->mc));
  432. }
  433. void ecc_weierstrass_get_affine(
  434. WeierstrassPoint *wp, mp_int **x, mp_int **y)
  435. {
  436. WeierstrassCurve *wc = wp->wc;
  437. ecc_weierstrass_normalise(wp);
  438. if (x)
  439. *x = monty_export(wc->mc, wp->X);
  440. if (y)
  441. *y = monty_export(wc->mc, wp->Y);
  442. }
  443. unsigned ecc_weierstrass_point_valid(WeierstrassPoint *P)
  444. {
  445. mp_int *rhs = ecc_weierstrass_equation_rhs(P->wc, P->X);
  446. mp_int *lhs = monty_mul(P->wc->mc, P->Y, P->Y);
  447. unsigned valid = mp_cmp_eq(lhs, rhs);
  448. mp_free(lhs);
  449. mp_free(rhs);
  450. return valid;
  451. }
  452. /* ----------------------------------------------------------------------
  453. * Montgomery curves.
  454. */
  455. struct MontgomeryPoint {
  456. /* XZ coordinates. These represent the affine x coordinate by the
  457. * relationship x = X/Z. */
  458. mp_int *X, *Z;
  459. MontgomeryCurve *mc;
  460. };
  461. struct MontgomeryCurve {
  462. /* Prime modulus of the finite field. */
  463. mp_int *p;
  464. /* Montgomery context for arithmetic mod p. */
  465. MontyContext *mc;
  466. /* Parameters of the curve, in Montgomery-multiplication
  467. * transformed form. */
  468. mp_int *a, *b;
  469. /* (a+2)/4, also in Montgomery-multiplication form. */
  470. mp_int *aplus2over4;
  471. };
  472. MontgomeryCurve *ecc_montgomery_curve(
  473. mp_int *p, mp_int *a, mp_int *b)
  474. {
  475. MontgomeryCurve *mc = snew(MontgomeryCurve);
  476. mc->p = mp_copy(p);
  477. mc->mc = monty_new(p);
  478. mc->a = monty_import(mc->mc, a);
  479. mc->b = monty_import(mc->mc, b);
  480. { // WINSCP
  481. mp_int *four = mp_from_integer(4);
  482. mp_int *fourinverse = mp_invert(four, mc->p);
  483. mp_int *aplus2 = mp_copy(a);
  484. mp_add_integer_into(aplus2, aplus2, 2);
  485. { // WINSCP
  486. mp_int *aplus2over4 = mp_modmul(aplus2, fourinverse, mc->p);
  487. mc->aplus2over4 = monty_import(mc->mc, aplus2over4);
  488. mp_free(four);
  489. mp_free(fourinverse);
  490. mp_free(aplus2);
  491. mp_free(aplus2over4);
  492. } // WINSCP
  493. } // WINSCP
  494. return mc;
  495. }
  496. void ecc_montgomery_curve_free(MontgomeryCurve *mc)
  497. {
  498. mp_free(mc->p);
  499. mp_free(mc->a);
  500. mp_free(mc->b);
  501. mp_free(mc->aplus2over4);
  502. monty_free(mc->mc);
  503. sfree(mc);
  504. }
  505. static MontgomeryPoint *ecc_montgomery_point_new_empty(MontgomeryCurve *mc)
  506. {
  507. MontgomeryPoint *mp = snew(MontgomeryPoint);
  508. mp->mc = mc;
  509. mp->X = mp->Z = NULL;
  510. return mp;
  511. }
  512. MontgomeryPoint *ecc_montgomery_point_new(MontgomeryCurve *mc, mp_int *x)
  513. {
  514. MontgomeryPoint *mp = ecc_montgomery_point_new_empty(mc);
  515. mp->X = monty_import(mc->mc, x);
  516. mp->Z = mp_copy(monty_identity(mc->mc));
  517. return mp;
  518. }
  519. MontgomeryPoint *ecc_montgomery_point_copy(MontgomeryPoint *orig)
  520. {
  521. MontgomeryPoint *mp = ecc_montgomery_point_new_empty(orig->mc);
  522. mp->X = mp_copy(orig->X);
  523. mp->Z = mp_copy(orig->Z);
  524. return mp;
  525. }
  526. void ecc_montgomery_point_free(MontgomeryPoint *mp)
  527. {
  528. mp_free(mp->X);
  529. mp_free(mp->Z);
  530. smemclr(mp, sizeof(*mp));
  531. sfree(mp);
  532. }
  533. static void ecc_montgomery_cond_overwrite(
  534. MontgomeryPoint *dest, MontgomeryPoint *src, unsigned overwrite)
  535. {
  536. mp_select_into(dest->X, dest->X, src->X, overwrite);
  537. mp_select_into(dest->Z, dest->Z, src->Z, overwrite);
  538. }
  539. static void ecc_montgomery_cond_swap(
  540. MontgomeryPoint *P, MontgomeryPoint *Q, unsigned swap)
  541. {
  542. mp_cond_swap(P->X, Q->X, swap);
  543. mp_cond_swap(P->Z, Q->Z, swap);
  544. }
  545. MontgomeryPoint *ecc_montgomery_diff_add(
  546. MontgomeryPoint *P, MontgomeryPoint *Q, MontgomeryPoint *PminusQ)
  547. {
  548. MontgomeryCurve *mc = P->mc;
  549. assert(Q->mc == mc);
  550. assert(PminusQ->mc == mc);
  551. /*
  552. * Differential addition is achieved using the following formula
  553. * that relates the affine x-coordinates of P, Q, P+Q and P-Q:
  554. *
  555. * x(P+Q) x(P-Q) (x(Q)-x(P))^2 = (x(P)x(Q) - 1)^2
  556. *
  557. * As with the Weierstrass coordinates, the code below transforms
  558. * that affine relation into a projective one to avoid having to
  559. * do a division during the main arithmetic.
  560. */
  561. { // WINSCP
  562. MontgomeryPoint *S = ecc_montgomery_point_new_empty(mc);
  563. mp_int *Px_m_Pz = monty_sub(mc->mc, P->X, P->Z);
  564. mp_int *Px_p_Pz = monty_add(mc->mc, P->X, P->Z);
  565. mp_int *Qx_m_Qz = monty_sub(mc->mc, Q->X, Q->Z);
  566. mp_int *Qx_p_Qz = monty_add(mc->mc, Q->X, Q->Z);
  567. mp_int *PmQp = monty_mul(mc->mc, Px_m_Pz, Qx_p_Qz);
  568. mp_int *PpQm = monty_mul(mc->mc, Px_p_Pz, Qx_m_Qz);
  569. mp_int *Xpre = monty_add(mc->mc, PmQp, PpQm);
  570. mp_int *Zpre = monty_sub(mc->mc, PmQp, PpQm);
  571. mp_int *Xpre2 = monty_mul(mc->mc, Xpre, Xpre);
  572. mp_int *Zpre2 = monty_mul(mc->mc, Zpre, Zpre);
  573. S->X = monty_mul(mc->mc, Xpre2, PminusQ->Z);
  574. S->Z = monty_mul(mc->mc, Zpre2, PminusQ->X);
  575. mp_free(Px_m_Pz);
  576. mp_free(Px_p_Pz);
  577. mp_free(Qx_m_Qz);
  578. mp_free(Qx_p_Qz);
  579. mp_free(PmQp);
  580. mp_free(PpQm);
  581. mp_free(Xpre);
  582. mp_free(Zpre);
  583. mp_free(Xpre2);
  584. mp_free(Zpre2);
  585. return S;
  586. } // WINSCP
  587. }
  588. MontgomeryPoint *ecc_montgomery_double(MontgomeryPoint *P)
  589. {
  590. MontgomeryCurve *mc = P->mc;
  591. MontgomeryPoint *D = ecc_montgomery_point_new_empty(mc);
  592. /*
  593. * To double a point in affine coordinates, in principle you can
  594. * use the same technique as for Weierstrass: differentiate the
  595. * curve equation to get the tangent line at the input point, use
  596. * that to get an expression for y which you substitute back into
  597. * the curve equation, and subtract the known two roots (in this
  598. * case both the same) from the x^2 coefficient of the resulting
  599. * cubic.
  600. *
  601. * In this case, we don't have an input y-coordinate, so you have
  602. * to do a bit of extra transformation to find a formula that can
  603. * work without it. The tangent formula is (3x^2 + 2ax + 1)/(2y),
  604. * and when that appears in the final formula it will be squared -
  605. * so we can substitute the y^2 in the denominator for the RHS of
  606. * the curve equation. Put together, that gives
  607. *
  608. * x_out = (x+1)^2 (x-1)^2 / 4(x^3+ax^2+x)
  609. *
  610. * and, as usual, the code below transforms that into projective
  611. * form to avoid the division.
  612. */
  613. mp_int *Px_m_Pz = monty_sub(mc->mc, P->X, P->Z);
  614. mp_int *Px_p_Pz = monty_add(mc->mc, P->X, P->Z);
  615. mp_int *Px_m_Pz_2 = monty_mul(mc->mc, Px_m_Pz, Px_m_Pz);
  616. mp_int *Px_p_Pz_2 = monty_mul(mc->mc, Px_p_Pz, Px_p_Pz);
  617. D->X = monty_mul(mc->mc, Px_m_Pz_2, Px_p_Pz_2);
  618. { // WINSCP
  619. mp_int *XZ = monty_mul(mc->mc, P->X, P->Z);
  620. mp_int *twoXZ = monty_add(mc->mc, XZ, XZ);
  621. mp_int *fourXZ = monty_add(mc->mc, twoXZ, twoXZ);
  622. mp_int *fourXZ_scaled = monty_mul(mc->mc, fourXZ, mc->aplus2over4);
  623. mp_int *Zpre = monty_add(mc->mc, Px_m_Pz_2, fourXZ_scaled);
  624. D->Z = monty_mul(mc->mc, fourXZ, Zpre);
  625. mp_free(Px_m_Pz);
  626. mp_free(Px_p_Pz);
  627. mp_free(Px_m_Pz_2);
  628. mp_free(Px_p_Pz_2);
  629. mp_free(XZ);
  630. mp_free(twoXZ);
  631. mp_free(fourXZ);
  632. mp_free(fourXZ_scaled);
  633. mp_free(Zpre);
  634. } // WINSCP
  635. return D;
  636. }
  637. static void ecc_montgomery_normalise(MontgomeryPoint *mp)
  638. {
  639. MontgomeryCurve *mc = mp->mc;
  640. mp_int *zinv = monty_invert(mc->mc, mp->Z);
  641. monty_mul_into(mc->mc, mp->X, mp->X, zinv);
  642. mp_free(zinv);
  643. mp_copy_into(mp->Z, monty_identity(mc->mc));
  644. }
  645. MontgomeryPoint *ecc_montgomery_multiply(MontgomeryPoint *B, mp_int *n)
  646. {
  647. /*
  648. * 'Montgomery ladder' technique, to compute an arbitrary integer
  649. * multiple of B under the constraint that you can only add two
  650. * unequal points if you also know their difference.
  651. *
  652. * The setup is that you maintain two curve points one of which is
  653. * always the other one plus B. Call them kB and (k+1)B, where k
  654. * is some integer that evolves as we go along. We begin by
  655. * doubling the input B, to initialise those points to B and 2B,
  656. * so that k=1.
  657. *
  658. * At each stage, we add kB and (k+1)B together - which we can do
  659. * under the differential-addition constraint because we know
  660. * their difference is always just B - to give us (2k+1)B. Then we
  661. * double one of kB or (k+1)B, and depending on which one we
  662. * choose, we end up with (2k)B or (2k+2)B. Either way, that
  663. * differs by B from the other value we've just computed. So in
  664. * each iteration, we do one diff-add and one doubling, plus a
  665. * couple of conditional swaps to choose which value we double and
  666. * which way round we put the output points, and the effect is to
  667. * replace k with either 2k or 2k+1, which we choose based on the
  668. * appropriate bit of the desired exponent.
  669. *
  670. * This routine doesn't assume we know the exact location of the
  671. * topmost set bit of the exponent. So to maintain constant time
  672. * it does an iteration for every _potential_ bit, starting from
  673. * the top downwards; after each iteration in which we haven't
  674. * seen a set exponent bit yet, we just overwrite the two points
  675. * with B and 2B again,
  676. */
  677. MontgomeryPoint *two_B = ecc_montgomery_double(B);
  678. MontgomeryPoint *k_B = ecc_montgomery_point_copy(B);
  679. MontgomeryPoint *kplus1_B = ecc_montgomery_point_copy(two_B);
  680. unsigned not_started_yet = 1;
  681. size_t bitindex; // WINSCP
  682. for (bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
  683. unsigned nbit = mp_get_bit(n, bitindex);
  684. MontgomeryPoint *sum = ecc_montgomery_diff_add(k_B, kplus1_B, B);
  685. ecc_montgomery_cond_swap(k_B, kplus1_B, nbit);
  686. { // WINSCP
  687. MontgomeryPoint *other = ecc_montgomery_double(k_B);
  688. ecc_montgomery_point_free(k_B);
  689. ecc_montgomery_point_free(kplus1_B);
  690. k_B = other;
  691. kplus1_B = sum;
  692. ecc_montgomery_cond_swap(k_B, kplus1_B, nbit);
  693. ecc_montgomery_cond_overwrite(k_B, B, not_started_yet);
  694. ecc_montgomery_cond_overwrite(kplus1_B, two_B, not_started_yet);
  695. not_started_yet &= ~nbit;
  696. } // WINSCP
  697. }
  698. ecc_montgomery_point_free(two_B);
  699. ecc_montgomery_point_free(kplus1_B);
  700. return k_B;
  701. }
  702. void ecc_montgomery_get_affine(MontgomeryPoint *mp, mp_int **x)
  703. {
  704. MontgomeryCurve *mc = mp->mc;
  705. ecc_montgomery_normalise(mp);
  706. if (x)
  707. *x = monty_export(mc->mc, mp->X);
  708. }
  709. /* ----------------------------------------------------------------------
  710. * Twisted Edwards curves.
  711. */
  712. struct EdwardsPoint {
  713. /*
  714. * We represent an Edwards curve point in 'extended coordinates'.
  715. * There's more than one coordinate system going by that name,
  716. * unfortunately. These ones have the semantics that X,Y,Z are
  717. * ordinary projective coordinates (so x=X/Z and y=Y/Z), but also,
  718. * we store the extra value T = xyZ = XY/Z.
  719. */
  720. mp_int *X, *Y, *Z, *T;
  721. EdwardsCurve *ec;
  722. };
  723. struct EdwardsCurve {
  724. /* Prime modulus of the finite field. */
  725. mp_int *p;
  726. /* Montgomery context for arithmetic mod p. */
  727. MontyContext *mc;
  728. /* Modsqrt context for point decompression. */
  729. ModsqrtContext *sc;
  730. /* Parameters of the curve, in Montgomery-multiplication
  731. * transformed form. */
  732. mp_int *d, *a;
  733. };
  734. EdwardsCurve *ecc_edwards_curve(mp_int *p, mp_int *d, mp_int *a,
  735. mp_int *nonsquare_mod_p)
  736. {
  737. EdwardsCurve *ec = snew(EdwardsCurve);
  738. ec->p = mp_copy(p);
  739. ec->mc = monty_new(p);
  740. ec->d = monty_import(ec->mc, d);
  741. ec->a = monty_import(ec->mc, a);
  742. if (nonsquare_mod_p)
  743. ec->sc = modsqrt_new(p, nonsquare_mod_p);
  744. else
  745. ec->sc = NULL;
  746. return ec;
  747. }
  748. void ecc_edwards_curve_free(EdwardsCurve *ec)
  749. {
  750. mp_free(ec->p);
  751. mp_free(ec->d);
  752. mp_free(ec->a);
  753. monty_free(ec->mc);
  754. if (ec->sc)
  755. modsqrt_free(ec->sc);
  756. sfree(ec);
  757. }
  758. static EdwardsPoint *ecc_edwards_point_new_empty(EdwardsCurve *ec)
  759. {
  760. EdwardsPoint *ep = snew(EdwardsPoint);
  761. ep->ec = ec;
  762. ep->X = ep->Y = ep->Z = ep->T = NULL;
  763. return ep;
  764. }
  765. static EdwardsPoint *ecc_edwards_point_new_imported(
  766. EdwardsCurve *ec, mp_int *monty_x, mp_int *monty_y)
  767. {
  768. EdwardsPoint *ep = ecc_edwards_point_new_empty(ec);
  769. ep->X = monty_x;
  770. ep->Y = monty_y;
  771. ep->T = monty_mul(ec->mc, ep->X, ep->Y);
  772. ep->Z = mp_copy(monty_identity(ec->mc));
  773. return ep;
  774. }
  775. EdwardsPoint *ecc_edwards_point_new(
  776. EdwardsCurve *ec, mp_int *x, mp_int *y)
  777. {
  778. return ecc_edwards_point_new_imported(
  779. ec, monty_import(ec->mc, x), monty_import(ec->mc, y));
  780. }
  781. EdwardsPoint *ecc_edwards_point_copy(EdwardsPoint *orig)
  782. {
  783. EdwardsPoint *ep = ecc_edwards_point_new_empty(orig->ec);
  784. ep->X = mp_copy(orig->X);
  785. ep->Y = mp_copy(orig->Y);
  786. ep->Z = mp_copy(orig->Z);
  787. ep->T = mp_copy(orig->T);
  788. return ep;
  789. }
  790. void ecc_edwards_point_free(EdwardsPoint *ep)
  791. {
  792. mp_free(ep->X);
  793. mp_free(ep->Y);
  794. mp_free(ep->Z);
  795. mp_free(ep->T);
  796. smemclr(ep, sizeof(*ep));
  797. sfree(ep);
  798. }
  799. EdwardsPoint *ecc_edwards_point_new_from_y(
  800. EdwardsCurve *ec, mp_int *yorig, unsigned desired_x_parity)
  801. {
  802. pinitassert(ec->sc);
  803. /*
  804. * The curve equation is ax^2 + y^2 = 1 + dx^2y^2, which
  805. * rearranges to x^2(dy^2-a) = y^2-1. So we compute
  806. * (y^2-1)/(dy^2-a) and take its square root.
  807. */
  808. unsigned success;
  809. mp_int *y = monty_import(ec->mc, yorig);
  810. mp_int *y2 = monty_mul(ec->mc, y, y);
  811. mp_int *dy2 = monty_mul(ec->mc, ec->d, y2);
  812. mp_int *dy2ma = monty_sub(ec->mc, dy2, ec->a);
  813. mp_int *y2m1 = monty_sub(ec->mc, y2, monty_identity(ec->mc));
  814. mp_int *recip_denominator = monty_invert(ec->mc, dy2ma);
  815. mp_int *radicand = monty_mul(ec->mc, y2m1, recip_denominator);
  816. mp_int *x = monty_modsqrt(ec->sc, radicand, &success);
  817. mp_free(y2);
  818. mp_free(dy2);
  819. mp_free(dy2ma);
  820. mp_free(y2m1);
  821. mp_free(recip_denominator);
  822. mp_free(radicand);
  823. if (!success) {
  824. /* Failure! x^2 worked out to be a number that has no square
  825. * root mod p. In this situation there's no point in trying to
  826. * be time-constant, since the protocol sequence is going to
  827. * diverge anyway when we complain to whoever gave us this
  828. * bogus value. */
  829. mp_free(x);
  830. mp_free(y);
  831. return NULL;
  832. }
  833. /*
  834. * Choose whichever of x and p-x has the specified parity (of its
  835. * lowest positive residue mod p).
  836. */
  837. { // WINSCP
  838. mp_int *tmp = monty_export(ec->mc, x);
  839. unsigned flip = (mp_get_bit(tmp, 0) ^ desired_x_parity) & 1;
  840. mp_sub_into(tmp, ec->p, x);
  841. mp_select_into(x, x, tmp, flip);
  842. mp_free(tmp);
  843. } // WINSCP
  844. return ecc_edwards_point_new_imported(ec, x, y);
  845. }
  846. static void ecc_edwards_cond_overwrite(
  847. EdwardsPoint *dest, EdwardsPoint *src, unsigned overwrite)
  848. {
  849. mp_select_into(dest->X, dest->X, src->X, overwrite);
  850. mp_select_into(dest->Y, dest->Y, src->Y, overwrite);
  851. mp_select_into(dest->Z, dest->Z, src->Z, overwrite);
  852. mp_select_into(dest->T, dest->T, src->T, overwrite);
  853. }
  854. static void ecc_edwards_cond_swap(
  855. EdwardsPoint *P, EdwardsPoint *Q, unsigned swap)
  856. {
  857. mp_cond_swap(P->X, Q->X, swap);
  858. mp_cond_swap(P->Y, Q->Y, swap);
  859. mp_cond_swap(P->Z, Q->Z, swap);
  860. mp_cond_swap(P->T, Q->T, swap);
  861. }
  862. EdwardsPoint *ecc_edwards_add(EdwardsPoint *P, EdwardsPoint *Q)
  863. {
  864. EdwardsCurve *ec = P->ec;
  865. assert(Q->ec == ec);
  866. { // WINSCP
  867. EdwardsPoint *S = ecc_edwards_point_new_empty(ec);
  868. /*
  869. * The affine rule for Edwards addition of (x1,y1) and (x2,y2) is
  870. *
  871. * x_out = (x1 y2 + y1 x2) / (1 + d x1 x2 y1 y2)
  872. * y_out = (y1 y2 - a x1 x2) / (1 - d x1 x2 y1 y2)
  873. *
  874. * The formulae below are listed as 'add-2008-hwcd' in
  875. * https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html
  876. *
  877. * and if you undo the careful optimisation to find out what
  878. * they're actually computing, it comes out to
  879. *
  880. * X_out = (X1 Y2 + Y1 X2) (Z1 Z2 - d T1 T2)
  881. * Y_out = (Y1 Y2 - a X1 X2) (Z1 Z2 + d T1 T2)
  882. * Z_out = (Z1 Z2 - d T1 T2) (Z1 Z2 + d T1 T2)
  883. * T_out = (X1 Y2 + Y1 X2) (Y1 Y2 - a X1 X2)
  884. */
  885. mp_int *PxQx = monty_mul(ec->mc, P->X, Q->X);
  886. mp_int *PyQy = monty_mul(ec->mc, P->Y, Q->Y);
  887. mp_int *PtQt = monty_mul(ec->mc, P->T, Q->T);
  888. mp_int *PzQz = monty_mul(ec->mc, P->Z, Q->Z);
  889. mp_int *Psum = monty_add(ec->mc, P->X, P->Y);
  890. mp_int *Qsum = monty_add(ec->mc, Q->X, Q->Y);
  891. mp_int *aPxQx = monty_mul(ec->mc, ec->a, PxQx);
  892. mp_int *dPtQt = monty_mul(ec->mc, ec->d, PtQt);
  893. mp_int *sumprod = monty_mul(ec->mc, Psum, Qsum);
  894. mp_int *xx_p_yy = monty_add(ec->mc, PxQx, PyQy);
  895. mp_int *E = monty_sub(ec->mc, sumprod, xx_p_yy);
  896. mp_int *F = monty_sub(ec->mc, PzQz, dPtQt);
  897. mp_int *G = monty_add(ec->mc, PzQz, dPtQt);
  898. mp_int *H = monty_sub(ec->mc, PyQy, aPxQx);
  899. S->X = monty_mul(ec->mc, E, F);
  900. S->Z = monty_mul(ec->mc, F, G);
  901. S->Y = monty_mul(ec->mc, G, H);
  902. S->T = monty_mul(ec->mc, H, E);
  903. mp_free(PxQx);
  904. mp_free(PyQy);
  905. mp_free(PtQt);
  906. mp_free(PzQz);
  907. mp_free(Psum);
  908. mp_free(Qsum);
  909. mp_free(aPxQx);
  910. mp_free(dPtQt);
  911. mp_free(sumprod);
  912. mp_free(xx_p_yy);
  913. mp_free(E);
  914. mp_free(F);
  915. mp_free(G);
  916. mp_free(H);
  917. return S;
  918. } // WINSCP
  919. }
  920. static void ecc_edwards_normalise(EdwardsPoint *ep)
  921. {
  922. EdwardsCurve *ec = ep->ec;
  923. mp_int *zinv = monty_invert(ec->mc, ep->Z);
  924. monty_mul_into(ec->mc, ep->X, ep->X, zinv);
  925. monty_mul_into(ec->mc, ep->Y, ep->Y, zinv);
  926. mp_free(zinv);
  927. mp_copy_into(ep->Z, monty_identity(ec->mc));
  928. monty_mul_into(ec->mc, ep->T, ep->X, ep->Y);
  929. }
  930. EdwardsPoint *ecc_edwards_multiply(EdwardsPoint *B, mp_int *n)
  931. {
  932. EdwardsPoint *two_B = ecc_edwards_add(B, B);
  933. EdwardsPoint *k_B = ecc_edwards_point_copy(B);
  934. EdwardsPoint *kplus1_B = ecc_edwards_point_copy(two_B);
  935. /*
  936. * Another copy of the same exponentiation routine following the
  937. * pattern of the Montgomery ladder, because it works as well as
  938. * any other technique and this way I didn't have to debug two of
  939. * them.
  940. */
  941. unsigned not_started_yet = 1;
  942. size_t bitindex; // WINSCP
  943. for (bitindex = mp_max_bits(n); bitindex-- > 0 ;) {
  944. unsigned nbit = mp_get_bit(n, bitindex);
  945. EdwardsPoint *sum = ecc_edwards_add(k_B, kplus1_B);
  946. ecc_edwards_cond_swap(k_B, kplus1_B, nbit);
  947. { // WINSCP
  948. EdwardsPoint *other = ecc_edwards_add(k_B, k_B);
  949. ecc_edwards_point_free(k_B);
  950. ecc_edwards_point_free(kplus1_B);
  951. k_B = other;
  952. kplus1_B = sum;
  953. ecc_edwards_cond_swap(k_B, kplus1_B, nbit);
  954. ecc_edwards_cond_overwrite(k_B, B, not_started_yet);
  955. ecc_edwards_cond_overwrite(kplus1_B, two_B, not_started_yet);
  956. not_started_yet &= ~nbit;
  957. } // WINSCP
  958. }
  959. ecc_edwards_point_free(two_B);
  960. ecc_edwards_point_free(kplus1_B);
  961. return k_B;
  962. }
  963. /*
  964. * Helper routine to determine whether two values each given as a pair
  965. * of projective coordinates represent the same affine value.
  966. */
  967. static inline unsigned projective_eq(
  968. MontyContext *mc, mp_int *An, mp_int *Ad,
  969. mp_int *Bn, mp_int *Bd)
  970. {
  971. mp_int *AnBd = monty_mul(mc, An, Bd);
  972. mp_int *BnAd = monty_mul(mc, Bn, Ad);
  973. unsigned toret = mp_cmp_eq(AnBd, BnAd);
  974. mp_free(AnBd);
  975. mp_free(BnAd);
  976. return toret;
  977. }
  978. unsigned ecc_edwards_eq(EdwardsPoint *P, EdwardsPoint *Q)
  979. {
  980. EdwardsCurve *ec = P->ec;
  981. assert(Q->ec == ec);
  982. return (projective_eq(ec->mc, P->X, P->Z, Q->X, Q->Z) &
  983. projective_eq(ec->mc, P->Y, P->Z, Q->Y, Q->Z));
  984. }
  985. void ecc_edwards_get_affine(EdwardsPoint *ep, mp_int **x, mp_int **y)
  986. {
  987. EdwardsCurve *ec = ep->ec;
  988. ecc_edwards_normalise(ep);
  989. if (x)
  990. *x = monty_export(ec->mc, ep->X);
  991. if (y)
  992. *y = monty_export(ec->mc, ep->Y);
  993. }