| 12345678910111213141516171819202122232425262728293031323334353637383940 |
- def extended_euclidean_algorithm(a, b):
- """
- Returns a three-tuple (gcd, x, y) such that
- a * x + b * y == gcd, where gcd is the greatest
- common divisor of a and b.
- This function implements the extended Euclidean
- algorithm and runs in O(log b) in the worst case.
- """
- s, old_s = 0, 1
- t, old_t = 1, 0
- r, old_r = b, a
- while r != 0:
- quotient = old_r // r
- old_r, r = r, old_r - quotient * r
- old_s, s = s, old_s - quotient * s
- old_t, t = t, old_t - quotient * t
- return old_r, old_s, old_t
- def inverse_of(n, p):
- """
- Returns the multiplicative inverse of
- n modulo p.
- This function returns an integer m such that
- (n * m) % p == 1.
- """
- gcd, x, y = extended_euclidean_algorithm(n, p)
- assert (n * x + p * y) % p == gcd
- if gcd != 1:
- # Either n is 0, or p is not a prime number.
- raise ValueError(
- '{} has no multiplicative inverse '
- 'modulo {}'.format(n, p))
- else:
- return x % p
|