Algorithm Search⌘K

Proofs: Sliding-window exponentiation

These are the human proofs of Sliding-window exponentiation, at full length.

Sliding-window exponentiation returns x^e and uses at most t - 2 + ceil(t/k) + 2^(k-1) products full

This proof shows: correctness, termination.

Let xx be an element of a monoid with identity 1, let k≥1k \ge 1, and let e≥1e \ge 1 have binary digits et−1…e0e_{t-1} \ldots e_0 with et−1=1e_{t-1} = 1. For −1≤i≤t−1-1 \le i \le t - 1 write Pi=⌊e/2i+1⌋P_i = \lfloor e / 2^{i+1} \rfloor, the number formed by the digits above position ii; so Pt−1=0P_{t-1} = 0 and P−1=eP_{-1} = e.

Theorem. SLIDING-WINDOW-POWER(x,e,k)(x, e, k) terminates and returns xex^e. It uses at most t−1t - 1 squarings in the main loop and at most ⌈t/k⌉−1\lceil t/k \rceil - 1 products by table entries, besides the at most 2k−12^{k-1} products of line L1.

1. The table. Line L1 sets T[1]=xT[1] = x and T[u]=T[u−2]⋅x2T[u] = T[u-2] \cdot x^2 for odd uu from 3 to 2k−12^k - 1. By induction on uu, T[u]=xu−2x2=xuT[u] = x^{u-2} x^2 = x^u, by associativity. It uses one squaring and 2k−1−12^{k-1} - 1 products.

2. The window is well defined. At line L5, ei=1e_i = 1, so the set of indices jj with max⁡(i−k+1,0)≤j≤i\max(i - k + 1, 0) \le j \le i and ej=1e_j = 1 contains ii and is not empty; let jj be its least element. Then 1≤i−j+1≤k1 \le i - j + 1 \le k, the number u=(ei…ej)2u = (e_i \ldots e_j)_2 satisfies 2i−j≤u<2i−j+1≤2k2^{i-j} \le u < 2^{i-j+1} \le 2^k, and uu is odd since its last digit is ej=1e_j = 1. So T[u]T[u] exists.

3. The invariant. At each test of line L3, y=xPiy = x^{P_i}.

Proof. At the first test, i=t−1i = t - 1 and y=1=x0=xPt−1y = 1 = x^0 = x^{P_{t-1}}. Suppose y=xPiy = x^{P_i} at a test with i≥0i \ge 0.

  • If ei=0e_i = 0, then Pi−1=2Pi+ei=2PiP_{i-1} = 2P_i + e_i = 2P_i, and line L4 sets yy to xPixPi=xPi−1x^{P_i} x^{P_i} = x^{P_{i-1}} and ii to i−1i - 1.
  • If ei=1e_i = 1, let jj and uu be as in part 2 and ℓ=i−j+1\ell = i - j + 1. Then Pj−1=⌊e/2j⌋=2ℓ⌊e/2i+1⌋+(ei…ej)2=2ℓPi+uP_{j-1} = \lfloor e/2^j \rfloor = 2^\ell \lfloor e/2^{i+1} \rfloor + (e_i \ldots e_j)_2 = 2^\ell P_i + u. After ℓ\ell squarings, y=x2ℓPiy = x^{2^\ell P_i}, and after the product with T[u]=xuT[u] = x^u, y=xPj−1y = x^{P_{j-1}}, with ii set to j−1j - 1.

In both cases the invariant holds at the next test. □\square

4. Termination and result. Each pass through the loop decreases ii by at least 1, and the loop runs while i≥0i \ge 0, so it stops after at most tt passes, with i=−1i = -1, since a window never goes below index 0. By part 3, y=xP−1=xey = x^{P_{-1}} = x^e, which line L6 returns. Skipping squarings of y=1y = 1 and replacing 1⋅T[u]1 \cdot T[u] by T[u]T[u] does not change any value, since 1⋅1=11 \cdot 1 = 1 and 1⋅z=z1 \cdot z = z. □\square

5. The counts. Let the passes that take line L5 be windows 1,…,W1, \ldots, W, from the top. The first window starts at i=t−1i = t - 1, since et−1=1e_{t-1} = 1; while y=1y = 1 nothing is counted, so the first window costs nothing. Every later digit is squared exactly once, at line L4 or within a window, so the main loop makes t−ℓ1≤t−1t - \ell_1 \le t - 1 squarings, where ℓ1≥1\ell_1 \ge 1 is the length of the first window, and W−1W - 1 products by table entries.

To bound WW, consider a window from ii to jj. If j>j0=max⁡(i−k+1,0)j > j_0 = \max(i - k + 1, 0), the digits ej−1,…,ej0e_{j-1}, \ldots, e_{j_0} are all 0 by the choice of jj as the least index with a 1, so they are read at line L4 before the next window starts. Hence each window starts at least kk positions below the previous one: if a window starts at ii, the next starts at an index at most i−ki - k. Since the first starts at t−1t - 1 and every start is at least 0, the starts t−1,≤t−1−k,≤t−1−2k,…t - 1, \le t - 1 - k, \le t - 1 - 2k, \ldots give (W−1)k≤t−1(W - 1)k \le t - 1, so W≤⌊(t−1)/k⌋+1≤⌈t/k⌉W \le \lfloor (t-1)/k \rfloor + 1 \le \lceil t/k \rceil. Adding part 1, the total is at most (t−1)+(⌈t/k⌉−1)+2k−1(t - 1) + (\lceil t/k \rceil - 1) + 2^{k-1}. ■\blacksquare

Back to Sliding-window exponentiation