Then Notes 隨筆

RSA 加密演算法

cover
目錄

RSA 加密演算法是一種非對稱加密(公開金鑰加密)演算法。RSA 的演算法是基於歐拉函數(Euler’s totient function)與歐拉定理(Euler’s theorem)而來。

歐拉函數

歐拉函數 ϕ(n)\phi(n)n\leq n 的正整數中與 nn 互質的個數

我們把 nn 做質因數分解可以得到:

n=p1k1p2k2prkrn = p_1^{k_1} \cdot p_2^{k_2} \dots p_r^{k_r}

就可以計算歐拉函數 ϕ(n)\phi(n)

ϕ(n)=npn(11p)\phi(n) = n \prod_{p|n} (1 - \frac{1}{p})

範例

  • ϕ(30)\phi(30)
    • 30=23530 = 2 \cdot 3 \cdot 5
    • (1,7,11,13,17,19,23,29)(1, 7, 11, 13, 17, 19, 23, 29)
    • ϕ(30)=30122345=8\phi(30) = 30 \cdot \frac{1}{2} \cdot \frac{2}{3} \cdot \frac{4}{5} = 8
  • ϕ(36)\phi(36)
    • 36=223236 = 2^2 \cdot 3^2
    • (1,5,7,11,13,15,17,19,23,25,29,31)(1, 5, 7, 11, 13, 15, 17, 19, 23, 25, 29, 31)
    • ϕ(36)=361223=12\phi(36) = 36 \cdot \frac{1}{2} \cdot \frac{2}{3} = 12

質數特性

對於兩個質數 ppqq,且 pqp \ne q(非常重要!)、合數 n=p×qn = p \times q

  • ϕ(p)=p1, ϕ(q)=q1\phi(p) = p - 1, \space \phi(q) = q - 1
  • ϕ(n)=ϕ(pq)=ϕ(p)ϕ(q)=(p1)(q1)\phi(n) = \phi(pq) = \phi(p) \cdot \phi(q) = (p - 1) \cdot (q - 1)
  • 例:ϕ(10)=ϕ(2)ϕ(5)=(21)(51)=4\phi(10) = \phi(2) \cdot \phi(5) = (2 - 1) \cdot (5 - 1) = 4

歐拉定理

對任意互質的兩數 aann 有以下性質

aϕ(n)1(modn)a^{\phi(n)} \equiv 1 \pmod n

RSA 演算法

  1. 選擇兩個大質數 ppqqpqp \ne q
  2. n=p×qn = p \times q
  3. ϕ(n)=(p1)(q1)\phi(n) = (p - 1) \cdot (q - 1)
  4. 選擇一個 ee 使其與 ϕ(n)\phi(n) 互質且小於 ϕ(n)\phi(n),即 gcd(ϕ(n),e)=1,1<e<ϕ(n)gcd(\phi(n), e) = 1, 1 < e < \phi(n)
  5. 計算 de1(modϕ(n)), d<ϕ(n)d \equiv e^{-1} \pmod{\phi(n)}, \space d < \phi(n)
    • 公鑰:{e, n}\{e, \space n\}
    • 私鑰:{d, n}\{d, \space n\}
  • 加密:
    • 明文 M<nM < n
    • 密文 C=Me(modn)C = M^e \pmod n
  • 解密
    • 密文 CC
    • 明文 M=Cd(modn)M = C^d \pmod n

範例

範例為了方便計算,所以用很小的質數做示範,實際應用場景中會使用超大質數。

  1. 選擇兩個質數 p=17, q=11p = 17, \space q = 11
  2. n=pq=17×11=187n = p \cdot q = 17 \times 11 = 187
  3. ϕ(n)=(p1)(q1)=16×10=160\phi(n) = (p - 1)(q - 1) = 16 \times 10 = 160
  4. 選擇 ee 使其與 ϕ(n)=160\phi(n) = 160 互質且小於 160160,我們選擇 e=7e = 7
  5. 計算 dd 使得 de1(modϕ(n))de \equiv 1 \pmod{\phi(n)}d<160d < 160。因為 23×7=161, 161mod160=123 \times 7 = 161, \space 161 \bmod 160 = 1,故 d=23d = 23
    • 公鑰:{7, 187}\{7, \space 187\}
    • 私鑰:{23, 187}\{23, \space 187\}

若明文為 8888,則

  • 加密
    • 明文:88<18788 < 187
    • 加密:887mod187=1188^7 \bmod{187} = 11
  • 解密
    • 密文:1111
    • 明文:1123mod187=8811^{23} \bmod 187 = 88

快速模冪演算法

從剛剛的例子我們會發現要計算 88788^7112311^{23},這是非常大的數字呢!如果要算出這個數字相當耗費資源。不過後面既然會需要 mod187\bmod 187,其實就不用真的乘開了,而這個問題在數學上稱之為模冪(modular exponentiation)運算。

x, y, nx, \space y, \space n 皆為整數且 x, y0, n1x, \space y \ge 0, \space n \ge 1,求 xymodnx^y \bmod n,可以透過下列演算法計算:

int mod_exp(int x, int y, int n)
{
    x %= n;
    if (x == 0)
        return 0;

    int result = 1;
    while (y > 0) {
        // y % 2 == 1
        if (y & 1)
            result = (result * x) % n;

        y /= 2;
        x = (x * x) % n;
    }

    return result;
}

我們會發現,887mod18788^7 \bmod 187 只需要 3 次迴圈就可以算完:

xyresult
輸入887187
177388
2132144
333011

本文由作者 Chiahong 發表,歡迎分享,如需引用時請註明來源,感謝您!