The extended Euclidian algorithm

The extended Euclidian algorithm is based on the Euclidian algorithm, which finds the greatest common divisor of two numbers . The extended Euclidian algorithm also does some bookkeeping, which allows it to express the greatest common divisor as a linear combination of and . For example, if we run the Euclidian algorithm for , we find that . Now, running the Euclidian algorithm tells us that and additionally tells us that .

Theory

If we suppose that the Euclidian algorithm is used to find the greatest common divisor of where , we can formulate the algorithm as a recurrent relation

which is then applied until , in which case is the greatest common divisor of and .

The extended Euclidian algorithm now keeps numbers such that

Obviously, we have and . Using that , we see that

To find and , use that . Using and we see that

factoring out and , we see that

so we see that

Implementation

Normally I try to give an implementation that works in C-style languages. However, the C-style languages are rather primitive in the sense that they provide no uniform and comfortable way to use tuples, so I will use Python for now.

Like in the implementation for Euclids algorithm, we have a wrapper that ensures that the first argument is always the biggest. The wrapper returns a triple (gcd, p, q), such that gcd is the greatest common divisor, and we have .

def gcd_extended(a, b):
	if a < b:
		(gcd, p, q) = gcd_extended_helper(b, 1, 0, a, 0, 1)
		return (gcd, q, p)
	else: return gcd_extended_helper(a, 1, 0, b, 0, 1)

Like for Euclids algorithm, we can use a recursive implementation

def gcd_extended_helper(a, p, q, b, r, s):
	if b == 0: return (a, p, q)
	k = a // b;
	return gcd_extended_helper(b, r, s, a - k * b, p - k * r, q - k * s)

or an iterative one

def gcd_extended_helper(a, p, q, b, r, s):
	while b != 0:
		(a, p, q, b, r, s) = (b, r, s, a - k * b, p - k * r, q - k * s)
	return (a, p, q)

Applications

When modular arithmetic modulo some number , we may want to find a multiplicative inverse of the element . That is, we want to find such that

Now, such an element only exists if , which is why it is often convenient to take prime (we can take any ). Now, note that if , then we have . So is the element we’re looking for.

Now we can define a function that computes the multiplicative inverse modulo as follows:

def inverse_modulo(a, n):
	(gcd, p, q) = gcd_extended(a, n)
	return p