No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

256 líneas
11 KiB

  1. /********************************************************************************************
  2. * Supersingular Isogeny Key Encapsulation Library
  3. *
  4. * Abstract: internal header file for P751
  5. *********************************************************************************************/
  6. #ifndef __P751_INTERNAL_H__
  7. #define __P751_INTERNAL_H__
  8. #include "api.h"
  9. #define NWORDS_FIELD 12 // Number of words of a 751-bit field element
  10. #define p751_ZERO_WORDS 5 // Number of "0" digits in the least significant part of p751 + 1
  11. // Basic constants
  12. #define NBITS_FIELD 751
  13. #define MAXBITS_FIELD 768
  14. #define MAXWORDS_FIELD ((MAXBITS_FIELD + RADIX - 1) / RADIX) // Max. number of words to represent field elements
  15. #define NWORDS64_FIELD ((NBITS_FIELD + 63) / 64) // Number of 64-bit words of a 751-bit field element
  16. #define NBITS_ORDER 384
  17. #define NWORDS_ORDER ((NBITS_ORDER + RADIX - 1) / RADIX) // Number of words of oA and oB, where oA and oB are the subgroup orders of Alice and Bob, resp.
  18. #define NWORDS64_ORDER ((NBITS_ORDER + 63) / 64) // Number of 64-bit words of a 384-bit element
  19. #define MAXBITS_ORDER NBITS_ORDER
  20. #define MAXWORDS_ORDER ((MAXBITS_ORDER + RADIX - 1) / RADIX) // Max. number of words to represent elements in [1, oA-1] or [1, oB].
  21. #define ALICE 0
  22. #define BOB 1
  23. #define OALICE_BITS 372
  24. #define OBOB_BITS 379
  25. #define OBOB_EXPON 239
  26. #define MASK_ALICE 0x0F
  27. #define MASK_BOB 0x03
  28. #define PRIME p751
  29. #define PARAM_A 0
  30. #define PARAM_C 1
  31. // Fixed parameters for isogeny tree computation
  32. #define MAX_INT_POINTS_ALICE 8
  33. #define MAX_INT_POINTS_BOB 10
  34. #define MAX_Alice 186
  35. #define MAX_Bob 239
  36. #define MSG_BYTES 32
  37. #define SECRETKEY_A_BYTES (OALICE_BITS + 7) / 8
  38. #define SECRETKEY_B_BYTES (OBOB_BITS + 7) / 8
  39. #define FP2_ENCODED_BYTES 2 * ((NBITS_FIELD + 7) / 8)
  40. // SIDH's basic element definitions and point representations
  41. typedef digit_t felm_t[NWORDS_FIELD]; // Datatype for representing 751-bit field elements (768-bit max.)
  42. typedef digit_t dfelm_t[2 * NWORDS_FIELD]; // Datatype for representing double-precision 2x751-bit field elements (2x768-bit max.)
  43. typedef felm_t f2elm_t[2]; // Datatype for representing quadratic extension field elements GF(p751^2)
  44. typedef f2elm_t publickey_t[3]; // Datatype for representing public keys equivalent to three GF(p751^2) elements
  45. typedef struct
  46. {
  47. f2elm_t X;
  48. f2elm_t Z;
  49. } point_proj; // Point representation in projective XZ Montgomery coordinates.
  50. typedef point_proj point_proj_t[1];
  51. /**************** Function prototypes ****************/
  52. /************* Multiprecision functions **************/
  53. // Copy wordsize digits, c = a, where lng(a) = nwords
  54. void copy_words(const digit_t *a, digit_t *c, const unsigned int nwords);
  55. // Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit
  56. unsigned int mp_add(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
  57. // 751-bit multiprecision addition, c = a+b
  58. void mp_add751(const digit_t *a, const digit_t *b, digit_t *c);
  59. void mp_add751_asm(const digit_t *a, const digit_t *b, digit_t *c);
  60. //void mp_addmask751_asm(const digit_t* a, const digit_t mask, digit_t* c);
  61. // 2x751-bit multiprecision addition, c = a+b
  62. void mp_add751x2(const digit_t *a, const digit_t *b, digit_t *c);
  63. void mp_add751x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
  64. // Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit
  65. unsigned int mp_sub(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
  66. digit_t mp_sub751x2_asm(const digit_t *a, const digit_t *b, digit_t *c);
  67. // Multiprecision left shift
  68. void mp_shiftleft(digit_t *x, unsigned int shift, const unsigned int nwords);
  69. // Multiprecision right shift by one
  70. void mp_shiftr1(digit_t *x, const unsigned int nwords);
  71. // Multiprecision left right shift by one
  72. void mp_shiftl1(digit_t *x, const unsigned int nwords);
  73. // Digit multiplication, digit * digit -> 2-digit result
  74. void digit_x_digit(const digit_t a, const digit_t b, digit_t *c);
  75. // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = nwords.
  76. void mp_mul(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
  77. void multiply(const digit_t *a, const digit_t *b, digit_t *c, const unsigned int nwords);
  78. // Montgomery multiplication modulo the group order, mc = ma*mb*r' mod order, where ma,mb,mc in [0, order-1]
  79. void Montgomery_multiply_mod_order(const digit_t *ma, const digit_t *mb, digit_t *mc, const digit_t *order, const digit_t *Montgomery_rprime);
  80. // (Non-constant time) Montgomery inversion modulo the curve order using a^(-1) = a^(order-2) mod order
  81. //void Montgomery_inversion_mod_order(const digit_t* ma, digit_t* mc, const digit_t* order, const digit_t* Montgomery_rprime);
  82. void Montgomery_inversion_mod_order_bingcd(const digit_t *a, digit_t *c, const digit_t *order, const digit_t *Montgomery_rprime, const digit_t *Montgomery_R2);
  83. // Conversion of elements in Z_r to Montgomery representation, where the order r is up to 384 bits.
  84. void to_Montgomery_mod_order(const digit_t *a, digit_t *mc, const digit_t *order, const digit_t *Montgomery_rprime, const digit_t *Montgomery_Rprime);
  85. // Conversion of elements in Z_r from Montgomery to standard representation, where the order is up to 384 bits.
  86. void from_Montgomery_mod_order(const digit_t *ma, digit_t *c, const digit_t *order, const digit_t *Montgomery_rprime);
  87. // Inversion modulo Alice's order 2^372.
  88. void inv_mod_orderA(const digit_t *a, digit_t *c);
  89. /************ Field arithmetic functions *************/
  90. // Copy of a field element, c = a
  91. void fpcopy751(const felm_t a, felm_t c);
  92. // Zeroing a field element, a = 0
  93. void fpzero751(felm_t a);
  94. // Non constant-time comparison of two field elements. If a = b return TRUE, otherwise, return FALSE
  95. bool fpequal751_non_constant_time(const felm_t a, const felm_t b);
  96. // Modular addition, c = a+b mod p751
  97. extern void fpadd751(const digit_t *a, const digit_t *b, digit_t *c);
  98. extern void fpadd751_asm(const digit_t *a, const digit_t *b, digit_t *c);
  99. // Modular subtraction, c = a-b mod p751
  100. extern void fpsub751(const digit_t *a, const digit_t *b, digit_t *c);
  101. extern void fpsub751_asm(const digit_t *a, const digit_t *b, digit_t *c);
  102. // Modular negation, a = -a mod p751
  103. extern void fpneg751(digit_t *a);
  104. // Modular division by two, c = a/2 mod p751.
  105. void fpdiv2_751(const digit_t *a, digit_t *c);
  106. // Modular correction to reduce field element a in [0, 2*p751-1] to [0, p751-1].
  107. void fpcorrection751(digit_t *a);
  108. // 751-bit Montgomery reduction, c = a mod p
  109. void rdc_mont(const digit_t *a, digit_t *c);
  110. // Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p751, where R=2^768
  111. void fpmul751_mont(const felm_t a, const felm_t b, felm_t c);
  112. void mul751_asm(const felm_t a, const felm_t b, dfelm_t c);
  113. void rdc751_asm(const dfelm_t ma, dfelm_t mc);
  114. // Field squaring using Montgomery arithmetic, c = a*b*R^-1 mod p751, where R=2^768
  115. void fpsqr751_mont(const felm_t ma, felm_t mc);
  116. // Conversion to Montgomery representation
  117. void to_mont(const felm_t a, felm_t mc);
  118. // Conversion from Montgomery representation to standard representation
  119. void from_mont(const felm_t ma, felm_t c);
  120. // Field inversion, a = a^-1 in GF(p751)
  121. void fpinv751_mont(felm_t a);
  122. // Field inversion, a = a^-1 in GF(p751) using the binary GCD
  123. void fpinv751_mont_bingcd(felm_t a);
  124. // Chain to compute (p751-3)/4 using Montgomery arithmetic
  125. void fpinv751_chain_mont(felm_t a);
  126. /************ GF(p^2) arithmetic functions *************/
  127. // Copy of a GF(p751^2) element, c = a
  128. void fp2copy751(const f2elm_t a, f2elm_t c);
  129. // Zeroing a GF(p751^2) element, a = 0
  130. void fp2zero751(f2elm_t a);
  131. // GF(p751^2) negation, a = -a in GF(p751^2)
  132. void fp2neg751(f2elm_t a);
  133. // GF(p751^2) addition, c = a+b in GF(p751^2)
  134. extern void fp2add751(const f2elm_t a, const f2elm_t b, f2elm_t c);
  135. // GF(p751^2) subtraction, c = a-b in GF(p751^2)
  136. extern void fp2sub751(const f2elm_t a, const f2elm_t b, f2elm_t c);
  137. // GF(p751^2) division by two, c = a/2 in GF(p751^2)
  138. void fp2div2_751(const f2elm_t a, f2elm_t c);
  139. // Modular correction, a = a in GF(p751^2)
  140. void fp2correction751(f2elm_t a);
  141. // GF(p751^2) squaring using Montgomery arithmetic, c = a^2 in GF(p751^2)
  142. void fp2sqr751_mont(const f2elm_t a, f2elm_t c);
  143. // GF(p751^2) multiplication using Montgomery arithmetic, c = a*b in GF(p751^2)
  144. void fp2mul751_mont(const f2elm_t a, const f2elm_t b, f2elm_t c);
  145. // Conversion of a GF(p751^2) element to Montgomery representation
  146. void to_fp2mont(const f2elm_t a, f2elm_t mc);
  147. // Conversion of a GF(p751^2) element from Montgomery representation to standard representation
  148. void from_fp2mont(const f2elm_t ma, f2elm_t c);
  149. // GF(p751^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2)
  150. void fp2inv751_mont(f2elm_t a);
  151. // GF(p751^2) inversion, a = (a0-i*a1)/(a0^2+a1^2), GF(p751) inversion done using the binary GCD
  152. void fp2inv751_mont_bingcd(f2elm_t a);
  153. // n-way Montgomery inversion
  154. void mont_n_way_inv(const f2elm_t *vec, const int n, f2elm_t *out);
  155. /************ Elliptic curve and isogeny functions *************/
  156. // Computes the j-invariant of a Montgomery curve with projective constant.
  157. void j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv);
  158. // Simultaneous doubling and differential addition.
  159. void xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24);
  160. // Doubling of a Montgomery point in projective coordinates (X:Z).
  161. void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24);
  162. // Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings.
  163. void xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, const int e);
  164. // Differential addition.
  165. void xADD(point_proj_t P, const point_proj_t Q, const f2elm_t xPQ);
  166. // Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4.
  167. void get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t *coeff);
  168. // Evaluates the isogeny at the point (X:Z) in the domain of the isogeny.
  169. void eval_4_isog(point_proj_t P, f2elm_t *coeff);
  170. // Tripling of a Montgomery point in projective coordinates (X:Z).
  171. void xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus);
  172. // Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings.
  173. void xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, const int e);
  174. // Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3.
  175. void get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t *coeff);
  176. // Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and a point P with coefficients given in coeff.
  177. void eval_3_isog(point_proj_t Q, const f2elm_t *coeff);
  178. // 3-way simultaneous inversion
  179. void inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3);
  180. // Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A.
  181. void get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A);
  182. #endif