tommath_private.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /* LibTomMath, multiple-precision integer library -- Tom St Denis */
  2. /* SPDX-License-Identifier: Unlicense */
  3. #ifndef TOMMATH_PRIV_H_
  4. #define TOMMATH_PRIV_H_
  5. #include "tommath.h"
  6. #include "tommath_class.h"
  7. /*
  8. * Private symbols
  9. * ---------------
  10. *
  11. * On Unix symbols can be marked as hidden if libtommath is compiled
  12. * as a shared object. By default, symbols are visible.
  13. * As of now, this feature is opt-in via the MP_PRIVATE_SYMBOLS define.
  14. *
  15. * On Win32 a .def file must be used to specify the exported symbols.
  16. */
  17. #if defined (MP_PRIVATE_SYMBOLS) && defined(__GNUC__) && __GNUC__ >= 4
  18. # define MP_PRIVATE __attribute__ ((visibility ("hidden")))
  19. #else
  20. # define MP_PRIVATE
  21. #endif
  22. /* Hardening libtommath
  23. * --------------------
  24. *
  25. * By default memory is zeroed before calling
  26. * MP_FREE to avoid leaking data. This is good
  27. * practice in cryptographical applications.
  28. *
  29. * Note however that memory allocators used
  30. * in cryptographical applications can often
  31. * be configured by itself to clear memory,
  32. * rendering the clearing in tommath unnecessary.
  33. * See for example https://github.com/GrapheneOS/hardened_malloc
  34. * and the option CONFIG_ZERO_ON_FREE.
  35. *
  36. * Furthermore there are applications which
  37. * value performance more and want this
  38. * feature to be disabled. For such applications
  39. * define MP_NO_ZERO_ON_FREE during compilation.
  40. */
  41. #ifdef MP_NO_ZERO_ON_FREE
  42. # define MP_FREE_BUFFER(mem, size) MP_FREE((mem), (size))
  43. # define MP_FREE_DIGITS(mem, digits) MP_FREE((mem), sizeof (mp_digit) * (size_t)(digits))
  44. #else
  45. # define MP_FREE_BUFFER(mem, size) \
  46. do { \
  47. size_t fs_ = (size); \
  48. void* fm_ = (mem); \
  49. if (fm_ != NULL) { \
  50. MP_ZERO_BUFFER(fm_, fs_); \
  51. MP_FREE(fm_, fs_); \
  52. } \
  53. } while (0)
  54. # define MP_FREE_DIGITS(mem, digits) \
  55. do { \
  56. int fd_ = (digits); \
  57. void* fm_ = (mem); \
  58. if (fm_ != NULL) { \
  59. size_t fs_ = sizeof (mp_digit) * (size_t)fd_; \
  60. MP_ZERO_BUFFER(fm_, fs_); \
  61. MP_FREE(fm_, fs_); \
  62. } \
  63. } while (0)
  64. #endif
  65. #ifdef MP_USE_MEMSET
  66. # include <string.h>
  67. # define MP_ZERO_BUFFER(mem, size) memset((mem), 0, (size))
  68. # define MP_ZERO_DIGITS(mem, digits) \
  69. do { \
  70. int zd_ = (digits); \
  71. if (zd_ > 0) { \
  72. memset((mem), 0, sizeof(mp_digit) * (size_t)zd_); \
  73. } \
  74. } while (0)
  75. #else
  76. # define MP_ZERO_BUFFER(mem, size) \
  77. do { \
  78. size_t zs_ = (size); \
  79. char* zm_ = (char*)(mem); \
  80. while (zs_-- > 0u) { \
  81. *zm_++ = '\0'; \
  82. } \
  83. } while (0)
  84. # define MP_ZERO_DIGITS(mem, digits) \
  85. do { \
  86. int zd_ = (digits); \
  87. mp_digit* zm_ = (mem); \
  88. while (zd_-- > 0) { \
  89. *zm_++ = 0; \
  90. } \
  91. } while (0)
  92. #endif
  93. /* Tunable cutoffs
  94. * ---------------
  95. *
  96. * - In the default settings, a cutoff X can be modified at runtime
  97. * by adjusting the corresponding X_CUTOFF variable.
  98. *
  99. * - Tunability of the library can be disabled at compile time
  100. * by defining the MP_FIXED_CUTOFFS macro.
  101. *
  102. * - There is an additional file tommath_cutoffs.h, which defines
  103. * the default cutoffs. These can be adjusted manually or by the
  104. * autotuner.
  105. *
  106. */
  107. #ifdef MP_FIXED_CUTOFFS
  108. # include "tommath_cutoffs.h"
  109. # define MP_KARATSUBA_MUL_CUTOFF MP_DEFAULT_KARATSUBA_MUL_CUTOFF
  110. # define MP_KARATSUBA_SQR_CUTOFF MP_DEFAULT_KARATSUBA_SQR_CUTOFF
  111. # define MP_TOOM_MUL_CUTOFF MP_DEFAULT_TOOM_MUL_CUTOFF
  112. # define MP_TOOM_SQR_CUTOFF MP_DEFAULT_TOOM_SQR_CUTOFF
  113. #else
  114. # define MP_KARATSUBA_MUL_CUTOFF KARATSUBA_MUL_CUTOFF
  115. # define MP_KARATSUBA_SQR_CUTOFF KARATSUBA_SQR_CUTOFF
  116. # define MP_TOOM_MUL_CUTOFF TOOM_MUL_CUTOFF
  117. # define MP_TOOM_SQR_CUTOFF TOOM_SQR_CUTOFF
  118. #endif
  119. /* define heap macros */
  120. #ifndef MP_MALLOC
  121. /* default to libc stuff */
  122. # include <stdlib.h>
  123. # define MP_MALLOC(size) malloc(size)
  124. # define MP_REALLOC(mem, oldsize, newsize) realloc((mem), (newsize))
  125. # define MP_CALLOC(nmemb, size) calloc((nmemb), (size))
  126. # define MP_FREE(mem, size) free(mem)
  127. #else
  128. /* prototypes for our heap functions */
  129. extern void *MP_MALLOC(size_t size);
  130. extern void *MP_REALLOC(void *mem, size_t oldsize, size_t newsize);
  131. extern void *MP_CALLOC(size_t nmemb, size_t size);
  132. extern void MP_FREE(void *mem, size_t size);
  133. #endif
  134. /* feature detection macro */
  135. #ifdef _MSC_VER
  136. /* Prevent false positive: not enough arguments for function-like macro invocation */
  137. #pragma warning(disable: 4003)
  138. #endif
  139. #define MP_STRINGIZE(x) MP__STRINGIZE(x)
  140. #define MP__STRINGIZE(x) ""#x""
  141. #define MP_HAS(x) (sizeof(MP_STRINGIZE(BN_##x##_C)) == 1u)
  142. /* TODO: Remove private_mp_word as soon as deprecated mp_word is removed from tommath. */
  143. #undef mp_word
  144. typedef private_mp_word mp_word;
  145. #define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
  146. #define MP_MAX(x, y) (((x) > (y)) ? (x) : (y))
  147. /* Static assertion */
  148. #define MP_STATIC_ASSERT(msg, cond) typedef char mp_static_assert_##msg[(cond) ? 1 : -1];
  149. /* ---> Basic Manipulations <--- */
  150. #define MP_IS_ZERO(a) ((a)->used == 0)
  151. #define MP_IS_EVEN(a) (((a)->used == 0) || (((a)->dp[0] & 1u) == 0u))
  152. #define MP_IS_ODD(a) (((a)->used > 0) && (((a)->dp[0] & 1u) == 1u))
  153. #define MP_SIZEOF_BITS(type) ((size_t)CHAR_BIT * sizeof(type))
  154. #define MP_MAXFAST (int)(1uL << (MP_SIZEOF_BITS(mp_word) - (2u * (size_t)MP_DIGIT_BIT)))
  155. /* TODO: Remove PRIVATE_MP_WARRAY as soon as deprecated MP_WARRAY is removed from tommath.h */
  156. #undef MP_WARRAY
  157. #define MP_WARRAY PRIVATE_MP_WARRAY
  158. /* TODO: Remove PRIVATE_MP_PREC as soon as deprecated MP_PREC is removed from tommath.h */
  159. #ifdef PRIVATE_MP_PREC
  160. # undef MP_PREC
  161. # define MP_PREC PRIVATE_MP_PREC
  162. #endif
  163. /* Minimum number of available digits in mp_int, MP_PREC >= MP_MIN_PREC */
  164. #define MP_MIN_PREC ((((int)MP_SIZEOF_BITS(long long) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT)
  165. MP_STATIC_ASSERT(prec_geq_min_prec, MP_PREC >= MP_MIN_PREC)
  166. /* random number source */
  167. extern MP_PRIVATE mp_err(*s_mp_rand_source)(void *out, size_t size);
  168. /* lowlevel functions, do not call! */
  169. MP_PRIVATE mp_bool s_mp_get_bit(const mp_int *a, unsigned int b);
  170. MP_PRIVATE mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR;
  171. MP_PRIVATE mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR;
  172. MP_PRIVATE mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR;
  173. MP_PRIVATE mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR;
  174. MP_PRIVATE mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR;
  175. MP_PRIVATE mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR;
  176. MP_PRIVATE mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) MP_WUR;
  177. MP_PRIVATE mp_err s_mp_sqr(const mp_int *a, mp_int *b) MP_WUR;
  178. MP_PRIVATE mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR;
  179. MP_PRIVATE mp_err s_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR;
  180. MP_PRIVATE mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR;
  181. MP_PRIVATE mp_err s_mp_karatsuba_sqr(const mp_int *a, mp_int *b) MP_WUR;
  182. MP_PRIVATE mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b) MP_WUR;
  183. MP_PRIVATE mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR;
  184. MP_PRIVATE mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR;
  185. MP_PRIVATE mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) MP_WUR;
  186. MP_PRIVATE mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) MP_WUR;
  187. MP_PRIVATE mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) MP_WUR;
  188. MP_PRIVATE mp_err s_mp_rand_platform(void *p, size_t n) MP_WUR;
  189. MP_PRIVATE mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat);
  190. MP_PRIVATE void s_mp_reverse(unsigned char *s, size_t len);
  191. MP_PRIVATE mp_err s_mp_prime_is_divisible(const mp_int *a, mp_bool *result);
  192. /* TODO: jenkins prng is not thread safe as of now */
  193. MP_PRIVATE mp_err s_mp_rand_jenkins(void *p, size_t n) MP_WUR;
  194. MP_PRIVATE void s_mp_rand_jenkins_init(uint64_t seed);
  195. extern MP_PRIVATE const char *const mp_s_rmap;
  196. extern MP_PRIVATE const uint8_t mp_s_rmap_reverse[];
  197. extern MP_PRIVATE const size_t mp_s_rmap_reverse_sz;
  198. extern MP_PRIVATE const mp_digit *s_mp_prime_tab;
  199. /* deprecated functions */
  200. MP_DEPRECATED(s_mp_invmod_fast) mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c);
  201. MP_DEPRECATED(s_mp_montgomery_reduce_fast) mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n,
  202. mp_digit rho);
  203. MP_DEPRECATED(s_mp_mul_digs_fast) mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c,
  204. int digs);
  205. MP_DEPRECATED(s_mp_mul_high_digs_fast) mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b,
  206. mp_int *c,
  207. int digs);
  208. MP_DEPRECATED(s_mp_sqr_fast) mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b);
  209. MP_DEPRECATED(s_mp_balance_mul) mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c);
  210. MP_DEPRECATED(s_mp_exptmod_fast) mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P,
  211. mp_int *Y,
  212. int redmode);
  213. MP_DEPRECATED(s_mp_invmod_slow) mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c);
  214. MP_DEPRECATED(s_mp_karatsuba_mul) mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c);
  215. MP_DEPRECATED(s_mp_karatsuba_sqr) mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b);
  216. MP_DEPRECATED(s_mp_toom_mul) mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c);
  217. MP_DEPRECATED(s_mp_toom_sqr) mp_err mp_toom_sqr(const mp_int *a, mp_int *b);
  218. MP_DEPRECATED(s_mp_reverse) void bn_reverse(unsigned char *s, int len);
  219. #define MP_GET_ENDIANNESS(x) \
  220. do{\
  221. int16_t n = 0x1; \
  222. char *p = (char *)&n; \
  223. x = (p[0] == '\x01') ? MP_LITTLE_ENDIAN : MP_BIG_ENDIAN; \
  224. } while (0)
  225. /* code-generating macros */
  226. #define MP_SET_UNSIGNED(name, type) \
  227. void name(mp_int * a, type b) \
  228. { \
  229. int i = 0; \
  230. while (b != 0u) { \
  231. a->dp[i++] = ((mp_digit)b & MP_MASK); \
  232. if (MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) { break; } \
  233. b >>= ((MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) ? 0 : MP_DIGIT_BIT); \
  234. } \
  235. a->used = i; \
  236. a->sign = MP_ZPOS; \
  237. MP_ZERO_DIGITS(a->dp + a->used, a->alloc - a->used); \
  238. }
  239. #define MP_SET_SIGNED(name, uname, type, utype) \
  240. void name(mp_int * a, type b) \
  241. { \
  242. uname(a, (b < 0) ? -(utype)b : (utype)b); \
  243. if (b < 0) { a->sign = MP_NEG; } \
  244. }
  245. #define MP_INIT_INT(name , set, type) \
  246. mp_err name(mp_int * a, type b) \
  247. { \
  248. mp_err err; \
  249. if ((err = mp_init(a)) != MP_OKAY) { \
  250. return err; \
  251. } \
  252. set(a, b); \
  253. return MP_OKAY; \
  254. }
  255. #define MP_GET_MAG(name, type) \
  256. type name(const mp_int* a) \
  257. { \
  258. unsigned i = MP_MIN((unsigned)a->used, (unsigned)((MP_SIZEOF_BITS(type) + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT)); \
  259. type res = 0u; \
  260. while (i --> 0u) { \
  261. res <<= ((MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) ? 0 : MP_DIGIT_BIT); \
  262. res |= (type)a->dp[i]; \
  263. if (MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) { break; } \
  264. } \
  265. return res; \
  266. }
  267. #define MP_GET_SIGNED(name, mag, type, utype) \
  268. type name(const mp_int* a) \
  269. { \
  270. utype res = mag(a); \
  271. return (a->sign == MP_NEG) ? (type)-res : (type)res; \
  272. }
  273. #endif