密碼學筆記 - Pollard's p - 1 Algorithm

(Updated: )
3 min read

假設我們有一個合數 nn,其中存在一個質因數 pp。
Pollard's p - 1 algorithm 是一種在 p−1p - 1 的最大質因數很小時,能有效分解 nn 的演算法。

這個方法常被應用在 CTF 題目中,用來分解 RSA 公鑰中的 nn,進而破解 RSA。

費馬小定理與分解的核心原理

根據 費馬小定理:
若 aa 不是 pp 的倍數,則:

ap−1≡1(modp)a^{p-1} \equiv 1 \pmod{p}

進一步來說,對某個 kk 有:

ak(p−1)≡1(modp)⇒ak(p−1)−1≡0(modp)a^{k(p-1)} \equiv 1 \pmod{p} \Rightarrow a^{k(p-1)} - 1 \equiv 0 \pmod{p}

所以:

gcd⁡(ak(p−1)−1,n)\gcd(a^{k(p-1)} - 1, n)

這個值一定會是 pp 的倍數——如果剛好等於 pp,那我們就成功找到一個非平凡因數了!

Pollard's p - 1 實作邏輯

演算法的關鍵就是去構造一個剛好是 p−1p - 1 倍數的指數。實作時,我們通常固定 a=2a = 2(只要 p≠2p \ne 2,上述推論都成立)。

接著,我們會嘗試計算如下:

  • gcd⁡(21−1,n)\gcd(2^1 - 1, n)
  • gcd⁡(21×2−1,n)\gcd(2^{1 \times 2} - 1, n)
  • gcd⁡(21×2×3−1,n)\gcd(2^{1 \times 2 \times 3} - 1, n)
  • gcd⁡(21×2×3×4−1,n)\gcd(2^{1 \times 2 \times 3 \times 4} - 1, n)
  • ⋯⋯

這個指數其實就是階乘 k!k!,也就是我們試圖讓 k!k! 包含 p−1p - 1 的所有質因數。

當某個 kk 滿足 p−1∣k!p - 1 \mid k! 時,就有很大機會使得:

gcd⁡(2k!−1,n)=p\gcd(2^{k!} - 1, n) = p

這樣我們就能成功分解 nn 啦。

使用條件

當 p−1p-1 最大的質因數很小,可以有效的分解合數 nn

Python 程式碼

import math

def pollard(n):
    a, b = 2, 2
    while True:
        a, b = pow(a, b, n), b + 1
        d = math.gcd(a - 1, n)
        if 1 < d < n:
            return d

載入評論區...