#ifndef BOOST_INTEGER_MOD_INVERSE_HPP
#define BOOST_INTEGER_MOD_INVERSE_HPP
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/integer/extended_euclidean.hpp>
namespace boost { namespace integer {
template<class Z>
Z mod_inverse(Z a, Z modulus)
{
if (modulus < Z(2))
{
BOOST_THROW_EXCEPTION(std::domain_error("mod_inverse: modulus must be > 1"));
}
a = a % modulus;
if (a == Z(0))
{
return Z(0);
}
boost::integer::euclidean_result_t<Z> u = boost::integer::extended_euclidean(a, modulus);
if (u.gcd > Z(1))
{
return Z(0);
}
while (u.x <= Z(0))
{
u.x += modulus;
}
return u.x;
}
}}
#endif