ecc-arithmetic.c 35 KB

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