Algorithm for calculating powers of extremely large numbers
Problem
As we all know the expression: \(x^n \mod m; (\forall x,n,m \in \mathbb N)\) is the building block of most of the cryptographic techniques. A simple implementation of it would be:
// calculate x^n
function power(x, n, m) {
let result = 1;
for (let i = 0; i < n; i++) {
result = (result * n) % m;
}
return result;
}
However, the above function wouldn't work with the extremely large number (> 1 bil) since it requires huge execution time.
The algorithm
Knowing that:
$$a^p \times a^q = a^{p+q}$$
and
$$a^{p+q} \mod m = (a^p\mod m)(a^q \mod m)$$
We convert the power value into a sum of series of the powers of two:
$$n = \sum(b_i \times 2^i); \text{for } b_i \text{ either 0 or 1}$$
for example: \(n = 11 = 1\times2^0+1\times2^1+0\times2^2+1\times2^3\). It could be seen that \(n=\overline{b_0b_1\dots b_n}\) is the binary representation of \(n\). For an arbitrary value of \(n\), we break the \(a^n\) into smaller pieces like below:
$$\begin{align*} a^n \mod m &= a^{\sum(b_i \times 2^i)} \mod m\\ &= a^{b_0\times2^0 + b_1\times2^1+...} \mod m \\ &= (a^{b_0\times2^0} \mod m)\times (a^{b_1 \times 2^1} \mod m) \ times \dots \end{align*}$$
Knowing that\((a^{2^k})^2 \mod m= a^{2^{k+1}} \mod m\); it means that once we have calculated \(a^{2^k}\) we can easily calculate \(a^{2^{k+1}} \mod m\) by just squaring it. Now, using a for loop, and a temporary variable to store \(a^{2^k}\) at the step \(k^{th}\). At the next of the for loop, square it up to calculate \(a^{2^{k+1}}\). The complexity of the algorithm is \( O(\log n)\).
// calculate a^n mod m for big n
function quick_pow(a, n, m) {
if (n === 0) return 1;
let temp = a;
let result = 1;
while (n>0) {
const b_i = n & 1; // calculate b_i by extracting the right most bit
if (b_i === 1) {
result = (result * temp) % m; // calculate the result
}
n = n >> 1; // shift right n by 1 bit
temp = (temp * temp) % m; // square the temporary value
}
return result;
}