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

(Updated: )
3 min read

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

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

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

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

ap11(modp)a^{p-1} \equiv 1 \pmod{p}

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

ak(p1)1(modp)ak(p1)10(modp)a^{k(p-1)} \equiv 1 \pmod{p} \Rightarrow a^{k(p-1)} - 1 \equiv 0 \pmod{p}

所以:

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

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

Pollard's p - 1 實作邏輯

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

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

  • gcd(211,n)\gcd(2^1 - 1, n)
  • gcd(21×21,n)\gcd(2^{1 \times 2} - 1, n)
  • gcd(21×2×31,n)\gcd(2^{1 \times 2 \times 3} - 1, n)
  • gcd(21×2×3×41,n)\gcd(2^{1 \times 2 \times 3 \times 4} - 1, n)
  • ⋯⋯

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

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

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

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

使用條件

p1p-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

載入評論區...