费马分解
在RSA密码中,当我们需要解密但没有 p 和 q 时是很难解出 ɸ(n) = ( p - 1 ) * ( q - 1 ) 的,这时候就需要我们将 n 分解为 p 和 q ,但是大质数分解是十分困难的,这时候可以使用费马分解法分解出 p 和 q 。
但是费马分解法使用时有一定的要求
在 p 和 q 相差不是很大的情况下可以使用费马分解。
费马分解的核心就是存在两个相差不大的素数的乘积,可以通过构造完全平方差的方式求出这两个素数。
n = p * q ( p 和 q 为两个质数 ,n 为 p 和 q 的乘积 )
已知 n ,并且 p 和 q 的大小相差不大。
构造完全平方差公式
n = p q = ( s - t ) ( s + t ) = s 2 - t 2
使得 n 为两数的平方差 ,然后变换得
t 2 = s 2 - n
令 s = int ( sqrt ( n ) ) + 1 ,
当 s 满足上式时则表明找到了符合条件的 s 和 t ,
否则 s + 1 继续判断是否符合上式要求,直至找到满足要求的 s 和 t 。
找到满足上式要求的 s 和 t 后,只需 带入第一个式子中求出对应的 p 和 q ,即 p , q = s ± t
Python代码实现
import math
def fermat(n): # 费马分解
s = int(math.isqrt(n))+1 # 构造 s
t = pow(s,2) - n # 构造 t
while int(math.isqrt(t)) != math.isqrt(t): # 判断 t 和 s 是否为完全平方差,不是则继续判断
s+=1
t=pow(s,2) - n
t = int(math.isqrt(t))
p = s - t
q = s + t
return p,q
res = fermat(n)
print(res)