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.
 
 
 
 
 

722 lines
22 KiB

  1. /** @brief A group of prime order p, based on $(iso_to). */
  2. #include <decaf/common.h>
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. /** @cond internal */
  7. #define $(C_NS)_SCALAR_LIMBS (($(scalar_bits)-1)/DECAF_WORD_BITS+1)
  8. /** @endcond */
  9. /** The number of bits in a scalar */
  10. #define $(C_NS)_SCALAR_BITS $(scalar_bits)
  11. /** @cond internal */
  12. #ifndef __DECAF_$(gf_shortname)_GF_DEFINED__
  13. #define __DECAF_$(gf_shortname)_GF_DEFINED__ 1
  14. /** @brief Galois field element internal structure */
  15. typedef struct gf_$(gf_shortname)_s {
  16. decaf_word_t limb[$(gf_impl_bits)/DECAF_WORD_BITS];
  17. } __attribute__((aligned(32))) gf_$(gf_shortname)_s, gf_$(gf_shortname)_t[1];
  18. #endif /* __DECAF_$(gf_shortname)_GF_DEFINED__ */
  19. /** @endcond */
  20. /** Number of bytes in a serialized point. */
  21. #define $(C_NS)_SER_BYTES $((gf_bits-2)//8 + 1)
  22. /** Number of bytes in an elligated point. For now set the same as SER_BYTES
  23. * but could be different for other curves.
  24. */
  25. #define $(C_NS)_HASH_BYTES $((gf_bits-2)//8 + 1)
  26. /** Number of bytes in a serialized scalar. */
  27. #define $(C_NS)_SCALAR_BYTES $((scalar_bits-1)//8 + 1)
  28. /** Number of bits in the "which" field of an elligator inverse */
  29. #define $(C_NS)_INVERT_ELLIGATOR_WHICH_BITS $(ceil_log2(cofactor) + 7 + elligator_onto - ((gf_bits-2) % 8))
  30. /** The cofactor the curve would have, if we hadn't removed it */
  31. #define $(C_NS)_REMOVED_COFACTOR $(cofactor)
  32. /** Number of bytes in an x$(gf_shortname) public key */
  33. #define DECAF_X$(gf_shortname)_PUBLIC_BYTES $((gf_bits-1)//8 + 1)
  34. /** Number of bytes in an x$(gf_shortname) private key */
  35. #define DECAF_X$(gf_shortname)_PRIVATE_BYTES $((gf_bits-1)//8 + 1)
  36. /** Twisted Edwards extended homogeneous coordinates */
  37. typedef struct $(c_ns)_point_s {
  38. /** @cond internal */
  39. gf_$(gf_shortname)_t x,y,z,t;
  40. /** @endcond */
  41. } $(c_ns)_point_t[1];
  42. /** Precomputed table based on a point. Can be trivial implementation. */
  43. struct $(c_ns)_precomputed_s;
  44. /** Precomputed table based on a point. Can be trivial implementation. */
  45. typedef struct $(c_ns)_precomputed_s $(c_ns)_precomputed_s;
  46. /** Size and alignment of precomputed point tables. */
  47. extern const size_t $(c_ns)_sizeof_precomputed_s DECAF_API_VIS, $(c_ns)_alignof_precomputed_s DECAF_API_VIS;
  48. /** Scalar is stored packed, because we don't need the speed. */
  49. typedef struct $(c_ns)_scalar_s {
  50. /** @cond internal */
  51. decaf_word_t limb[$(C_NS)_SCALAR_LIMBS];
  52. /** @endcond */
  53. } $(c_ns)_scalar_t[1];
  54. /** A scalar equal to 1. */
  55. extern const $(c_ns)_scalar_t $(c_ns)_scalar_one DECAF_API_VIS;
  56. /** A scalar equal to 0. */
  57. extern const $(c_ns)_scalar_t $(c_ns)_scalar_zero DECAF_API_VIS;
  58. /** The identity point on the curve. */
  59. extern const $(c_ns)_point_t $(c_ns)_point_identity DECAF_API_VIS;
  60. /** An arbitrarily chosen base point on the curve. */
  61. extern const $(c_ns)_point_t $(c_ns)_point_base DECAF_API_VIS;
  62. /** Precomputed table for the base point on the curve. */
  63. extern const struct $(c_ns)_precomputed_s *$(c_ns)_precomputed_base DECAF_API_VIS;
  64. /**
  65. * @brief Read a scalar from wire format or from bytes.
  66. *
  67. * @param [in] ser Serialized form of a scalar.
  68. * @param [out] out Deserialized form.
  69. *
  70. * @retval DECAF_SUCCESS The scalar was correctly encoded.
  71. * @retval DECAF_FAILURE The scalar was greater than the modulus,
  72. * and has been reduced modulo that modulus.
  73. */
  74. decaf_error_t $(c_ns)_scalar_decode (
  75. $(c_ns)_scalar_t out,
  76. const unsigned char ser[$(C_NS)_SCALAR_BYTES]
  77. ) DECAF_API_VIS DECAF_WARN_UNUSED DECAF_NONNULL DECAF_NOINLINE;
  78. /**
  79. * @brief Read a scalar from wire format or from bytes. Reduces mod
  80. * scalar prime.
  81. *
  82. * @param [in] ser Serialized form of a scalar.
  83. * @param [in] ser_len Length of serialized form.
  84. * @param [out] out Deserialized form.
  85. */
  86. void $(c_ns)_scalar_decode_long (
  87. $(c_ns)_scalar_t out,
  88. const unsigned char *ser,
  89. size_t ser_len
  90. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  91. /**
  92. * @brief Serialize a scalar to wire format.
  93. *
  94. * @param [out] ser Serialized form of a scalar.
  95. * @param [in] s Deserialized scalar.
  96. */
  97. void $(c_ns)_scalar_encode (
  98. unsigned char ser[$(C_NS)_SCALAR_BYTES],
  99. const $(c_ns)_scalar_t s
  100. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_NOINLINE;
  101. /**
  102. * @brief Add two scalars. The scalars may use the same memory.
  103. * @param [in] a One scalar.
  104. * @param [in] b Another scalar.
  105. * @param [out] out a+b.
  106. */
  107. void $(c_ns)_scalar_add (
  108. $(c_ns)_scalar_t out,
  109. const $(c_ns)_scalar_t a,
  110. const $(c_ns)_scalar_t b
  111. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  112. /**
  113. * @brief Compare two scalars.
  114. * @param [in] a One scalar.
  115. * @param [in] b Another scalar.
  116. * @retval DECAF_TRUE The scalars are equal.
  117. * @retval DECAF_FALSE The scalars are not equal.
  118. */
  119. decaf_bool_t $(c_ns)_scalar_eq (
  120. const $(c_ns)_scalar_t a,
  121. const $(c_ns)_scalar_t b
  122. ) DECAF_API_VIS DECAF_WARN_UNUSED DECAF_NONNULL DECAF_NOINLINE;
  123. /**
  124. * @brief Subtract two scalars. The scalars may use the same memory.
  125. * @param [in] a One scalar.
  126. * @param [in] b Another scalar.
  127. * @param [out] out a-b.
  128. */
  129. void $(c_ns)_scalar_sub (
  130. $(c_ns)_scalar_t out,
  131. const $(c_ns)_scalar_t a,
  132. const $(c_ns)_scalar_t b
  133. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  134. /**
  135. * @brief Multiply two scalars. The scalars may use the same memory.
  136. * @param [in] a One scalar.
  137. * @param [in] b Another scalar.
  138. * @param [out] out a*b.
  139. */
  140. void $(c_ns)_scalar_mul (
  141. $(c_ns)_scalar_t out,
  142. const $(c_ns)_scalar_t a,
  143. const $(c_ns)_scalar_t b
  144. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  145. /**
  146. * @brief Halve a scalar. The scalars may use the same memory.
  147. * @param [in] a A scalar.
  148. * @param [out] out a/2.
  149. */
  150. void $(c_ns)_scalar_halve (
  151. $(c_ns)_scalar_t out,
  152. const $(c_ns)_scalar_t a
  153. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  154. /**
  155. * @brief Invert a scalar. When passed zero, return 0. The input and output may alias.
  156. * @param [in] a A scalar.
  157. * @param [out] out 1/a.
  158. * @return DECAF_SUCCESS The input is nonzero.
  159. */
  160. decaf_error_t $(c_ns)_scalar_invert (
  161. $(c_ns)_scalar_t out,
  162. const $(c_ns)_scalar_t a
  163. ) DECAF_API_VIS DECAF_WARN_UNUSED DECAF_NONNULL DECAF_NOINLINE;
  164. /**
  165. * @brief Copy a scalar. The scalars may use the same memory, in which
  166. * case this function does nothing.
  167. * @param [in] a A scalar.
  168. * @param [out] out Will become a copy of a.
  169. */
  170. static inline void DECAF_NONNULL $(c_ns)_scalar_copy (
  171. $(c_ns)_scalar_t out,
  172. const $(c_ns)_scalar_t a
  173. ) {
  174. *out = *a;
  175. }
  176. /**
  177. * @brief Set a scalar to an unsigned 64-bit integer.
  178. * @param [in] a An integer.
  179. * @param [out] out Will become equal to a.
  180. */
  181. void $(c_ns)_scalar_set_unsigned (
  182. $(c_ns)_scalar_t out,
  183. uint64_t a
  184. ) DECAF_API_VIS DECAF_NONNULL;
  185. /**
  186. * @brief Encode a point as a sequence of bytes.
  187. *
  188. * @param [out] ser The byte representation of the point.
  189. * @param [in] pt The point to encode.
  190. */
  191. void $(c_ns)_point_encode (
  192. uint8_t ser[$(C_NS)_SER_BYTES],
  193. const $(c_ns)_point_t pt
  194. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  195. /**
  196. * @brief Decode a point from a sequence of bytes.
  197. *
  198. * Every point has a unique encoding, so not every
  199. * sequence of bytes is a valid encoding. If an invalid
  200. * encoding is given, the output is undefined.
  201. *
  202. * @param [out] pt The decoded point.
  203. * @param [in] ser The serialized version of the point.
  204. * @param [in] allow_identity DECAF_TRUE if the identity is a legal input.
  205. * @retval DECAF_SUCCESS The decoding succeeded.
  206. * @retval DECAF_FAILURE The decoding didn't succeed, because
  207. * ser does not represent a point.
  208. */
  209. decaf_error_t $(c_ns)_point_decode (
  210. $(c_ns)_point_t pt,
  211. const uint8_t ser[$(C_NS)_SER_BYTES],
  212. decaf_bool_t allow_identity
  213. ) DECAF_API_VIS DECAF_WARN_UNUSED DECAF_NONNULL DECAF_NOINLINE;
  214. /**
  215. * @brief Copy a point. The input and output may alias,
  216. * in which case this function does nothing.
  217. *
  218. * @param [out] a A copy of the point.
  219. * @param [in] b Any point.
  220. */
  221. static inline void DECAF_NONNULL $(c_ns)_point_copy (
  222. $(c_ns)_point_t a,
  223. const $(c_ns)_point_t b
  224. ) {
  225. *a=*b;
  226. }
  227. /**
  228. * @brief Test whether two points are equal. If yes, return
  229. * DECAF_TRUE, else return DECAF_FALSE.
  230. *
  231. * @param [in] a A point.
  232. * @param [in] b Another point.
  233. * @retval DECAF_TRUE The points are equal.
  234. * @retval DECAF_FALSE The points are not equal.
  235. */
  236. decaf_bool_t $(c_ns)_point_eq (
  237. const $(c_ns)_point_t a,
  238. const $(c_ns)_point_t b
  239. ) DECAF_API_VIS DECAF_WARN_UNUSED DECAF_NONNULL DECAF_NOINLINE;
  240. /**
  241. * @brief Add two points to produce a third point. The
  242. * input points and output point can be pointers to the same
  243. * memory.
  244. *
  245. * @param [out] sum The sum a+b.
  246. * @param [in] a An addend.
  247. * @param [in] b An addend.
  248. */
  249. void $(c_ns)_point_add (
  250. $(c_ns)_point_t sum,
  251. const $(c_ns)_point_t a,
  252. const $(c_ns)_point_t b
  253. ) DECAF_API_VIS DECAF_NONNULL;
  254. /**
  255. * @brief Double a point. Equivalent to
  256. * $(c_ns)_point_add(two_a,a,a), but potentially faster.
  257. *
  258. * @param [out] two_a The sum a+a.
  259. * @param [in] a A point.
  260. */
  261. void $(c_ns)_point_double (
  262. $(c_ns)_point_t two_a,
  263. const $(c_ns)_point_t a
  264. ) DECAF_API_VIS DECAF_NONNULL;
  265. /**
  266. * @brief Subtract two points to produce a third point. The
  267. * input points and output point can be pointers to the same
  268. * memory.
  269. *
  270. * @param [out] diff The difference a-b.
  271. * @param [in] a The minuend.
  272. * @param [in] b The subtrahend.
  273. */
  274. void $(c_ns)_point_sub (
  275. $(c_ns)_point_t diff,
  276. const $(c_ns)_point_t a,
  277. const $(c_ns)_point_t b
  278. ) DECAF_API_VIS DECAF_NONNULL;
  279. /**
  280. * @brief Negate a point to produce another point. The input
  281. * and output points can use the same memory.
  282. *
  283. * @param [out] nega The negated input point
  284. * @param [in] a The input point.
  285. */
  286. void $(c_ns)_point_negate (
  287. $(c_ns)_point_t nega,
  288. const $(c_ns)_point_t a
  289. ) DECAF_API_VIS DECAF_NONNULL;
  290. /**
  291. * @brief Multiply a base point by a scalar: scaled = scalar*base.
  292. *
  293. * @param [out] scaled The scaled point base*scalar
  294. * @param [in] base The point to be scaled.
  295. * @param [in] scalar The scalar to multiply by.
  296. */
  297. void $(c_ns)_point_scalarmul (
  298. $(c_ns)_point_t scaled,
  299. const $(c_ns)_point_t base,
  300. const $(c_ns)_scalar_t scalar
  301. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  302. /**
  303. * @brief Multiply a base point by a scalar: scaled = scalar*base.
  304. * This function operates directly on serialized forms.
  305. *
  306. * @warning This function is experimental. It may not be supported
  307. * long-term.
  308. *
  309. * @param [out] scaled The scaled point base*scalar
  310. * @param [in] base The point to be scaled.
  311. * @param [in] scalar The scalar to multiply by.
  312. * @param [in] allow_identity Allow the input to be the identity.
  313. * @param [in] short_circuit Allow a fast return if the input is illegal.
  314. *
  315. * @retval DECAF_SUCCESS The scalarmul succeeded.
  316. * @retval DECAF_FAILURE The scalarmul didn't succeed, because
  317. * base does not represent a point.
  318. */
  319. decaf_error_t $(c_ns)_direct_scalarmul (
  320. uint8_t scaled[$(C_NS)_SER_BYTES],
  321. const uint8_t base[$(C_NS)_SER_BYTES],
  322. const $(c_ns)_scalar_t scalar,
  323. decaf_bool_t allow_identity,
  324. decaf_bool_t short_circuit
  325. ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;
  326. /**
  327. * @brief RFC 7748 Diffie-Hellman scalarmul. This function uses a different
  328. * (non-Decaf) encoding.
  329. *
  330. * @param [out] scaled The scaled point base*scalar
  331. * @param [in] base The point to be scaled.
  332. * @param [in] scalar The scalar to multiply by.
  333. *
  334. * @retval DECAF_SUCCESS The scalarmul succeeded.
  335. * @retval DECAF_FAILURE The scalarmul didn't succeed, because the base
  336. * point is in a small subgroup.
  337. */
  338. decaf_error_t decaf_x$(gf_shortname) (
  339. uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
  340. const uint8_t base[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
  341. const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES]
  342. ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE;
  343. /**
  344. * @brief Multiply a point by the cofactor, then encode it like RFC 7748
  345. *
  346. * @param [out] out The scaled and encoded point.
  347. * @param [in] p The point to be scaled and encoded.
  348. */
  349. void $(c_ns)_point_mul_by_cofactor_and_encode_like_x$(gf_shortname) (
  350. uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
  351. const $(c_ns)_point_t p
  352. );
  353. /** The base point for X$(gf_shortname) Diffie-Hellman */
  354. extern const uint8_t decaf_x$(gf_shortname)_base_point[DECAF_X$(gf_shortname)_PUBLIC_BYTES] DECAF_API_VIS;
  355. /**
  356. * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses
  357. * a different (non-Decaf) encoding.
  358. *
  359. * @deprecated Renamed to decaf_x$(gf_shortname)_derive_public_key.
  360. * I have no particular timeline for removing this name.
  361. *
  362. * @param [out] scaled The scaled point base*scalar
  363. * @param [in] scalar The scalar to multiply by.
  364. */
  365. void decaf_x$(gf_shortname)_generate_key (
  366. uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
  367. const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES]
  368. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_DEPRECATED("Renamed to decaf_x$(gf_shortname)_derive_public_key");
  369. /**
  370. * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses
  371. * a different (non-Decaf) encoding.
  372. *
  373. * Does exactly the same thing as decaf_x$(gf_shortname)_generate_key,
  374. * but has a better name.
  375. *
  376. * @param [out] scaled The scaled point base*scalar
  377. * @param [in] scalar The scalar to multiply by.
  378. */
  379. void decaf_x$(gf_shortname)_derive_public_key (
  380. uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
  381. const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES]
  382. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  383. /* FUTURE: uint8_t $(c_ns)_encode_like_curve$(gf_shortname)) */
  384. /**
  385. * @brief Precompute a table for fast scalar multiplication.
  386. * Some implementations do not include precomputed points; for
  387. * those implementations, this implementation simply copies the
  388. * point.
  389. *
  390. * @param [out] a A precomputed table of multiples of the point.
  391. * @param [in] b Any point.
  392. */
  393. void $(c_ns)_precompute (
  394. $(c_ns)_precomputed_s *a,
  395. const $(c_ns)_point_t b
  396. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  397. /**
  398. * @brief Multiply a precomputed base point by a scalar:
  399. * scaled = scalar*base.
  400. * Some implementations do not include precomputed points; for
  401. * those implementations, this function is the same as
  402. * $(c_ns)_point_scalarmul
  403. *
  404. * @param [out] scaled The scaled point base*scalar
  405. * @param [in] base The point to be scaled.
  406. * @param [in] scalar The scalar to multiply by.
  407. */
  408. void $(c_ns)_precomputed_scalarmul (
  409. $(c_ns)_point_t scaled,
  410. const $(c_ns)_precomputed_s *base,
  411. const $(c_ns)_scalar_t scalar
  412. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  413. /**
  414. * @brief Multiply two base points by two scalars:
  415. * scaled = scalar1*base1 + scalar2*base2.
  416. *
  417. * Equivalent to two calls to $(c_ns)_point_scalarmul, but may be
  418. * faster.
  419. *
  420. * @param [out] combo The linear combination scalar1*base1 + scalar2*base2.
  421. * @param [in] base1 A first point to be scaled.
  422. * @param [in] scalar1 A first scalar to multiply by.
  423. * @param [in] base2 A second point to be scaled.
  424. * @param [in] scalar2 A second scalar to multiply by.
  425. */
  426. void $(c_ns)_point_double_scalarmul (
  427. $(c_ns)_point_t combo,
  428. const $(c_ns)_point_t base1,
  429. const $(c_ns)_scalar_t scalar1,
  430. const $(c_ns)_point_t base2,
  431. const $(c_ns)_scalar_t scalar2
  432. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  433. /**
  434. * Multiply one base point by two scalars:
  435. *
  436. * a1 = scalar1 * base
  437. * a2 = scalar2 * base
  438. *
  439. * Equivalent to two calls to $(c_ns)_point_scalarmul, but may be
  440. * faster.
  441. *
  442. * @param [out] a1 The first multiple. It may be the same as the input point.
  443. * @param [out] a2 The second multiple. It may be the same as the input point.
  444. * @param [in] base1 A point to be scaled.
  445. * @param [in] scalar1 A first scalar to multiply by.
  446. * @param [in] scalar2 A second scalar to multiply by.
  447. */
  448. void $(c_ns)_point_dual_scalarmul (
  449. $(c_ns)_point_t a1,
  450. $(c_ns)_point_t a2,
  451. const $(c_ns)_point_t base1,
  452. const $(c_ns)_scalar_t scalar1,
  453. const $(c_ns)_scalar_t scalar2
  454. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  455. /**
  456. * @brief Multiply two base points by two scalars:
  457. * scaled = scalar1*$(c_ns)_point_base + scalar2*base2.
  458. *
  459. * Otherwise equivalent to $(c_ns)_point_double_scalarmul, but may be
  460. * faster at the expense of being variable time.
  461. *
  462. * @param [out] combo The linear combination scalar1*base + scalar2*base2.
  463. * @param [in] scalar1 A first scalar to multiply by.
  464. * @param [in] base2 A second point to be scaled.
  465. * @param [in] scalar2 A second scalar to multiply by.
  466. *
  467. * @warning: This function takes variable time, and may leak the scalars
  468. * used. It is designed for signature verification.
  469. */
  470. void $(c_ns)_base_double_scalarmul_non_secret (
  471. $(c_ns)_point_t combo,
  472. const $(c_ns)_scalar_t scalar1,
  473. const $(c_ns)_point_t base2,
  474. const $(c_ns)_scalar_t scalar2
  475. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  476. /**
  477. * @brief Constant-time decision between two points. If pick_b
  478. * is zero, out = a; else out = b.
  479. *
  480. * @param [out] out The output. It may be the same as either input.
  481. * @param [in] a Any point.
  482. * @param [in] b Any point.
  483. * @param [in] pick_b If nonzero, choose point b.
  484. */
  485. void $(c_ns)_point_cond_sel (
  486. $(c_ns)_point_t out,
  487. const $(c_ns)_point_t a,
  488. const $(c_ns)_point_t b,
  489. decaf_word_t pick_b
  490. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  491. /**
  492. * @brief Constant-time decision between two scalars. If pick_b
  493. * is zero, out = a; else out = b.
  494. *
  495. * @param [out] out The output. It may be the same as either input.
  496. * @param [in] a Any scalar.
  497. * @param [in] b Any scalar.
  498. * @param [in] pick_b If nonzero, choose scalar b.
  499. */
  500. void $(c_ns)_scalar_cond_sel (
  501. $(c_ns)_scalar_t out,
  502. const $(c_ns)_scalar_t a,
  503. const $(c_ns)_scalar_t b,
  504. decaf_word_t pick_b
  505. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  506. /**
  507. * @brief Test that a point is valid, for debugging purposes.
  508. *
  509. * @param [in] to_test The point to test.
  510. * @retval DECAF_TRUE The point is valid.
  511. * @retval DECAF_FALSE The point is invalid.
  512. */
  513. decaf_bool_t $(c_ns)_point_valid (
  514. const $(c_ns)_point_t to_test
  515. ) DECAF_API_VIS DECAF_WARN_UNUSED DECAF_NONNULL DECAF_NOINLINE;
  516. /**
  517. * @brief Torque a point, for debugging purposes. The output
  518. * will be equal to the input.
  519. *
  520. * @param [out] q The point to torque.
  521. * @param [in] p The point to torque.
  522. */
  523. void $(c_ns)_point_debugging_torque (
  524. $(c_ns)_point_t q,
  525. const $(c_ns)_point_t p
  526. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  527. /**
  528. * @brief Projectively scale a point, for debugging purposes.
  529. * The output will be equal to the input, and will be valid
  530. * even if the factor is zero.
  531. *
  532. * @param [out] q The point to scale.
  533. * @param [in] p The point to scale.
  534. * @param [in] factor Serialized GF factor to scale.
  535. */
  536. void $(c_ns)_point_debugging_pscale (
  537. $(c_ns)_point_t q,
  538. const $(c_ns)_point_t p,
  539. const unsigned char factor[$(C_NS)_SER_BYTES]
  540. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  541. /**
  542. * @brief Almost-Elligator-like hash to curve.
  543. *
  544. * Call this function with the output of a hash to make a hash to the curve.
  545. *
  546. * This function runs Elligator2 on the $(c_ns) Jacobi quartic model. It then
  547. * uses the isogeny to put the result in twisted Edwards form. As a result,
  548. * it is safe (cannot produce points of order 4), and would be compatible with
  549. * hypothetical other implementations of Decaf using a Montgomery or untwisted
  550. * Edwards model.
  551. *
  552. * Unlike Elligator, this function may be up to 4:1 on [0,(p-1)/2]:
  553. * A factor of 2 due to the isogeny.
  554. * A factor of 2 because we quotient out the 2-torsion.
  555. *
  556. * This makes it about 8:1 overall, or 16:1 overall on curves with cofactor 8.
  557. *
  558. * Negating the input (mod q) results in the same point. Inverting the input
  559. * (mod q) results in the negative point. This is the same as Elligator.
  560. *
  561. * This function isn't quite indifferentiable from a random oracle.
  562. * However, it is suitable for many protocols, including SPEKE and SPAKE2 EE.
  563. * Furthermore, calling it twice with independent seeds and adding the results
  564. * is indifferentiable from a random oracle.
  565. *
  566. * @param [in] hashed_data Output of some hash function.
  567. * @param [out] pt The data hashed to the curve.
  568. */
  569. void
  570. $(c_ns)_point_from_hash_nonuniform (
  571. $(c_ns)_point_t pt,
  572. const unsigned char hashed_data[$(C_NS)_HASH_BYTES]
  573. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  574. /**
  575. * @brief Indifferentiable hash function encoding to curve.
  576. *
  577. * Equivalent to calling $(c_ns)_point_from_hash_nonuniform twice and adding.
  578. *
  579. * @param [in] hashed_data Output of some hash function.
  580. * @param [out] pt The data hashed to the curve.
  581. */
  582. void $(c_ns)_point_from_hash_uniform (
  583. $(c_ns)_point_t pt,
  584. const unsigned char hashed_data[2*$(C_NS)_HASH_BYTES]
  585. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE;
  586. /**
  587. * @brief Inverse of elligator-like hash to curve.
  588. *
  589. * This function writes to the buffer, to make it so that
  590. * $(c_ns)_point_from_hash_nonuniform(buffer) = pt if
  591. * possible. Since there may be multiple preimages, the
  592. * "which" parameter chooses between them. To ensure uniform
  593. * inverse sampling, this function succeeds or fails
  594. * independently for different "which" values.
  595. *
  596. * @param [out] recovered_hash Encoded data.
  597. * @param [in] pt The point to encode.
  598. * @param [in] which A value determining which inverse point
  599. * to return.
  600. *
  601. * @retval DECAF_SUCCESS The inverse succeeded.
  602. * @retval DECAF_FAILURE The inverse failed.
  603. */
  604. decaf_error_t
  605. $(c_ns)_invert_elligator_nonuniform (
  606. unsigned char recovered_hash[$(C_NS)_HASH_BYTES],
  607. const $(c_ns)_point_t pt,
  608. uint32_t which
  609. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED;
  610. /**
  611. * @brief Inverse of elligator-like hash to curve.
  612. *
  613. * This function writes to the buffer, to make it so that
  614. * $(c_ns)_point_from_hash_uniform(buffer) = pt if
  615. * possible. Since there may be multiple preimages, the
  616. * "which" parameter chooses between them. To ensure uniform
  617. * inverse sampling, this function succeeds or fails
  618. * independently for different "which" values.
  619. *
  620. * @param [out] recovered_hash Encoded data.
  621. * @param [in] pt The point to encode.
  622. * @param [in] which A value determining which inverse point
  623. * to return.
  624. *
  625. * @retval DECAF_SUCCESS The inverse succeeded.
  626. * @retval DECAF_FAILURE The inverse failed.
  627. */
  628. decaf_error_t
  629. $(c_ns)_invert_elligator_uniform (
  630. unsigned char recovered_hash[2*$(C_NS)_HASH_BYTES],
  631. const $(c_ns)_point_t pt,
  632. uint32_t which
  633. ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED;
  634. /**
  635. * @brief Overwrite scalar with zeros.
  636. */
  637. void $(c_ns)_scalar_destroy (
  638. $(c_ns)_scalar_t scalar
  639. ) DECAF_NONNULL DECAF_API_VIS;
  640. /**
  641. * @brief Overwrite point with zeros.
  642. */
  643. void $(c_ns)_point_destroy (
  644. $(c_ns)_point_t point
  645. ) DECAF_NONNULL DECAF_API_VIS;
  646. /**
  647. * @brief Overwrite precomputed table with zeros.
  648. */
  649. void $(c_ns)_precomputed_destroy (
  650. $(c_ns)_precomputed_s *pre
  651. ) DECAF_NONNULL DECAF_API_VIS;
  652. #ifdef __cplusplus
  653. } /* extern "C" */
  654. #endif