Algorithm Search⌘K

Proofs: Batch modular inverse

These are the human proofs of Batch modular inverse, at full length.

Batch modular inverse returns every inverse, or a divisor of m when one does not exist full

This proof shows: correctness.

Claim. Let m≥1m \ge 1 and let x1,…,xkx_1, \ldots, x_k be residues modulo mm, with k≥0k \ge 0. If every xix_i is a unit modulo mm, the algorithm returns y1,…,yky_1, \ldots, y_k with xiyi≡1(modm)x_i y_i \equiv 1 \pmod m for each ii, and it uses 3(k−1)3(k - 1) modular multiplications and one inversion for k≥1k \ge 1. If some xix_i is not a unit, line L6 stops with g=gcd⁡(zk,m)>1g = \gcd(z_k, m) > 1, a divisor of mm.

The empty case. For k=0k = 0, line L1 returns the empty list, which is correct.

Forward pass. Lines L2 to L4 set z1=x1z_1 = x_1 and zi=zi−1xi mod mz_i = z_{i-1} x_i \bmod m. By induction on ii, zi≡x1x2⋯xi(modm)z_i \equiv x_1 x_2 \cdots x_i \pmod m for 1≤i≤k1 \le i \le k. This uses k−1k - 1 multiplications.

When the product is invertible. A product of units is a unit, and conversely, if zkz_k is a unit with inverse ww, then for each ii

xi⋅(w∏j≠ixj)≡zkw≡1(modm),x_i \cdot \Big(w \prod_{j \ne i} x_j\Big) \equiv z_k w \equiv 1 \pmod m,

so xix_i is a unit. Hence gcd⁡(zk,m)=1\gcd(z_k, m) = 1 if and only if every xix_i is a unit modulo mm. Line L5 computes g=gcd⁡(zk,m)g = \gcd(z_k, m) and, when g=1g = 1, q≡zk−1(modm)q \equiv z_k^{-1} \pmod m by the extended Euclidean algorithm. If some xix_i is not a unit, then g>1g > 1 and g∣mg \mid m, and line L6 stops as claimed. From now on, every xix_i is a unit.

Backward pass. We show that at the start of the iteration of line L7 with index ii, for i=k,k−1,…,2i = k, k - 1, \ldots, 2, the invariant q≡zi−1(modm)q \equiv z_i^{-1} \pmod m holds.

  • Start. For i=ki = k, it holds by line L5.
  • Step. Assume q≡zi−1q \equiv z_i^{-1} at the start of the iteration for ii. Line L8 sets
yi=qzi−1≡x1⋯xi−1x1⋯xi=xi−1(modm),y_i = q z_{i-1} \equiv \frac{x_1 \cdots x_{i-1}}{x_1 \cdots x_i} = x_i^{-1} \pmod m,

which is the correct output for position ii. Line L8 reads zi−1z_{i-1}, which has not been overwritten yet, because the loop writes only positions i,i+1,…,ki, i+1, \ldots, k before it reaches index i−1i - 1. Line L9 sets q←qxi≡zi−1xi≡zi−1−1q \leftarrow q x_i \equiv z_i^{-1} x_i \equiv z_{i-1}^{-1}, which is the invariant for i−1i - 1.

After the last iteration, i=2i = 2, the invariant gives q≡z1−1=x1−1q \equiv z_1^{-1} = x_1^{-1}, and line L10 sets y1=qy_1 = q. If k=1k = 1, the loop does not run and q≡z1−1=x1−1q \equiv z_1^{-1} = x_1^{-1} directly by line L5. So every yiy_i is the inverse of xix_i. The backward pass makes two multiplications per iteration, 2(k−1)2(k - 1) in total.

Count. The two passes use (k−1)+2(k−1)=3(k−1)(k - 1) + 2(k - 1) = 3(k - 1) modular multiplications, and line L5 is the only inversion. ■\blacksquare

Back to Batch modular inverse