mpint_i.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * mpint_i.h: definitions used internally by the bignum code, and
  3. * also a few other vaguely-bignum-like places.
  4. */
  5. /* ----------------------------------------------------------------------
  6. * The assorted conditional definitions of BignumInt and multiply
  7. * macros used throughout the bignum code to treat numbers as arrays
  8. * of the most conveniently sized word for the target machine.
  9. * Exported so that other code (e.g. poly1305) can use it too.
  10. *
  11. * This code must export, in whatever ifdef branch it ends up in:
  12. *
  13. * - two types: 'BignumInt' and 'BignumCarry'. BignumInt is an
  14. * unsigned integer type which will be used as the base word size
  15. * for all bignum operations. BignumCarry is an unsigned integer
  16. * type used to hold the carry flag taken as input and output by
  17. * the BignumADC macro (see below).
  18. *
  19. * - four constant macros: BIGNUM_INT_BITS, BIGNUM_INT_BYTES,
  20. * BIGNUM_TOP_BIT, BIGNUM_INT_MASK. These should be more or less
  21. * self-explanatory, but just in case, they give the number of bits
  22. * in BignumInt, the number of bytes that works out to, the
  23. * BignumInt value consisting of only the top bit, and the
  24. * BignumInt value with all bits set.
  25. *
  26. * - four statement macros: BignumADC, BignumMUL, BignumMULADD,
  27. * BignumMULADD2. These do various kinds of multi-word arithmetic,
  28. * and all produce two output values.
  29. * * BignumADC(ret,retc,a,b,c) takes input BignumInt values a,b
  30. * and a BignumCarry c, and outputs a BignumInt ret = a+b+c and
  31. * a BignumCarry retc which is the carry off the top of that
  32. * addition.
  33. * * BignumMUL(rh,rl,a,b) returns the two halves of the
  34. * double-width product a*b.
  35. * * BignumMULADD(rh,rl,a,b,addend) returns the two halves of the
  36. * double-width value a*b + addend.
  37. * * BignumMULADD2(rh,rl,a,b,addend1,addend2) returns the two
  38. * halves of the double-width value a*b + addend1 + addend2.
  39. *
  40. * Every branch of the main ifdef below defines the type BignumInt and
  41. * the value BIGNUM_INT_BITS. The other three constant macros are
  42. * filled in by common code further down.
  43. *
  44. * Most branches also define a macro DEFINE_BIGNUMDBLINT containing a
  45. * typedef statement which declares a type _twice_ the length of a
  46. * BignumInt. This causes the common code further down to produce a
  47. * default implementation of the four statement macros in terms of
  48. * that double-width type, and also to defined BignumCarry to be
  49. * BignumInt.
  50. *
  51. * However, if a particular compile target does not have a type twice
  52. * the length of the BignumInt you want to use but it does provide
  53. * some alternative means of doing add-with-carry and double-word
  54. * multiply, then the ifdef branch in question can just define
  55. * BignumCarry and the four statement macros itself, and that's fine
  56. * too.
  57. */
  58. #if defined __SIZEOF_INT128__
  59. /*
  60. * 64-bit BignumInt using gcc/clang style 128-bit BignumDblInt.
  61. *
  62. * gcc and clang both provide a __uint128_t type on 64-bit targets
  63. * (and, when they do, indicate its presence by the above macro),
  64. * using the same 'two machine registers' kind of code generation
  65. * that 32-bit targets use for 64-bit ints.
  66. */
  67. typedef unsigned long long BignumInt;
  68. #define BIGNUM_INT_BITS_BITS 6
  69. #define DEFINE_BIGNUMDBLINT typedef __uint128_t BignumDblInt
  70. #elif defined _MSC_VER && defined _M_AMD64
  71. /*
  72. * 64-bit BignumInt, using Visual Studio x86-64 compiler intrinsics.
  73. *
  74. * 64-bit Visual Studio doesn't provide very much in the way of help
  75. * here: there's no int128 type, and also no inline assembler giving
  76. * us direct access to the x86-64 MUL or ADC instructions. However,
  77. * there are compiler intrinsics giving us that access, so we can
  78. * use those - though it turns out we have to be a little careful,
  79. * since they seem to generate wrong code if their pointer-typed
  80. * output parameters alias their inputs. Hence all the internal temp
  81. * variables inside the macros.
  82. */
  83. #include <intrin.h>
  84. typedef unsigned char BignumCarry; /* the type _addcarry_u64 likes to use */
  85. typedef unsigned __int64 BignumInt;
  86. #define BIGNUM_INT_BITS_BITS 6
  87. #define BignumADC(ret, retc, a, b, c) do \
  88. { \
  89. BignumInt ADC_tmp; \
  90. (retc) = _addcarry_u64(c, a, b, &ADC_tmp); \
  91. (ret) = ADC_tmp; \
  92. } while (0)
  93. #define BignumMUL(rh, rl, a, b) do \
  94. { \
  95. BignumInt MULADD_hi; \
  96. (rl) = _umul128(a, b, &MULADD_hi); \
  97. (rh) = MULADD_hi; \
  98. } while (0)
  99. #define BignumMULADD(rh, rl, a, b, addend) do \
  100. { \
  101. BignumInt MULADD_lo, MULADD_hi; \
  102. MULADD_lo = _umul128(a, b, &MULADD_hi); \
  103. MULADD_hi += _addcarry_u64(0, MULADD_lo, (addend), &(rl)); \
  104. (rh) = MULADD_hi; \
  105. } while (0)
  106. #define BignumMULADD2(rh, rl, a, b, addend1, addend2) do \
  107. { \
  108. BignumInt MULADD_lo1, MULADD_lo2, MULADD_hi; \
  109. MULADD_lo1 = _umul128(a, b, &MULADD_hi); \
  110. MULADD_hi += _addcarry_u64(0, MULADD_lo1, (addend1), &MULADD_lo2); \
  111. MULADD_hi += _addcarry_u64(0, MULADD_lo2, (addend2), &(rl)); \
  112. (rh) = MULADD_hi; \
  113. } while (0)
  114. #elif defined __GNUC__ || defined _LLP64 || __STDC__ >= 199901L
  115. /* 32-bit BignumInt, using C99 unsigned long long as BignumDblInt */
  116. typedef unsigned int BignumInt;
  117. #define BIGNUM_INT_BITS_BITS 5
  118. #define DEFINE_BIGNUMDBLINT typedef unsigned long long BignumDblInt
  119. #elif (defined _MSC_VER && defined _M_IX86) || defined(MPEXT)
  120. /* 32-bit BignumInt, using Visual Studio __int64 as BignumDblInt */
  121. typedef unsigned int BignumInt;
  122. #define BIGNUM_INT_BITS_BITS 5
  123. #define DEFINE_BIGNUMDBLINT typedef unsigned __int64 BignumDblInt
  124. #elif defined _LP64
  125. /*
  126. * 32-bit BignumInt, using unsigned long itself as BignumDblInt.
  127. *
  128. * Only for platforms where long is 64 bits, of course.
  129. */
  130. typedef unsigned int BignumInt;
  131. #define BIGNUM_INT_BITS_BITS 5
  132. #define DEFINE_BIGNUMDBLINT typedef unsigned long BignumDblInt
  133. #else
  134. /*
  135. * 16-bit BignumInt, using unsigned long as BignumDblInt.
  136. *
  137. * This is the final fallback for real emergencies: C89 guarantees
  138. * unsigned short/long to be at least the required sizes, so this
  139. * should work on any C implementation at all. But it'll be
  140. * noticeably slow, so if you find yourself in this case you
  141. * probably want to move heaven and earth to find an alternative!
  142. */
  143. typedef unsigned short BignumInt;
  144. #define BIGNUM_INT_BITS_BITS 4
  145. #define DEFINE_BIGNUMDBLINT typedef unsigned long BignumDblInt
  146. #endif
  147. /*
  148. * Common code across all branches of that ifdef: define all the
  149. * easy constant macros in terms of BIGNUM_INT_BITS_BITS.
  150. */
  151. #define BIGNUM_INT_BITS (1 << BIGNUM_INT_BITS_BITS)
  152. #define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8)
  153. #define BIGNUM_TOP_BIT (((BignumInt)1) << (BIGNUM_INT_BITS-1))
  154. #define BIGNUM_INT_MASK (BIGNUM_TOP_BIT | (BIGNUM_TOP_BIT-1))
  155. /*
  156. * Common code across _most_ branches of the ifdef: define a set of
  157. * statement macros in terms of the BignumDblInt type provided. In
  158. * this case, we also define BignumCarry to be the same thing as
  159. * BignumInt, for simplicity.
  160. */
  161. #ifdef DEFINE_BIGNUMDBLINT
  162. typedef BignumInt BignumCarry;
  163. #define BignumADC(ret, retc, a, b, c) do \
  164. { \
  165. DEFINE_BIGNUMDBLINT; \
  166. BignumDblInt ADC_temp = (BignumInt)(a); \
  167. ADC_temp += (BignumInt)(b); \
  168. ADC_temp += (c); \
  169. (ret) = (BignumInt)ADC_temp; \
  170. (retc) = (BignumCarry)(ADC_temp >> BIGNUM_INT_BITS); \
  171. } while (0)
  172. #define BignumMUL(rh, rl, a, b) do \
  173. { \
  174. DEFINE_BIGNUMDBLINT; \
  175. BignumDblInt MUL_temp = (BignumInt)(a); \
  176. MUL_temp *= (BignumInt)(b); \
  177. (rh) = (BignumInt)(MUL_temp >> BIGNUM_INT_BITS); \
  178. (rl) = (BignumInt)(MUL_temp); \
  179. } while (0)
  180. #define BignumMULADD(rh, rl, a, b, addend) do \
  181. { \
  182. DEFINE_BIGNUMDBLINT; \
  183. BignumDblInt MUL_temp = (BignumInt)(a); \
  184. MUL_temp *= (BignumInt)(b); \
  185. MUL_temp += (BignumInt)(addend); \
  186. (rh) = (BignumInt)(MUL_temp >> BIGNUM_INT_BITS); \
  187. (rl) = (BignumInt)(MUL_temp); \
  188. } while (0)
  189. #define BignumMULADD2(rh, rl, a, b, addend1, addend2) do \
  190. { \
  191. DEFINE_BIGNUMDBLINT; \
  192. BignumDblInt MUL_temp = (BignumInt)(a); \
  193. MUL_temp *= (BignumInt)(b); \
  194. MUL_temp += (BignumInt)(addend1); \
  195. MUL_temp += (BignumInt)(addend2); \
  196. (rh) = (BignumInt)(MUL_temp >> BIGNUM_INT_BITS); \
  197. (rl) = (BignumInt)(MUL_temp); \
  198. } while (0)
  199. #endif /* DEFINE_BIGNUMDBLINT */
  200. /* ----------------------------------------------------------------------
  201. * Data structures used inside bignum.c.
  202. */
  203. struct mp_int {
  204. size_t nw;
  205. BignumInt *w;
  206. };
  207. struct MontyContext {
  208. /*
  209. * The actual modulus.
  210. */
  211. mp_int *m;
  212. /*
  213. * Montgomery multiplication works by selecting a value r > m,
  214. * coprime to m, which is really easy to divide by. In binary
  215. * arithmetic, that means making it a power of 2; in fact we make
  216. * it a whole number of BignumInt.
  217. *
  218. * We don't store r directly as an mp_int (there's no need). But
  219. * its value is 2^rbits; we also store rw = rbits/BIGNUM_INT_BITS
  220. * (the corresponding word offset within an mp_int).
  221. *
  222. * pw is the number of words needed to store an mp_int you're
  223. * doing reduction on: it has to be big enough to hold the sum of
  224. * an input value up to m^2 plus an extra addend up to m*r.
  225. */
  226. size_t rbits, rw, pw;
  227. /*
  228. * The key step in Montgomery reduction requires the inverse of -m
  229. * mod r.
  230. */
  231. mp_int *minus_minv_mod_r;
  232. /*
  233. * r^1, r^2 and r^3 mod m, which are used for various purposes.
  234. *
  235. * (Annoyingly, this is one of the rare cases where it would have
  236. * been nicer to have a Pascal-style 1-indexed array. I couldn't
  237. * _quite_ bring myself to put a gratuitous zero element in here.
  238. * So you just have to live with getting r^k by taking the [k-1]th
  239. * element of this array.)
  240. */
  241. mp_int *powers_of_r_mod_m[3];
  242. /*
  243. * Persistent scratch space from which monty_* functions can
  244. * allocate storage for intermediate values.
  245. */
  246. mp_int *scratch;
  247. };