You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

274 lines
7.9 KiB

  1. /* Copyright (c) 2015 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. /**
  5. * @file decaf.h
  6. * @author Mike Hamburg
  7. * @brief A group of prime order p.
  8. *
  9. * The Decaf library implements cryptographic operations on a an elliptic curve
  10. * group of prime order p. It accomplishes this by using a twisted Edwards
  11. * curve (isogenous to Ed448-Goldilocks) and wiping out the cofactor.
  12. *
  13. * The formulas are all complete and have no special cases, except that
  14. * decaf_decode can fail because not every sequence of bytes is a valid group
  15. * element.
  16. *
  17. * The formulas contain no data-dependent branches, timing or memory accesses.
  18. */
  19. #ifndef __DECAF_H__
  20. #define __DECAF_H__ 1
  21. #include <stdint.h>
  22. typedef uint64_t decaf_word_t, decaf_bool_t;
  23. /* TODO: prefix all these operations and factor to support multiple curves. */
  24. /* TODO: perfield, so when 25519 hits this will change */
  25. #define DECAF_FIELD_BITS 448
  26. #define DECAF_LIMBS (1 + (512-1)/8/sizeof(decaf_word_t))
  27. #define DECAF_SCALAR_LIMBS (1 + (448-3)/8/sizeof(decaf_word_t))
  28. /** Number of bytes in a serialized point. One less bit than you'd think. */
  29. #define DECAF_SER_BYTES ((DECAF_FIELD_BITS+6)/8)
  30. /** Twisted Edwards (-1,d-1) extended homogeneous coordinates */
  31. typedef struct decaf_point_s {
  32. decaf_word_t x[DECAF_LIMBS],y[DECAF_LIMBS],z[DECAF_LIMBS],t[DECAF_LIMBS];
  33. } decaf_point_t[1];
  34. typedef struct decaf_scalar_s {
  35. decaf_word_t limb[DECAF_SCALAR_LIMBS];
  36. } decaf_scalar_t[1];
  37. static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1, DECAF_FALSE = 0;
  38. /** NB Success is -1, failure is 0. TODO: see if people would rather the reverse. */
  39. static const decaf_bool_t DECAF_SUCCESS = DECAF_TRUE, DECAF_FAILURE = DECAF_FALSE;
  40. /** The identity point on the curve. */
  41. const decaf_point_t decaf_identity;
  42. /** An arbitrarily chosen base point on the curve. TODO: define */
  43. const decaf_point_t decaf_basepoint;
  44. #ifdef __cplusplus
  45. extern "C" {
  46. #endif
  47. /* Goldilocks' build flags default to hidden and stripping executables. */
  48. #define API_VIS __attribute__((visibility("default")))
  49. #define WARN_UNUSED __attribute__((warn_unused_result))
  50. #define NONNULL1 __attribute__((nonnull(1)))
  51. #define NONNULL2 __attribute__((nonnull(1,2)))
  52. #define NONNULL3 __attribute__((nonnull(1,2,3)))
  53. // TODO: ser, deser, inv?.
  54. // FIXME: scalar math is untested, and therefore probably wrong.
  55. /**
  56. * @brief Add two scalars. The scalars may use the same memory.
  57. * @param [in] a One scalar.
  58. * @param [in] b Another scalar.
  59. * @param [out] out a+b.
  60. */
  61. void decaf_add_scalars (
  62. decaf_scalar_t out,
  63. const decaf_scalar_t a,
  64. const decaf_scalar_t b
  65. ) API_VIS NONNULL3;
  66. /**
  67. * @brief Subtract two scalars. The scalars may use the same memory.
  68. * @param [in] a One scalar.
  69. * @param [in] b Another scalar.
  70. * @param [out] out a-b.
  71. */
  72. void decaf_sub_scalars (
  73. decaf_scalar_t out,
  74. const decaf_scalar_t a,
  75. const decaf_scalar_t b
  76. ) API_VIS NONNULL3;
  77. /**
  78. * @brief Multiply two scalars. The scalars may use the same memory.
  79. * @param [in] a One scalar.
  80. * @param [in] b Another scalar.
  81. * @param [out] out a*b.
  82. */
  83. void decaf_mul_scalars (
  84. decaf_scalar_t out,
  85. const decaf_scalar_t a,
  86. const decaf_scalar_t b
  87. ) API_VIS NONNULL3;
  88. /**
  89. * @brief Encode a point as a sequence of bytes.
  90. *
  91. * @param [out] ser The byte representation of the point.
  92. * @param [in] pt The point to encode.
  93. */
  94. void decaf_encode (
  95. uint8_t ser[DECAF_SER_BYTES],
  96. const decaf_point_t pt
  97. ) API_VIS NONNULL2;
  98. /**
  99. * @brief Decode a point from a sequence of bytes.
  100. *
  101. * Every point has a unique encoding, so not every
  102. * sequence of bytes is a valid encoding. If an invalid
  103. * encoding is given, the output is undefined.
  104. *
  105. * @param [out] pt The decoded point.
  106. * @param [in] ser The serialized version of the point.
  107. * @retval DECAF_SUCCESS The decoding succeeded.
  108. * @retval DECAF_FAILURE The decoding didn't succeed, because
  109. * ser does not represent a point.
  110. */
  111. decaf_bool_t decaf_decode (
  112. decaf_point_t pt,
  113. const uint8_t ser[DECAF_SER_BYTES],
  114. decaf_bool_t allow_identity
  115. ) API_VIS WARN_UNUSED NONNULL2;
  116. /**
  117. * @brief Copy a point. The input and output may alias,
  118. * in which case this function does nothing.
  119. *
  120. * @param [out] a A copy of the point.
  121. * @param [in] b Any point.
  122. */
  123. void decaf_copy (
  124. decaf_point_t a,
  125. const decaf_point_t b
  126. ) API_VIS NONNULL2;
  127. /**
  128. * @brief Test whether two points are equal. If yes, return
  129. * DECAF_TRUE, else return DECAF_FALSE.
  130. *
  131. * @param [in] a A point.
  132. * @param [in] b Another point.
  133. * @retval DECAF_TRUE The points are equal.
  134. * @retval DECAF_FALSE The points are not equal.
  135. */
  136. decaf_bool_t decaf_eq (
  137. const decaf_point_t a,
  138. const decaf_point_t b
  139. ) API_VIS WARN_UNUSED NONNULL2;
  140. /**
  141. * @brief Add two points to produce a third point. The
  142. * input points and output point can be pointers to the same
  143. * memory.
  144. *
  145. * @param [out] sum The sum a+b.
  146. * @param [in] a An addend.
  147. * @param [in] b An addend.
  148. */
  149. void decaf_add (
  150. decaf_point_t sum,
  151. const decaf_point_t a,
  152. const decaf_point_t b
  153. ) API_VIS NONNULL3;
  154. /**
  155. * @brief Subtract two points to produce a third point. The
  156. * input points and output point can be pointers to the same
  157. * memory.
  158. *
  159. * @param [out] sum The difference a-b.
  160. * @param [in] a The minuend.
  161. * @param [in] b The subtrahend.
  162. */
  163. void decaf_sub (
  164. decaf_point_t diff,
  165. const decaf_point_t a,
  166. const decaf_point_t b
  167. ) API_VIS NONNULL3;
  168. /**
  169. * @brief Multiply a base point by a scalar.
  170. *
  171. * @param [out] scaled The scaled point base*scalar
  172. * @param [in] base The point to be scaled.
  173. * @param [in] scalar The scalar to multilpy by.
  174. * @param [in] scalar_words The number of words in the scalar [TODO]
  175. */
  176. void decaf_scalarmul (
  177. decaf_point_t scaled,
  178. const decaf_point_t base,
  179. const decaf_word_t *scalar,
  180. unsigned int scalar_words
  181. ) API_VIS NONNULL3;
  182. /**
  183. * @brief Test that a point is valid, for debugging purposes.
  184. *
  185. * @param [in] point The number to test.
  186. * @retval DECAF_TRUE The point is valid.
  187. * @retval DECAF_FALSE The point is invalid.
  188. */
  189. decaf_bool_t decaf_valid (
  190. const decaf_point_t toTest
  191. ) API_VIS WARN_UNUSED NONNULL1;
  192. /**
  193. * @brief Almost-Elligator-like hash to curve.
  194. *
  195. * Call this function with the output of a hash to make a hash to the curve.
  196. *
  197. * This function runs Elligator2 on the decaf Jacobi quartic model. It then
  198. * uses the isogeny to put the result in twisted Edwards form. As a result,
  199. * it is safe (cannot produce points of order 4), and would be compatible with
  200. * hypothetical other implementations of Decaf using a Montgomery or untwisted
  201. * Edwards model.
  202. *
  203. * Unlike Elligator, this function may be up to 4:1 on [0,(p-1)/2]:
  204. * A factor of 2 due to the isogeny.
  205. * A factor of 2 because we quotient out the 2-torsion.
  206. * // TODO: check that it isn't more, especially for the identity point.
  207. *
  208. * Negating the input (mod q) results in the same point. Inverting the input
  209. * (mod q) results in the negative point. This is the same as Elligator.
  210. *
  211. * This function isn't quite indifferentiable from a random oracle.
  212. * However, it is suitable for many protocols, including SPEKE and SPAKE2 EE.
  213. * Furthermore, calling it twice with independent seeds and adding the results
  214. * is indifferentiable from a random oracle.
  215. *
  216. * @param [in] hashed_data Output of some hash function.
  217. * @param [out] pt The data hashed to the curve.
  218. */
  219. void decaf_nonuniform_map_to_curve (
  220. decaf_point_t pt,
  221. const unsigned char hashed_data[DECAF_SER_BYTES]
  222. ) API_VIS NONNULL2;
  223. /**
  224. * @brief Indifferentiable hash function encoding to curve.
  225. *
  226. * Equivalent to calling decaf_nonuniform_map_to_curve twice and adding.
  227. *
  228. * @param [in] hashed_data Output of some hash function.
  229. * @param [out] pt The data hashed to the curve.
  230. */
  231. void decaf_uniform_map_to_curve (
  232. decaf_point_t pt,
  233. const unsigned char hashed_data[2*DECAF_SER_BYTES]
  234. ) API_VIS NONNULL2;
  235. #undef API_VIS
  236. #undef WARN_UNUSED
  237. #undef NONNULL2
  238. #undef NONNULL3
  239. #ifdef __cplusplus
  240. }; /* extern "C" */
  241. #endif
  242. #endif /* __DECAF_H__ */