ecc.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #ifndef PUTTY_ECC_H
  2. #define PUTTY_ECC_H
  3. /*
  4. * Arithmetic functions for the various kinds of elliptic curves used
  5. * by PuTTY's public-key cryptography.
  6. *
  7. * All of these elliptic curves are over the finite field whose order
  8. * is a large prime p. (Elliptic curves over a field of order 2^n are
  9. * also known, but PuTTY currently has no need of them.)
  10. */
  11. /* ----------------------------------------------------------------------
  12. * Weierstrass curves (or rather, 'short form' Weierstrass curves).
  13. *
  14. * A curve in this form is defined by two parameters a,b, and the
  15. * non-identity points on the curve are represented by (x,y) (the
  16. * 'affine coordinates') such that y^2 = x^3 + ax + b.
  17. *
  18. * The identity element of the curve's group is an additional 'point
  19. * at infinity', which is considered to be the third point on the
  20. * intersection of the curve with any vertical line. Hence, the
  21. * inverse of the point (x,y) is (x,-y).
  22. */
  23. /*
  24. * Create and destroy Weierstrass curve data structures. The mandatory
  25. * parameters to the constructor are the prime modulus p, and the
  26. * curve parameters a,b.
  27. *
  28. * 'nonsquare_mod_p' is an optional extra parameter, only needed by
  29. * ecc_edwards_point_new_from_y which has to take a modular square
  30. * root. You can pass it as NULL if you don't need that function.
  31. */
  32. WeierstrassCurve *ecc_weierstrass_curve(
  33. mp_int *p, mp_int *a, mp_int *b, mp_int *nonsquare_mod_p);
  34. void ecc_weierstrass_curve_free(WeierstrassCurve *);
  35. /*
  36. * Create points on a Weierstrass curve, given the curve.
  37. *
  38. * point_new_identity returns the special identity point.
  39. * point_new(x,y) returns the non-identity point with the given affine
  40. * coordinates.
  41. *
  42. * point_new_from_x constructs a non-identity point given only the
  43. * x-coordinate, by using the curve equation to work out what y has to
  44. * be. Of course the equation only tells you y^2, so it only
  45. * determines y up to sign; the parameter desired_y_parity controls
  46. * which of the two values of y you get, by saying whether you'd like
  47. * its minimal non-negative residue mod p to be even or odd. (Of
  48. * course, since p itself is odd, exactly one of y and p-y is odd.)
  49. * This function has to take a modular square root, so it will only
  50. * work if you passed in a non-square mod p when constructing the
  51. * curve.
  52. */
  53. WeierstrassPoint *ecc_weierstrass_point_new_identity(WeierstrassCurve *curve);
  54. WeierstrassPoint *ecc_weierstrass_point_new(
  55. WeierstrassCurve *curve, mp_int *x, mp_int *y);
  56. WeierstrassPoint *ecc_weierstrass_point_new_from_x(
  57. WeierstrassCurve *curve, mp_int *x, unsigned desired_y_parity);
  58. /* Memory management: copy and free points. */
  59. void ecc_weierstrass_point_copy_into(
  60. WeierstrassPoint *dest, WeierstrassPoint *src);
  61. WeierstrassPoint *ecc_weierstrass_point_copy(WeierstrassPoint *orig);
  62. void ecc_weierstrass_point_free(WeierstrassPoint *point);
  63. /* Check whether a point is actually on the curve. */
  64. unsigned ecc_weierstrass_point_valid(WeierstrassPoint *);
  65. /*
  66. * Add two points and return their sum. This function is fully
  67. * general: it should do the right thing if the two inputs are the
  68. * same, or if either (or both) of the input points is the identity,
  69. * or if the two input points are inverses so the output is the
  70. * identity. However, it pays for that generality by being slower than
  71. * the special-purpose functions below..
  72. */
  73. WeierstrassPoint *ecc_weierstrass_add_general(
  74. WeierstrassPoint *, WeierstrassPoint *);
  75. /*
  76. * Fast but less general arithmetic functions: add two points on the
  77. * condition that they are not equal and neither is the identity, and
  78. * add a point to itself.
  79. */
  80. WeierstrassPoint *ecc_weierstrass_add(WeierstrassPoint *, WeierstrassPoint *);
  81. WeierstrassPoint *ecc_weierstrass_double(WeierstrassPoint *);
  82. /*
  83. * Compute an integer multiple of a point. Not guaranteed to work
  84. * unless the integer argument is less than the order of the point in
  85. * the group (because it won't cope if an identity element shows up in
  86. * any intermediate product).
  87. */
  88. WeierstrassPoint *ecc_weierstrass_multiply(WeierstrassPoint *, mp_int *);
  89. /*
  90. * Query functions to get the value of a point back out. is_identity
  91. * tells you whether the point is the identity; if it isn't, then
  92. * get_affine will retrieve one or both of its affine coordinates.
  93. * (You can pass NULL as either output pointer, if you don't need that
  94. * coordinate as output.)
  95. */
  96. unsigned ecc_weierstrass_is_identity(WeierstrassPoint *wp);
  97. void ecc_weierstrass_get_affine(WeierstrassPoint *wp, mp_int **x, mp_int **y);
  98. /* ----------------------------------------------------------------------
  99. * Montgomery curves.
  100. *
  101. * A curve in this form is defined by two parameters a,b, and the
  102. * curve equation is by^2 = x^3 + ax^2 + x.
  103. *
  104. * As with Weierstrass curves, there's an additional point at infinity
  105. * that is the identity element, and the inverse of (x,y) is (x,-y).
  106. *
  107. * However, we don't actually work with full (x,y) pairs. We just
  108. * store the x-coordinate (so what we're really representing is not a
  109. * specific point on the curve but a two-point set {P,-P}). This means
  110. * you can't quite do point addition, because if you're given {P,-P}
  111. * and {Q,-Q} as input, you can work out a pair of x-coordinates that
  112. * are those of P-Q and P+Q, but you don't know which is which.
  113. *
  114. * Instead, the basic operation is 'differential addition', in which
  115. * you are given three parameters P, Q and P-Q and you return P+Q. (As
  116. * well as disambiguating which of the possible answers you want, that
  117. * extra input also enables a fast formulae for computing it. This
  118. * fast formula is more or less why Montgomery curves are useful in
  119. * the first place.)
  120. *
  121. * Doubling a point is still possible to do unambiguously, so you can
  122. * still compute an integer multiple of P if you start by making 2P
  123. * and then doing a series of differential additions.
  124. */
  125. /*
  126. * Create and destroy Montgomery curve data structures.
  127. */
  128. MontgomeryCurve *ecc_montgomery_curve(mp_int *p, mp_int *a, mp_int *b);
  129. void ecc_montgomery_curve_free(MontgomeryCurve *);
  130. /*
  131. * Create, copy and free points on the curve. We don't need to
  132. * explicitly represent the identity for this application.
  133. */
  134. MontgomeryPoint *ecc_montgomery_point_new(MontgomeryCurve *mc, mp_int *x);
  135. void ecc_montgomery_point_copy_into(
  136. MontgomeryPoint *dest, MontgomeryPoint *src);
  137. MontgomeryPoint *ecc_montgomery_point_copy(MontgomeryPoint *orig);
  138. void ecc_montgomery_point_free(MontgomeryPoint *mp);
  139. /*
  140. * Basic arithmetic routines: differential addition and point-
  141. * doubling. Each of these assumes that no special cases come up - no
  142. * input or output point should be the identity, and in diff_add, P
  143. * and Q shouldn't be the same.
  144. */
  145. MontgomeryPoint *ecc_montgomery_diff_add(
  146. MontgomeryPoint *P, MontgomeryPoint *Q, MontgomeryPoint *PminusQ);
  147. MontgomeryPoint *ecc_montgomery_double(MontgomeryPoint *P);
  148. /*
  149. * Compute an integer multiple of a point.
  150. */
  151. MontgomeryPoint *ecc_montgomery_multiply(MontgomeryPoint *, mp_int *);
  152. /*
  153. * Return the affine x-coordinate of a point.
  154. */
  155. void ecc_montgomery_get_affine(MontgomeryPoint *mp, mp_int **x);
  156. /*
  157. * Test whether a point is the curve identity.
  158. */
  159. unsigned ecc_montgomery_is_identity(MontgomeryPoint *mp);
  160. /* ----------------------------------------------------------------------
  161. * Twisted Edwards curves.
  162. *
  163. * A curve in this form is defined by two parameters d,a, and the
  164. * curve equation is a x^2 + y^2 = 1 + d x^2 y^2.
  165. *
  166. * Apparently if you ask a proper algebraic geometer they'll tell you
  167. * that this is technically not an actual elliptic curve. Certainly it
  168. * doesn't work quite the same way as the other kinds: in this form,
  169. * there is no need for a point at infinity, because the identity
  170. * element is represented by the affine coordinates (0,1). And you
  171. * invert a point by negating its x rather than y coordinate: the
  172. * inverse of (x,y) is (-x,y).
  173. *
  174. * The usefulness of this representation is that the addition formula
  175. * is 'strongly unified', meaning that the same formula works for any
  176. * input and output points, without needing special cases for the
  177. * identity or for doubling.
  178. */
  179. /*
  180. * Create and destroy Edwards curve data structures.
  181. *
  182. * Similarly to ecc_weierstrass_curve, you don't have to provide
  183. * nonsquare_mod_p if you don't need ecc_edwards_point_new_from_y.
  184. */
  185. EdwardsCurve *ecc_edwards_curve(
  186. mp_int *p, mp_int *d, mp_int *a, mp_int *nonsquare_mod_p);
  187. void ecc_edwards_curve_free(EdwardsCurve *);
  188. /*
  189. * Create points.
  190. *
  191. * There's no need to have a separate function to create the identity
  192. * point, because you can just pass x=0 and y=1 to the usual function.
  193. *
  194. * Similarly to the Weierstrass curve, ecc_edwards_point_new_from_y
  195. * creates a point given only its y-coordinate and the desired parity
  196. * of its x-coordinate, and you can only call it if you provided the
  197. * optional nonsquare_mod_p argument when creating the curve.
  198. */
  199. EdwardsPoint *ecc_edwards_point_new(
  200. EdwardsCurve *curve, mp_int *x, mp_int *y);
  201. EdwardsPoint *ecc_edwards_point_new_from_y(
  202. EdwardsCurve *curve, mp_int *y, unsigned desired_x_parity);
  203. /* Copy and free points. */
  204. void ecc_edwards_point_copy_into(EdwardsPoint *dest, EdwardsPoint *src);
  205. EdwardsPoint *ecc_edwards_point_copy(EdwardsPoint *orig);
  206. void ecc_edwards_point_free(EdwardsPoint *point);
  207. /*
  208. * Arithmetic: add two points, and calculate an integer multiple of a
  209. * point.
  210. */
  211. EdwardsPoint *ecc_edwards_add(EdwardsPoint *, EdwardsPoint *);
  212. EdwardsPoint *ecc_edwards_multiply(EdwardsPoint *, mp_int *);
  213. /*
  214. * Query functions: compare two points for equality, and return the
  215. * affine coordinates of a point.
  216. */
  217. unsigned ecc_edwards_eq(EdwardsPoint *, EdwardsPoint *);
  218. void ecc_edwards_get_affine(EdwardsPoint *wp, mp_int **x, mp_int **y);
  219. #endif /* PUTTY_ECC_H */