bn_mp_montgomery_setup.c 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. #include "tommath_private.h"
  2. #ifdef BN_MP_MONTGOMERY_SETUP_C
  3. /* LibTomMath, multiple-precision integer library -- Tom St Denis */
  4. /* SPDX-License-Identifier: Unlicense */
  5. /* setups the montgomery reduction stuff */
  6. mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho)
  7. {
  8. mp_digit x, b;
  9. /* fast inversion mod 2**k
  10. *
  11. * Based on the fact that
  12. *
  13. * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
  14. * => 2*X*A - X*X*A*A = 1
  15. * => 2*(1) - (1) = 1
  16. */
  17. b = n->dp[0];
  18. if ((b & 1u) == 0u) {
  19. return MP_VAL;
  20. }
  21. x = (((b + 2u) & 4u) << 1) + b; /* here x*a==1 mod 2**4 */
  22. x *= 2u - (b * x); /* here x*a==1 mod 2**8 */
  23. #if !defined(MP_8BIT)
  24. x *= 2u - (b * x); /* here x*a==1 mod 2**16 */
  25. #endif
  26. #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
  27. x *= 2u - (b * x); /* here x*a==1 mod 2**32 */
  28. #endif
  29. #ifdef MP_64BIT
  30. x *= 2u - (b * x); /* here x*a==1 mod 2**64 */
  31. #endif
  32. /* rho = -1/m mod b */
  33. *rho = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - x) & MP_MASK;
  34. return MP_OKAY;
  35. }
  36. #endif