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.
 
 
 

215 lines
10 KiB

  1. /********************************************************************************************
  2. * SIDH: an efficient supersingular isogeny-based cryptography library for ephemeral
  3. * Diffie-Hellman key exchange.
  4. *
  5. * Copyright (c) Microsoft Corporation. All rights reserved.
  6. *
  7. *
  8. * Abstract: main header file
  9. *
  10. *********************************************************************************************/
  11. #ifndef __SIDH_H__
  12. #define __SIDH_H__
  13. #include <stdint.h>
  14. #include <stdbool.h>
  15. #include <stddef.h>
  16. // Definition of operating system
  17. #define OS_WIN 1
  18. #define OS_LINUX 2
  19. #define OS_TARGET OS_LINUX
  20. #define COMPILER_VC 1
  21. #define COMPILER_GCC 2
  22. #define COMPILER_CLANG 3
  23. #define COMPILER COMPILER_GCC
  24. // Definition of the targeted architecture and basic data types
  25. #define TARGET_AMD64 1
  26. #define TARGET_x86 2
  27. #define TARGET_ARM 3
  28. #define TARGET_ARM64 4
  29. #define TARGET TARGET_AMD64
  30. #define RADIX 64
  31. typedef uint64_t digit_t; // Unsigned 64-bit digit
  32. typedef int64_t sdigit_t; // Signed 64-bit digit
  33. typedef uint32_t hdigit_t; // Unsigned 32-bit digit
  34. #define NWORDS_FIELD 12 // Number of words of a 751-bit field element
  35. #define p751_ZERO_WORDS 5 // Number of "0" digits in the least significant part of p751 + 1
  36. #define RADIX64 64
  37. // Selection of generic, portable implementation
  38. // Unsupported configurations
  39. #if (TARGET != TARGET_AMD64) && (TARGET != TARGET_ARM64) && !defined(GENERIC_IMPLEMENTATION)
  40. #error-- "Unsupported configuration"
  41. #endif
  42. // Extended datatype support
  43. #if defined(GENERIC_IMPLEMENTATION)
  44. typedef uint64_t uint128_t[2];
  45. #elif (TARGET == TARGET_AMD64 && OS_TARGET == OS_LINUX) && (COMPILER == COMPILER_GCC || COMPILER == COMPILER_CLANG)
  46. #define UINT128_SUPPORT
  47. typedef unsigned uint128_t __attribute__((mode(TI)));
  48. #elif (TARGET == TARGET_ARM64 && OS_TARGET == OS_LINUX) && (COMPILER == COMPILER_GCC || COMPILER == COMPILER_CLANG)
  49. #define UINT128_SUPPORT
  50. typedef unsigned uint128_t __attribute__((mode(TI)));
  51. #elif (TARGET == TARGET_AMD64) && (OS_TARGET == OS_WIN && COMPILER == COMPILER_VC)
  52. #define SCALAR_INTRIN_SUPPORT
  53. typedef uint64_t uint128_t[2];
  54. #else
  55. #error-- "Unsupported configuration"
  56. #endif
  57. // Basic constants
  58. #define NBITS_FIELD 751
  59. #define MAXBITS_FIELD 768
  60. #define MAXWORDS_FIELD ((MAXBITS_FIELD + RADIX - 1) / RADIX) // Max. number of words to represent field elements
  61. #define NWORDS64_FIELD ((NBITS_FIELD + 63) / 64) // Number of 64-bit words of a 751-bit field element
  62. #define NBITS_ORDER 384
  63. #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.
  64. #define NWORDS64_ORDER ((NBITS_ORDER + 63) / 64) // Number of 64-bit words of a 384-bit element
  65. #define MAXBITS_ORDER NBITS_ORDER
  66. #define MAXWORDS_ORDER ((MAXBITS_ORDER + RADIX - 1) / RADIX) // Max. number of words to represent elements in [1, oA-1] or [1, oB].
  67. // Basic constants for elliptic curve BigMont
  68. #define BIGMONT_NBITS_ORDER 749
  69. #define BIGMONT_MAXBITS_ORDER 768
  70. #define BIGMONT_NWORDS_ORDER ((BIGMONT_NBITS_ORDER + RADIX - 1) / RADIX) // Number of words of BigMont's subgroup order.
  71. #define BIGMONT_MAXWORDS_ORDER ((BIGMONT_MAXBITS_ORDER + RADIX - 1) / RADIX) // Max. number of words to represent elements in [1, BigMont_order].
  72. // Definitions of the error-handling type and error codes
  73. typedef enum {
  74. CRYPTO_SUCCESS, // 0x00
  75. CRYPTO_ERROR, // 0x01
  76. CRYPTO_ERROR_DURING_TEST, // 0x02
  77. CRYPTO_ERROR_UNKNOWN, // 0x03
  78. CRYPTO_ERROR_NOT_IMPLEMENTED, // 0x04
  79. CRYPTO_ERROR_NO_MEMORY, // 0x05
  80. CRYPTO_ERROR_INVALID_PARAMETER, // 0x06
  81. CRYPTO_ERROR_SHARED_KEY, // 0x07
  82. CRYPTO_ERROR_PUBLIC_KEY_VALIDATION, // 0x08
  83. CRYPTO_ERROR_TOO_MANY_ITERATIONS, // 0x09
  84. CRYPTO_ERROR_END_OF_LIST
  85. } CRYPTO_STATUS;
  86. #define CRYPTO_STATUS_TYPE_SIZE (CRYPTO_ERROR_END_OF_LIST)
  87. // Definitions of the error messages
  88. // NOTE: they must match the error codes above
  89. #define CRYPTO_MSG_SUCCESS "CRYPTO_SUCCESS"
  90. #define CRYPTO_MSG_ERROR "CRYPTO_ERROR"
  91. #define CRYPTO_MSG_ERROR_DURING_TEST "CRYPTO_ERROR_DURING_TEST"
  92. #define CRYPTO_MSG_ERROR_UNKNOWN "CRYPTO_ERROR_UNKNOWN"
  93. #define CRYPTO_MSG_ERROR_NOT_IMPLEMENTED "CRYPTO_ERROR_NOT_IMPLEMENTED"
  94. #define CRYPTO_MSG_ERROR_NO_MEMORY "CRYPTO_ERROR_NO_MEMORY"
  95. #define CRYPTO_MSG_ERROR_INVALID_PARAMETER "CRYPTO_ERROR_INVALID_PARAMETER"
  96. #define CRYPTO_MSG_ERROR_SHARED_KEY "CRYPTO_ERROR_SHARED_KEY"
  97. #define CRYPTO_MSG_ERROR_PUBLIC_KEY_VALIDATION "CRYPTO_ERROR_PUBLIC_KEY_VALIDATION"
  98. #define CRYPTO_MSG_ERROR_TOO_MANY_ITERATIONS "CRYPTO_ERROR_TOO_MANY_ITERATIONS"
  99. // Definition of type random_bytes to implement callback functions outputting "nbytes" random values to "random_array"
  100. typedef CRYPTO_STATUS (*RandomBytes)(unsigned int nbytes, unsigned char *random_array);
  101. // Definition of type for curve isogeny system identifiers. Currently valid value is "SIDHp751" (see SIDH.h)
  102. typedef char CurveIsogeny_ID[10];
  103. // Supersingular elliptic curve isogeny structures:
  104. // This data struct contains the static curve isogeny data
  105. typedef struct
  106. {
  107. CurveIsogeny_ID CurveIsogeny; // Curve isogeny system identifier, base curve defined over GF(p^2)
  108. unsigned int pwordbits; // Smallest multiple of 32 larger than the prime bitlength
  109. unsigned int owordbits; // Smallest multiple of 32 larger than the order bitlength
  110. unsigned int pbits; // Bitlength of the prime p
  111. uint64_t prime[MAXWORDS_FIELD]; // Prime p
  112. uint64_t A[MAXWORDS_FIELD]; // Base curve parameter "A"
  113. uint64_t C[MAXWORDS_FIELD]; // Base curve parameter "C"
  114. unsigned int oAbits; // Order bitlength for Alice
  115. uint64_t Aorder[MAXWORDS_ORDER]; // Order of Alice's (sub)group
  116. unsigned int oBbits; // Order bitlength for Bob
  117. unsigned int eB; // Power of Bob's subgroup order (i.e., oB = 3^eB)
  118. uint64_t Border[MAXWORDS_ORDER]; // Order of Bob's (sub)group
  119. uint64_t PA[2 * MAXWORDS_FIELD]; // Alice's generator PA = (XPA,YPA), where XPA and YPA are defined over GF(p)
  120. uint64_t PB[2 * MAXWORDS_FIELD]; // Bob's generator PB = (XPB,YPB), where XPB and YPB are defined over GF(p)
  121. unsigned int BigMont_A24; // BigMont's curve parameter A24 = (A+2)/4
  122. uint64_t BigMont_order[BIGMONT_MAXWORDS_ORDER]; // BigMont's subgroup order
  123. uint64_t Montgomery_R2[MAXWORDS_FIELD]; // Montgomery constant (2^W)^2 mod p, using a suitable value W
  124. uint64_t Montgomery_pp[MAXWORDS_FIELD]; // Montgomery constant -p^-1 mod 2^W, using a suitable value W
  125. uint64_t Montgomery_one[MAXWORDS_FIELD]; // Value one in Montgomery representation
  126. } CurveIsogenyStaticData, *PCurveIsogenyStaticData;
  127. // This data struct is initialized with the targeted curve isogeny system during setup
  128. typedef struct
  129. {
  130. CurveIsogeny_ID CurveIsogeny; // Curve isogeny system identifier, base curve defined over GF(p^2)
  131. unsigned int pwordbits; // Closest multiple of 32 to prime bitlength
  132. unsigned int owordbits; // Closest multiple of 32 to order bitlength
  133. unsigned int pbits; // Bitlength of the prime p
  134. digit_t *prime; // Prime p
  135. digit_t *A; // Base curve parameter "A"
  136. digit_t *C; // Base curve parameter "C"
  137. unsigned int oAbits; // Order bitlength for Alice
  138. digit_t *Aorder; // Order of Alice's (sub)group
  139. unsigned int oBbits; // Order bitlength for Bob
  140. unsigned int eB; // Power of Bob's subgroup order (i.e., oB = 3^eB)
  141. digit_t *Border; // Order of Bob's (sub)group
  142. digit_t *PA; // Alice's generator PA = (XPA,YPA), where XPA and YPA are defined over GF(p)
  143. digit_t *PB; // Bob's generator PB = (XPB,YPB), where XPB and YPB are defined over GF(p)
  144. unsigned int BigMont_A24; // BigMont's curve parameter A24 = (A+2)/4
  145. digit_t *BigMont_order; // BigMont's subgroup order
  146. digit_t *Montgomery_R2; // Montgomery constant (2^W)^2 mod p, using a suitable value W
  147. digit_t *Montgomery_pp; // Montgomery constant -p^-1 mod 2^W, using a suitable value W
  148. digit_t *Montgomery_one; // Value one in Montgomery representation
  149. RandomBytes RandomBytesFunction; // Function providing random bytes to generate nonces or secret keys
  150. } CurveIsogenyStruct, *PCurveIsogenyStruct;
  151. // Supported curve isogeny systems:
  152. // "SIDHp751", base curve: supersingular elliptic curve E: y^2 = x^3 + x
  153. extern CurveIsogenyStaticData CurveIsogeny_SIDHp751;
  154. /******************** Function prototypes ***********************/
  155. /*************** Setup/initialization functions *****************/
  156. // Dynamic allocation of memory for curve isogeny structure.
  157. // Returns NULL on error.
  158. PCurveIsogenyStruct SIDH_curve_allocate(PCurveIsogenyStaticData CurveData);
  159. // Initialize curve isogeny structure pCurveIsogeny with static data extracted from pCurveIsogenyData.
  160. // This needs to be called after allocating memory for "pCurveIsogeny" using SIDH_curve_allocate().
  161. CRYPTO_STATUS SIDH_curve_initialize(PCurveIsogenyStruct pCurveIsogeny, RandomBytes RandomBytesFunction, PCurveIsogenyStaticData pCurveIsogenyData);
  162. // Free memory for curve isogeny structure
  163. void SIDH_curve_free(PCurveIsogenyStruct pCurveIsogeny);
  164. // Output error/success message for a given CRYPTO_STATUS
  165. const char *SIDH_get_error_message(CRYPTO_STATUS Status);
  166. // Output random values in the range [1, order-1] in little endian format that can be used as private keys.
  167. CRYPTO_STATUS random_mod_order(digit_t *random_digits, unsigned int AliceOrBob, PCurveIsogenyStruct pCurveIsogeny);
  168. // Output random values in the range [1, BigMont_order-1] in little endian format that can be used as private keys
  169. // to compute scalar multiplications using the elliptic curve BigMont.
  170. CRYPTO_STATUS random_BigMont_mod_order(digit_t *random_digits, PCurveIsogenyStruct pCurveIsogeny);
  171. // Clear "nwords" digits from memory
  172. void clear_words(void *mem, digit_t nwords);
  173. #endif