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.
 
 
 
 
 

619 lines
12 KiB

  1. /**
  2. * @file ec_point.h
  3. * @copyright
  4. * Copyright (c) 2014 Cryptography Research, Inc. \n
  5. * Released under the MIT License. See LICENSE.txt for license information.
  6. * @author Mike Hamburg
  7. * @warning This file was automatically generated.
  8. */
  9. #ifndef __CC_INCLUDED_EC_POINT_H__
  10. #define __CC_INCLUDED_EC_POINT_H__
  11. #include "field.h"
  12. #include "constant_time.h"
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. /**
  17. * Affine point on an Edwards curve.
  18. */
  19. typedef struct affine_t {
  20. field_a_t x, y;
  21. } affine_a_t[1];
  22. /**
  23. * Affine point on a twisted Edwards curve.
  24. */
  25. typedef struct tw_affine_t {
  26. field_a_t x, y;
  27. } tw_affine_a_t[1];
  28. /**
  29. * Montgomery buffer.
  30. */
  31. typedef struct montgomery_t {
  32. field_a_t z0, xd, zd, xa, za;
  33. } montgomery_a_t[1];
  34. /**
  35. * Montgomery buffer, augmented version.
  36. */
  37. typedef struct montgomery_aux_t {
  38. field_a_t s0, xd, zd, xa, za, xs, zs;
  39. } montgomery_aux_a_t[1];
  40. /**
  41. * Extensible coordinates for Edwards curves, suitable for
  42. * accumulators.
  43. *
  44. * Represents the point (x/z, y/z). The extra coordinates
  45. * t,u satisfy xy = tuz, allowing for conversion to Extended
  46. * form by multiplying t and u.
  47. *
  48. * The idea is that you don't have to do this multiplication
  49. * when doubling the accumulator, because the t-coordinate
  50. * isn't used there. At the same time, as long as you only
  51. * have one point in extensible form, additions don't cost
  52. * extra.
  53. *
  54. * This is essentially a lazier version of Hisil et al's
  55. * lookahead trick. It might be worth considering that trick
  56. * instead.
  57. */
  58. typedef struct extensible_t {
  59. field_a_t x, y, z, t, u;
  60. } extensible_a_t[1];
  61. /**
  62. * Extensible coordinates for twisted Edwards curves,
  63. * suitable for accumulators.
  64. */
  65. typedef struct tw_extensible_t {
  66. field_a_t x, y, z, t, u;
  67. } tw_extensible_a_t[1];
  68. /**
  69. * Niels coordinates for twisted Edwards curves.
  70. *
  71. * Good for mixed readdition; suitable for fixed tables.
  72. */
  73. typedef struct tw_niels_t {
  74. field_a_t a, b, c;
  75. } tw_niels_a_t[1];
  76. /**
  77. * Projective niels coordinates for twisted Edwards curves.
  78. *
  79. * Good for readdition; suitable for temporary tables.
  80. */
  81. typedef struct tw_pniels_t {
  82. tw_niels_a_t n;
  83. field_a_t z;
  84. } tw_pniels_a_t[1];
  85. /**
  86. * Auto-generated copy method.
  87. */
  88. static __inline__ void
  89. copy_affine (
  90. affine_a_t a,
  91. const affine_a_t ds
  92. ) __attribute__((unused,always_inline));
  93. /**
  94. * Auto-generated copy method.
  95. */
  96. static __inline__ void
  97. copy_tw_affine (
  98. tw_affine_a_t a,
  99. const tw_affine_a_t ds
  100. ) __attribute__((unused,always_inline));
  101. /**
  102. * Auto-generated copy method.
  103. */
  104. static __inline__ void
  105. copy_montgomery (
  106. montgomery_a_t a,
  107. const montgomery_a_t ds
  108. ) __attribute__((unused,always_inline));
  109. /**
  110. * Auto-generated copy method.
  111. */
  112. static __inline__ void
  113. copy_extensible (
  114. extensible_a_t a,
  115. const extensible_a_t ds
  116. ) __attribute__((unused,always_inline));
  117. /**
  118. * Auto-generated copy method.
  119. */
  120. static __inline__ void
  121. copy_tw_extensible (
  122. tw_extensible_a_t a,
  123. const tw_extensible_a_t ds
  124. ) __attribute__((unused,always_inline));
  125. /**
  126. * Auto-generated copy method.
  127. */
  128. static __inline__ void
  129. copy_tw_niels (
  130. tw_niels_a_t a,
  131. const tw_niels_a_t ds
  132. ) __attribute__((unused,always_inline));
  133. /**
  134. * Auto-generated copy method.
  135. */
  136. static __inline__ void
  137. copy_tw_pniels (
  138. tw_pniels_a_t a,
  139. const tw_pniels_a_t ds
  140. ) __attribute__((unused,always_inline));
  141. /**
  142. * Add two points on a twisted Edwards curve, one in Extensible form
  143. * and the other in half-Niels form.
  144. */
  145. void
  146. add_tw_niels_to_tw_extensible (
  147. tw_extensible_a_t d,
  148. const tw_niels_a_t e
  149. );
  150. /**
  151. * Add two points on a twisted Edwards curve, one in Extensible form
  152. * and the other in half-Niels form.
  153. */
  154. void
  155. sub_tw_niels_from_tw_extensible (
  156. tw_extensible_a_t d,
  157. const tw_niels_a_t e
  158. );
  159. /**
  160. * Add two points on a twisted Edwards curve, one in Extensible form
  161. * and the other in projective Niels form.
  162. */
  163. void
  164. add_tw_pniels_to_tw_extensible (
  165. tw_extensible_a_t e,
  166. const tw_pniels_a_t a
  167. );
  168. /**
  169. * Add two points on a twisted Edwards curve, one in Extensible form
  170. * and the other in projective Niels form.
  171. */
  172. void
  173. sub_tw_pniels_from_tw_extensible (
  174. tw_extensible_a_t e,
  175. const tw_pniels_a_t a
  176. );
  177. /**
  178. * Double a point on a twisted Edwards curve, in "extensible" coordinates.
  179. */
  180. void
  181. double_tw_extensible (
  182. tw_extensible_a_t a
  183. );
  184. /**
  185. * Double a point on an Edwards curve, in "extensible" coordinates.
  186. */
  187. void
  188. double_extensible (
  189. extensible_a_t a
  190. );
  191. /**
  192. * Double a point, and transfer it to the twisted curve.
  193. *
  194. * That is, apply the 4-isogeny.
  195. */
  196. void
  197. twist_and_double (
  198. tw_extensible_a_t b,
  199. const extensible_a_t a
  200. );
  201. /**
  202. * Double a point, and transfer it to the untwisted curve.
  203. *
  204. * That is, apply the dual isogeny.
  205. */
  206. void
  207. untwist_and_double (
  208. extensible_a_t b,
  209. const tw_extensible_a_t a
  210. );
  211. void
  212. convert_tw_affine_to_tw_pniels (
  213. tw_pniels_a_t b,
  214. const tw_affine_a_t a
  215. );
  216. void
  217. convert_tw_affine_to_tw_extensible (
  218. tw_extensible_a_t b,
  219. const tw_affine_a_t a
  220. );
  221. void
  222. convert_affine_to_extensible (
  223. extensible_a_t b,
  224. const affine_a_t a
  225. );
  226. void
  227. convert_tw_extensible_to_tw_pniels (
  228. tw_pniels_a_t b,
  229. const tw_extensible_a_t a
  230. );
  231. void
  232. convert_tw_pniels_to_tw_extensible (
  233. tw_extensible_a_t e,
  234. const tw_pniels_a_t d
  235. );
  236. void
  237. convert_tw_niels_to_tw_extensible (
  238. tw_extensible_a_t e,
  239. const tw_niels_a_t d
  240. );
  241. void
  242. montgomery_step (
  243. montgomery_a_t a
  244. );
  245. void
  246. montgomery_aux_step (
  247. montgomery_aux_a_t a
  248. );
  249. void
  250. deserialize_montgomery (
  251. montgomery_a_t a,
  252. const field_a_t sbz
  253. );
  254. mask_t
  255. serialize_montgomery (
  256. field_a_t b,
  257. const montgomery_a_t a,
  258. const field_a_t sbz
  259. );
  260. mask_t
  261. serialize_montgomery_decaf (
  262. field_a_t b,
  263. const montgomery_aux_a_t a,
  264. const field_a_t sbz
  265. );
  266. void
  267. deserialize_montgomery_decaf (
  268. montgomery_aux_a_t a,
  269. const field_a_t s
  270. );
  271. /**
  272. * Serialize a point on an Edwards curve.
  273. *
  274. * The serialized form would be sqrt((z-y)/(z+y)) with sign of xz.
  275. *
  276. * It would be on 4y^2/(1-d) = x^3 + 2(1+d)/(1-d) * x^2 + x.
  277. *
  278. * But 4/(1-d) isn't square, so we need to twist it:
  279. *
  280. * -x is on 4y^2/(d-1) = x^3 + 2(d+1)/(d-1) * x^2 + x
  281. */
  282. void
  283. serialize_extensible (
  284. field_a_t b,
  285. const extensible_a_t a
  286. );
  287. /**
  288. *
  289. */
  290. void
  291. untwist_and_double_and_serialize (
  292. field_a_t b,
  293. const tw_extensible_a_t a
  294. );
  295. /**
  296. * Expensive transfer from untwisted to twisted. Roughly equivalent to halve and isogeny.
  297. * Correctly transfers point of order 2.
  298. *
  299. * Can't have x=+1 (it's not even). There is code to fix the exception that would otherwise
  300. * occur at (0,1).
  301. *
  302. * Input point must be even.
  303. */
  304. void
  305. twist_even (
  306. tw_extensible_a_t b,
  307. const extensible_a_t a
  308. );
  309. /**
  310. * Expensive transfer from untwisted to twisted. Roughly equivalent to halve and isogeny.
  311. *
  312. * This function is for testing purposes only, because it can return odd points on the
  313. * twist. This can cause exceptions in the point addition formula. What's more, this
  314. * function should be able to return points of order 4, which are at infinity.
  315. *
  316. * This function probably doesn't properly handle special cases, such as the point at
  317. * infinity (FUTURE).
  318. *
  319. * This function probably isn't a homomorphism, in that it probably doesn't consistently
  320. * handle adjustments by the point of order 2 when the input is odd. (FUTURE)
  321. */
  322. void
  323. test_only_twist (
  324. tw_extensible_a_t b,
  325. const extensible_a_t a
  326. );
  327. mask_t
  328. field_is_square (
  329. const field_a_t x
  330. );
  331. mask_t
  332. is_even_pt (
  333. const extensible_a_t a
  334. );
  335. mask_t
  336. is_even_tw (
  337. const tw_extensible_a_t a
  338. );
  339. /**
  340. * Deserialize a point to an untwisted affine curve.
  341. */
  342. mask_t
  343. deserialize_affine (
  344. affine_a_t a,
  345. const field_a_t sz
  346. );
  347. /**
  348. * Deserialize a point and transfer it to the twist.
  349. *
  350. * Not guaranteed to preserve the 4-torsion component.
  351. *
  352. * Refuses to deserialize +-1, which are the points of order 2.
  353. */
  354. mask_t
  355. deserialize_and_twist_approx (
  356. tw_extensible_a_t a,
  357. const field_a_t sz
  358. )
  359. __attribute__((warn_unused_result));
  360. mask_t
  361. decaf_deserialize_affine (
  362. affine_a_t a,
  363. const field_a_t s,
  364. mask_t allow_identity
  365. )
  366. __attribute__((warn_unused_result));
  367. void
  368. decaf_serialize_extensible (
  369. field_a_t b,
  370. const extensible_a_t a
  371. );
  372. mask_t
  373. decaf_deserialize_tw_affine (
  374. tw_affine_a_t a,
  375. const field_a_t s,
  376. mask_t allow_identity
  377. )
  378. __attribute__((warn_unused_result));
  379. void
  380. decaf_serialize_tw_extensible (
  381. field_a_t b,
  382. const tw_extensible_a_t a
  383. );
  384. void
  385. set_identity_extensible (
  386. extensible_a_t a
  387. );
  388. void
  389. set_identity_tw_extensible (
  390. tw_extensible_a_t a
  391. );
  392. void
  393. set_identity_affine (
  394. affine_a_t a
  395. );
  396. mask_t
  397. eq_affine (
  398. const affine_a_t a,
  399. const affine_a_t b
  400. );
  401. mask_t
  402. eq_extensible (
  403. const extensible_a_t a,
  404. const extensible_a_t b
  405. );
  406. mask_t
  407. eq_tw_extensible (
  408. const tw_extensible_a_t a,
  409. const tw_extensible_a_t b
  410. );
  411. void
  412. elligator_2s_inject (
  413. affine_a_t a,
  414. const field_a_t r
  415. );
  416. mask_t
  417. validate_affine (
  418. const affine_a_t a
  419. );
  420. mask_t
  421. decaf_eq_tw_extensible (
  422. const tw_extensible_a_t a,
  423. const tw_extensible_a_t b
  424. )
  425. __attribute__((warn_unused_result));
  426. mask_t
  427. decaf_eq_extensible (
  428. const extensible_a_t a,
  429. const extensible_a_t b
  430. )
  431. __attribute__((warn_unused_result));
  432. /**
  433. * Check the invariants for struct tw_extensible_t.
  434. * NOTE: This function was automatically generated
  435. * with no regard for speed.
  436. */
  437. mask_t
  438. validate_tw_extensible (
  439. const tw_extensible_a_t ext
  440. );
  441. /**
  442. * Check the invariants for struct extensible_t.
  443. * NOTE: This function was automatically generated
  444. * with no regard for speed.
  445. */
  446. mask_t
  447. validate_extensible (
  448. const extensible_a_t ext
  449. );
  450. /**
  451. * If doNegate, then negate a twisted niels point.
  452. */
  453. static __inline__ void
  454. __attribute__((unused))
  455. cond_negate_tw_niels (
  456. tw_niels_a_t n,
  457. mask_t doNegate
  458. ) {
  459. constant_time_cond_swap(n->a, n->b, sizeof(n->a), doNegate);
  460. field_cond_neg(n->c, doNegate);
  461. }
  462. /**
  463. * If doNegate, then negate a twisted projective niels point.
  464. */
  465. static __inline__ void
  466. __attribute__((unused))
  467. cond_negate_tw_pniels (
  468. tw_pniels_a_t n,
  469. mask_t doNegate
  470. ) {
  471. cond_negate_tw_niels(n->n, doNegate);
  472. }
  473. void
  474. copy_affine (
  475. affine_a_t a,
  476. const affine_a_t ds
  477. ) {
  478. field_copy ( a->x, ds->x );
  479. field_copy ( a->y, ds->y );
  480. }
  481. void
  482. copy_tw_affine (
  483. tw_affine_a_t a,
  484. const tw_affine_a_t ds
  485. ) {
  486. field_copy ( a->x, ds->x );
  487. field_copy ( a->y, ds->y );
  488. }
  489. void
  490. copy_montgomery (
  491. montgomery_a_t a,
  492. const montgomery_a_t ds
  493. ) {
  494. field_copy ( a->z0, ds->z0 );
  495. field_copy ( a->xd, ds->xd );
  496. field_copy ( a->zd, ds->zd );
  497. field_copy ( a->xa, ds->xa );
  498. field_copy ( a->za, ds->za );
  499. }
  500. void
  501. copy_extensible (
  502. extensible_a_t a,
  503. const extensible_a_t ds
  504. ) {
  505. field_copy ( a->x, ds->x );
  506. field_copy ( a->y, ds->y );
  507. field_copy ( a->z, ds->z );
  508. field_copy ( a->t, ds->t );
  509. field_copy ( a->u, ds->u );
  510. }
  511. void
  512. copy_tw_extensible (
  513. tw_extensible_a_t a,
  514. const tw_extensible_a_t ds
  515. ) {
  516. field_copy ( a->x, ds->x );
  517. field_copy ( a->y, ds->y );
  518. field_copy ( a->z, ds->z );
  519. field_copy ( a->t, ds->t );
  520. field_copy ( a->u, ds->u );
  521. }
  522. void
  523. copy_tw_niels (
  524. tw_niels_a_t a,
  525. const tw_niels_a_t ds
  526. ) {
  527. field_copy ( a->a, ds->a );
  528. field_copy ( a->b, ds->b );
  529. field_copy ( a->c, ds->c );
  530. }
  531. void
  532. copy_tw_pniels (
  533. tw_pniels_a_t a,
  534. const tw_pniels_a_t ds
  535. ) {
  536. copy_tw_niels( a->n, ds->n );
  537. field_copy ( a->z, ds->z );
  538. }
  539. #ifdef __cplusplus
  540. }; /* extern "C" */
  541. #endif
  542. #endif /* __CC_INCLUDED_EC_POINT_H__ */