static void extendedGCD(uint64_t a, uint64_t b, int64_t *x, int64_t *y) { if (b == 0) { *x = 1; *y = 0; return; } int64_t d = a / b, xp, yp; extendedGCD(b, a % b, &xp, &yp); *x = yp; *y = xp - (d * yp); }
/** * \brief Extended Euclidean algorithm * * Computes 'x' and 'y' that satisfy gcd(a, b) = ax + by, * where x and y may be negative. */ void extendedGCD(uint64_t a, uint64_t b, int64_t &x, int64_t &y) { if (b == 0) { x = 1; y = 0; return; } int64_t d = a / b, x_, y_; extendedGCD(b, a % b, x_, y_); x = y_; y = x_ - (int64_t) (d * y_); }
static uint64_t multiplicativeInverse(int64_t a, int64_t n) { int64_t x, y; extendedGCD(a, n, &x, &y); return Mod(x, n); }
/** * \brief Compute the multiplicative inverse of a math::modulo n, * where a and n a re relative prime. The result is in the * range 1, ..., n - 1. */ uint64_t multiplicativeInverse(int64_t a, int64_t n) { int64_t x, y; extendedGCD(a, n, x, y); return math::modulo(x, n); }