8.1 模運算與群環體#
模運算:密碼學的呼吸#
模運算(modular arithmetic)就是「只看餘數」的算術:a ≡ b (mod n) 表示 a 與 b 除以 n 的餘數相同。時鐘是最直覺的例子:13 點即 1 點(mod 12)。密碼學熱愛模運算的理由很實際——運算結果被壓縮在固定範圍內(不會無限膨脹),且「去路徑、留餘數」的過程本身就是單向性的來源。
基本性質(加法與乘法都「取模後仍成立」):
(a + b) mod n = ((a mod n) + (b mod n)) mod n
(a · b) mod n = ((a mod n) · (b mod n)) mod n
最大公因數與擴展歐幾里得#
gcd(a, b):輾轉相除gcd(a, b) = gcd(b, a mod b),複雜度 O(log b)。- 互質:gcd(a, n) = 1。
- 擴展歐幾里得:找整數 x, y 使
a·x + b·y = gcd(a, b)。當 gcd(e, φ)=1 時可得e·x ≡ 1 (mod φ),即模反元素——這正是 RSA 求 d 的方法,也是 Pythonpow(e, -1, φ)的內涵。
費馬小定理與歐拉定理(RSA 的正確性證明)#
- 費馬小定理:p 質數、gcd(a,p)=1 ⇒
a^(p−1) ≡ 1 (mod p)。 - 歐拉定理:n 任意、gcd(a,n)=1 ⇒
a^φ(n) ≡ 1 (mod n),其中 φ(n)(歐拉函數)是 1..n 中與 n 互質的個數;對 n = p·q(質數積)有φ(n) = (p−1)(q−1)。
RSA 回顧(7.2 節):e·d ≡ 1 (mod φ(n)),故 M^(ed) = M^(1+kφ(n)) ≡ M^(1) ≡ M (mod n)——兩行就證明了加解密可逆。
群、環、體:三分鐘版#
| 結構 | 具備的運算 | 例子 |
|---|---|---|
| 群 (G, ·) | 封閉、結合、有單位元、每元素可逆 | (Z_n, +)、橢圓曲線點群 |
| 交換群 | 群 + 交換律 | 以上皆 |
| 環 (R, +, ·) | 加法成交換群;乘法封閉、結合、有單位元(除法不必有) | Z_n |
| 體 (F) | 環 + 每個非零元素有乘法反元素 | Z_p(p 質數)、GF(2^8)(AES 的 S-box) |
密碼學常用的三個舞台:Z_p(p 質數的非零元素乘法群,階為 p−1,DH 的老家)、*GF(2^8)(AES MixColumns 的體)、橢圓曲線點群**(ECC 的家)。
群的階(order):群中元素個數。元素的階:使 g^m = 1 的最小 m,必整除群階(拉格朗日定理)——RSA 金鑰產生時要求 e 與 φ(n) 互質、橢圓曲線要求基點階為大質數,都是這條定理的應用。
Python 實作#
def egcd(a, b): # 擴展歐幾里得
if b == 0: return (a, 1, 0)
g, x, y = egcd(b, a % b)
return (g, y, x - (a // b) * y)
def modinv(a, n): # 模反元素
g, x, _ = egcd(a % n, n)
assert g == 1, "不互質,無反元素"
return x % n
print(pow(7, 128, 13), (7 % 13) ** 2 % 13) # 7^128 = 7^(6*21+2) → 驗證費馬
print(modinv(65537, (101 * 103 - 101 - 103 + 1))) # RSA 的 d
print(pow(3, 322 - 1, 323), "歐拉定理:3^φ(323) mod 323 = 1")
# Z_p* 的元素階必整除 p−1(拉格朗日)
p = 23
for g in range(2, p):
o, v = 1, g
while v != 1:
v = v * g % p; o += 1
print(f"g={g:2} 階={o:2}", "← 生成元" if o == p - 1 else "")
安全性分析#
- 模運算的單向性不是萬能:加法、乘法、開方皆「可逆容易」;真正難的是離散對數(8.2)與分解(8.3)——單向難題是挑出來的,不是模運算自動給的。
- 弱參數的教訓:p−1 若為「光滑數」(只有小質因數),Pohlig–Hellman 演算法把離散對數拆成小問題逐個擊破——DH 參數的 p 必須使 p−1 含大質因數(或直接用安全素數 p = 2q+1)。
- 非質數模數的陷阱:Z_n(n 合數)不是體,除法/開方可能「沒有答案」或多解;RSA 之所以敢在 Z_n 上工作,全靠私鑰持有 φ(n) 這個陷門。
練習#
- 用
egcd求 17 在 mod 3120 下的反元素(即迷你 RSA 的 d:φ(3120)=φ(65×48) 自行拆解 p=65 需先分解)。 - 對 p=11 的每個 g∈[2,10] 列出階,找出所有生成元;觀察生成元個數是 φ(p−1)。
- 證明:若 p 質數且
a^(p−1) ≢ 1 (mod p),則 p 不是質數——這正是 Fermat 素性測試;再用一個合數(如 341 = 11×31)找出「欺騙 Fermat 測試」的 a,體會為何需要 Miller–Rabin(8.3 節)。