ecc-arithmetic.c 37 KB

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