mod_inverse_test.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * (C) Copyright Nick Thompson 2018.
  3. * Use, modification and distribution are subject to the
  4. * Boost Software License, Version 1.0. (See accompanying file
  5. * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. #include "multiprecision_config.hpp"
  8. #ifndef DISABLE_MP_TESTS
  9. #include <boost/integer/mod_inverse.hpp>
  10. #include <boost/cstdint.hpp>
  11. #include <boost/optional/optional.hpp>
  12. #include <boost/core/lightweight_test.hpp>
  13. #include <boost/multiprecision/cpp_int.hpp>
  14. #include <boost/integer/common_factor.hpp>
  15. using boost::multiprecision::int128_t;
  16. using boost::multiprecision::int256_t;
  17. using boost::integer::mod_inverse;
  18. using boost::integer::gcd;
  19. template<class Z>
  20. void test_mod_inverse()
  21. {
  22. //Z max_arg = std::numeric_limits<Z>::max();
  23. Z max_arg = 500;
  24. for (Z modulus = 2; modulus < max_arg; ++modulus)
  25. {
  26. if (modulus % 1000 == 0)
  27. {
  28. std::cout << "Testing all inverses modulo " << modulus << std::endl;
  29. }
  30. for (Z a = 1; a < modulus; ++a)
  31. {
  32. Z gcdam = gcd(a, modulus);
  33. Z inv_a = mod_inverse(a, modulus);
  34. // Should fail if gcd(a, mod) != 1:
  35. if (gcdam > 1)
  36. {
  37. BOOST_TEST(inv_a == 0);
  38. }
  39. else
  40. {
  41. BOOST_TEST(inv_a > 0);
  42. // Cast to a bigger type so the multiplication won't overflow.
  43. int256_t a_inv = inv_a;
  44. int256_t big_a = a;
  45. int256_t m = modulus;
  46. int256_t outta_be_one = (a_inv*big_a) % m;
  47. BOOST_TEST_EQ(outta_be_one, 1);
  48. }
  49. }
  50. }
  51. }
  52. int main()
  53. {
  54. test_mod_inverse<boost::int16_t>();
  55. test_mod_inverse<boost::int32_t>();
  56. test_mod_inverse<boost::int64_t>();
  57. test_mod_inverse<int128_t>();
  58. return boost::report_errors();
  59. }
  60. #else
  61. int main()
  62. {
  63. return 0;
  64. }
  65. #endif