Section 2.2 Common divisors and the Euclidean algorithm
It turns out that the straightforward idea of numbers possessing divisors in common has important consequences for the construction of secure mathematical encryption schemes.
Definition 2.2.1.
Let \(a, b \in \Z\text{.}\) A number \(d\) is called a common divisor of \(a\) and \(b\) if \(d \mid a\) and \(d \mid b\text{.}\)Checkpoint 2.2.2.
As a common divisor can be no larger than either of the numbers \(a\) and \(b\text{,}\) there always must be a largest such \(d\text{,}\) called the greatest common divisor. We denote the greatest common divisor of \(a\) and \(b\) with the symbol \(\gcd(a,b)\text{.}\) Finding a gcd is straightforward task in the case that the numbers are small - we can perform a factorization of the numbers, compare factors, and construct the gcd by multiplying all of the factors that the numbers have in common. For example, \(\gcd(128, 36) = 4\) because \(128 = 2^7\) and \(36 = 2^2 3^2\text{,}\) and thus the numbers share \(2^2\) as a common factor. However, at the scale of numbers used in cryptography, this is not an efficient method for finding a gcd.
Checkpoint 2.2.3.
We need an alternative approach. Fortunately, an easy observation about the division algorithm will provide the foundation for a significantly more efficient method. Let \(a, b \in \Z\text{.}\) By the division algorithm, there are unique numbers \(q, r \in \Z\) with \(0 \leq r \lt b\) so that
Observe that if \(d \mid a\) and \(d \mid b\) then \(d \mid r\text{.}\) (Why?) Observe that if \(e \mid b\) and \(e \mid r\) then \(e \mid a\text{.}\) (Why?) This means that the common divisors of \(a\) and \(b\) are the same as the common divisors of \(b\) and \(r\text{.}\) We conclude that \(\gcd(a,b) = \gcd(b, r)\text{.}\) This reduction of complexity gives us the core step in what is known as the Euclidean algorithm. Finally, observe that since every nonzero integer divides \(0\text{,}\) we have \(\gcd(n, 0) = n\text{.}\)
Theorem 2.2.4. (Euclidean algorithm).
Let \(a, b\) be postive integers with \(a \geq b\text{.}\) Then \(\gcd(a,b) = \gcd(r_{n-1},0) = r_{n-1}\) where the remainder \(r_{n-1}\) is the remainder in the penultimate step in the process
- \(a = bq_1 + r_1\) (reduces problem to finding \(\gcd(b, r_1)\))
- \(b = r_1 q_2 + r_2\) (reduces problem to finding \(\gcd(r_1, r_2)\))
- \(r_1 = r_2 q_3 + r_3\) (reduces problem to finding \(\gcd(r_2, r_3)\)).
- \(\displaystyle \vdots\)
- \(r_{n-3} = r_{n-2} q_{n-1} + r_{n-1}\) (reduces problem to \(\gcd(r_{n-2}, r_{n-1}))\))
- \(r_{n-2} = r_{n-1} q_n + 0\) (reduces to \(\gcd(r_{n-1}, 0) = r_{n-1}\)).
There is actually more information contained in the calculation above. Let \(a = 2024\) and \(b = 748\text{.}\) Using a series of cascading substitutions, we can show that
In fact, it is always the case that \(\gcd(a,b)\) can be written as an integer linear combination of \(a\) and \(b\text{,}\) a result known as the extended Euclidean algorithm.
Theorem 2.2.5. (extended Euclidean algorithm).
\(a, b\)- Use the Euclidean algorithm to find the string of quotients \(q_1, \ldots, q_n\) appearing in the descending equations, where \(n\) is the number of steps required to reach remainder 0.
-
Construct two recursive sequences, \(P\) and \(Q\text{.}\)
- Set \(P_0 = 1, P_1 = q_1\) and \(P_{k} = q_k \cdot P_{k-1} + P_{k-2}\) for \(2 \leq k \leq n\text{.}\) The sequence will terminate with \(P_n = a\text{.}\)
- Set \(Q_0 = 0, Q_1 = 1\) and \(Q_{k} = q_k \cdot Q_{k-1} + Q_{k-2}\) for \(2 \leq k \leq n\text{.}\) The sequence will terminate with \(Q_n = b\text{.}\)
- The final terms of the sequence will satisfy the equation\begin{equation*} a Q_{n-1} - b P_{n-1} = (-1)^n. \end{equation*}Dividing through by \((-1)^n\) will give\begin{equation*} a ((-1)^n Q_{n-1}) - b ((-1)^n P_{n-1}) = 1, \end{equation*}which gives \(u\) and \(v\text{.}\)
You should notice that the algorithm can actually be used on any pair \(a, b\) by dividing through by the gcd.
Checkpoint 2.2.6.
You can make a nice visual representation of the algorithm with an array:
\(q_1\) | \(q_2\) | \(q_{n-1}\) | \(q_n\) | |||
\(0\) | \(1\) | \(P_1\) | \(P_2\) | \(\ldots\) | \(P_{n-1}\) | \(P_n = a\) |
\(1\) | \(0\) | \(Q_1\) | \(Q_2\) | \(\ldots\) | \(Q_{n-1}\) | \(Q_n = a\) |
The above algorithm is powerful, but requires storing potentially lots of information. There are more efficient approaches, though you may wish to implement the algorithm above.
Example 2.2.8.
Find \(u\) and \(v\) so that \(82 u + 17 v = gcd(82,17)\text{.}\) First, we perform the Euclidean algorithm to get the list of quotients that we need to perform the extension.
The array version of the algorithm looks like
Exercises Exercises
1.
Write a python function that computes \(\gcd(a,b)\) for \(a, b \in \Z\text{.}\)
2.
An efficient algorithm for computing a solution to \(au + bv = \gcd(a,b)\) is given below:
- Set \(u = 1, g = a, x = 0\) and \(y = b\text{.}\)
- If \(y = 0\text{,}\) set \(v = (g - au)/b\) and return values \((g, u, v)\text{.}\)
- Divide \(g\) by \(y\) to get \(g = qy + t\) with \(0 \leq t \lt y\text{,}\) store \(q\) and \(t\text{.}\)
- Set \(s = u - qx\text{.}\)
- Set \(u = x\) and \(g = y\text{.}\)
- Set \(x = s\) and \(y = t\text{.}\)
- Go to Step (b).
Your tasks are:
- Convince me that \(g = \gcd(a,b)\) and \(au + bv = g\text{.}\)
- Implement this algorithm in a python function.