Intro to Extended Euclidean Algorithm
Intro to Extended Euclidean Algorithm
CX330Prologue
I decided to write this to help myself to better understand the attacks in RSA or other crypto system. And if this can help you, that would be my honor! Also, all the code in this note will in Python since it’s the most used exploit script language in CTFs.
Let’s start!
Euclidean Algorithm
Intro
It’s an algorithm to calculate the GCD (Greatest Common Divisor) between 2 numbers, and in Chinese, it’s called 輾轉相除法 BTW.
Principles
It’s an recursive algorithm, so every step’s output is the input of the next step. Here we set is the count of the steps, starting from 0.
The inputs of every step are non-negative remainders . And since the remainders obtained by each round are smaller than those calculated in the former round, . In the step, the algorithm calculates the quotient and remainder that satisfy the following equations.
That is, should recursively minus until it’s less than .
In the first step (), we set and are equal to and . In the second step (), we calculate the quotient and the remainder by dividing (which is ) by (the remainder we obtained in the first step), and so on. The whole algorithm can be represented by the following equations.
If , the first step is actually switching those, since .
Because the remainder calculate in each step is always decreasing and never gonna be negative, there must be an such that in the step. Then is the GCD of and . Also, is impossible to be infinite so there must be finite natural numbers between and .
Code
def euclidean_algorithm(a, b) -> int:
if (b == 0):
return a
return euclidean_algorithm(b, a%b)
This function will return the GCD of .
Extended Euclidean Algorithm
Intro
Extended Euclidean Algorithm, obviously is the extension of Euclidean Algorithm. For known , the Extended Euclidean Algorithm can find the that satisfy the Bézout’s identity while obtaining . If , we can change the problem into , and let .
Bézout’s identity is an important result in Number Theory, describing the relationship between the GCD of 2 numbers & their linear combinations. The equation is
For arbitrary 2 integers , there must be integers that satisfy this equation.
By the way, the Extended Euclidean Algorithm is an self-verifying algorithm. We can simply use the and obtained in the last step to times , and see if they’re equal to and to verify the calculation is correct.
And the most important thing for us (CTFers, or cybersecurity enthusiasts) is that this algorithm can be used to calculate the modular multiplicative inverse, which is necessary in RSA to obtain the keys.
Principles
In an standard Euclidean Algorithm, we mark the 2 numbers for which we want to calculate the GCD as and , and the quotient we get in the step to be , remainder to be . Then we can write the Eulidean Algorithm as following.
When some step the , the algorithm breaks. And the obtained in the last step is .
The Extended Euclidean Algorithm adds 2 additional sequences and based on and , and lets , , and . In the Extended Euclidean Algorithm, each step calculates , and furthermore calculates and , which is
And the breaking condition is the same with the Euclidean Algorithm, which is , and the and at this time is the solution for .
To find the modular multiplicative inverse , we can use the following steps.
- Confirm that and are coprime, which means , if it’s not, then the doesn’t exist.
- Use the Extended Euclidean Algorithm to solve , then the is what we want.
For example, if we want to find the modular multiplicative inverse of 3 modulo 11.
To learn more about how the Extended Euclidean Algorithm is used in attacking RSA, I will put some challenge here ASAP.
Code
def extended_euclidean(a: int, b: int) -> tuple[int, int, int]:
if a == 0:
return (b, 0, 1)
g, y, x = extended_euclidean(b % a, a)
return (g, x - (b // a) * y, y)
def inverse(a: int, b: int) -> int:
g, x, y = extended_euclidean(a, b) # ax + by = gcd
if g == 1:
return x % b
raise ValueError("base is not invertible for the given modulus.")