Modular exponentiation (repeated squaring)
Compute aᵇ mod n with about log b multiplications: square the base again and again, and multiply it in for every 1 bit of b.
Computing aᵇ with b − 1 multiplications is hopeless for large b (as in RSA). But write b in base 2:
- Time:
O(log b) - Space:
O(1) - CLRS, section 31.6
- Johnsonbaugh, chapter 5
7⁵⁶⁰ mod 561 = 1; 560 has ten bits, so 13 multiplications (10 squarings and 3 products) do instead of 559.
def mod_pow(a, b, n):# a to the power b, mod n, reading the bits of b from the right.result = 1 % nbase = a % nrows = []while b > 0:bit = b % 2if bit == 1:result = result * base % nrows.append((bit, base, result))base = base * base % nb = b // 2return result
Start
The table is still empty.
Local variables
Orange = changed in this step
Call stack
- mod_pow()line 1
Explanation
The idea
Computing aᵇ with b − 1 multiplications is hopeless for large b (as in RSA). But write b in base 2:
b = 560 = 1000110000₂ ⇒ a⁵⁶⁰ = a⁵¹² · a³² · a¹⁶
The powers a¹, a², a⁴, a⁸, … come from repeated squaring, and only those whose bit is 1 are multiplied into the
answer. Taking mod n after each multiplication keeps the numbers small.
Cost
At most 2 log b multiplications. It underlies RSA, the Miller–Rabin test and Diffie–Hellman.
What to watch in the trace
- Each table row is one bit of
b(from the right): the bit, that round's base and the result so far.