Skip to content

RSA 的分析

使用连分数展开进行攻击

连分数

对于一个数 α 的展开,形如:

α=c0+1c1+1c2+1c3+

可以简记为:

[c0;c1,c2,c3,]

如何计算:

c0=αε0=αc0c1=1ε0ε1=1ε0c1c2=1ε1ε2=1ε1c2

n-th convergent: (n次渐进分数)

对于 α=[c0;c1,c2,],其 n-th convergent 定义为:

anbn=[c0;c1,c2,,cn]

计算如下:

a0b0=c01a1b1=c0c1+1c1anbn=cnan1+an2cnbn1+bn2(n2)

e.g.

α = 45/89

α=4589,c0=α=4589=0,ε0=αc0=4589,c1=1ε0=8945=1,ε1=1ε0c1=89451=4445,c2=1ε1=4544=1,ε2=1ε1c2=45441=144,c3=1ε2=441=44,ε3=1ε2c3=44144=0.

因此连分数表示为:

4589=[0;1,1,44]=0+11+11+144.

计算收敛分数:

a0b0=c01=0,a1b1=c0c1+1c1=11=1,a2b2=c2a1+a0c2b1+b0=11+011+1=12,a3b3=c3a2+a1c3b2+b1=441+1442+1=4589.

Lemma

如果 |αab|<12b2,那么 abα 的某个收敛分数。

Wiener’s attack on RSA

如果满足:

  • p<q<2p
  • e<(p1)(q1)
  • d<13n14

则存在:

  • ed=1+kϕ(N)
  • ϕ(N)=N(p+q)+1
  • e<ϕ(N),k<d
  • 考虑:
eNkd=edkNdN=1+kϕ(N)kNdN=1k(p+q1)dN<p+q1N,k<d<3NN=3N,q<2p<13d2,d<13N14<12d2QED

Code

Sage
python
from sage.all import *

n = 9449868410449
e = 6792605526025

test_message = 123456
enc_test_message = pow(test_message, e, n)

def weiner_atk(e,n):
    continued_fraction_expansion = continued_fraction(e/n)
    convergents = continued_fraction_expansion.convergents()
    print(convergents)

    for iter in convergents:
        k,d = iter.as_integer_ratio()
        if k == 0:
            continue
        if (e*d - 1) % k != 0:
            continue
        phi_n = (e*d - 1) // k
        s = n - phi_n + 1
        discriminant = s*s - 4*n
        if discriminant >= 0:
            t = isqrt(discriminant)
            if t*t == discriminant:
                dec_test_message = pow(enc_test_message, d, n)
                # print(dec_test_message)
                if dec_test_message == test_message:
                    return d
    return None

d = weiner_atk(e, n)
print(f"Found d: {d}")
bash
[0, 1, 2/3, 3/4, 5/7, 18/25, 23/32, 409/569, 1659/2308, 2068/2877, 3727/5185, 76608/106577, 156943/218339, 1175209/1634950, 8383406/11662989, 34708833/48286906, 77801072/108236801]
123456
Found d: 569

Coppersmith

直觉

假设: c=memodN,m=m0+x0, 如果 x0 表示信息的低位,已知信息的高位 m0,有方程如下:

f(x)=c(m0+x)emodN

故而,当 x0 很小时,我们可以求解这个多项式来得到明文,特别是在 e 也很小时。

同时,对于持有私钥,既拥有 N 的分解, p, q 时,求解 f(x) 时更加容易的。但是对于攻击者来说这是不可能的。

但是我们可以通过一些转换,使得:

f(x)=0modNg(x)=0

既然 f(x) 在模 N 意义下有一个小根 x0,那么我们可以构造一个整数多项式 g(x),使得 g(x) 在整数意义下也有一个小根 x0,并且在 Z 上求解 g(x) 是非常容易的。(牛顿法求根)

e.g.

  • N=17×19=323,并令f(x)=x2+33x+215.
  • 寻找满足 f(x)0(modN) 的解。
  • x0=3 是一个解,但在整数域 Z 上有 f(3)0
  • 定义g(x)=9f(x)N(x+6)=9x226x3.
  • f(x0)0(modN)g(x0)0(modN)g(x0)=0 over Z
  • g(x) 的系数较小且满足 g(3)=0,其根可在实数域 R 上用牛顿法求出。

通过 格 找出多项式 gx

Coppersmith's method 的核心思想是通过构造一组多项式,并利用 LLL 算法 找出一个新的多项式 g(x),使得 g(x) 在整数域 Z 上有一个小根 x0,从而可以通过牛顿法求出该根。

构造方法略

e.g.

M=10001 并考虑多项式 (这里的M 等同于模数 N)

F(x)=x3+10x2+5000x222.

可以验证 F(x) 是不可约的,并且 F(x) 在模 M 下有一个小解 x0=4。注意 |x0|<M1/6,因此可以预期能够找到 x0。假设 X=10 是给定的 x0 大小的界限。考虑基矩阵

B=(M0000MX0000MX202225000X10X2X3).

对此矩阵运行 LLL 算法得到一个约化基,其第一行为

(444,10,2000,2000).

该向量对应的多项式为

G(x)=444+x20x22x3.

G(x) 上运行牛顿求根法得到解 x0=4