[rsa]已知e,d,n,分解n

ed-1=k*phi(n)

phi(n)=(p-1)*(q-1)=p*q-(p+q)+1

由于-(p+q)+1相对p*q的很小

k=(ed-1)//n+1

phi(n)=(ed-1)//k

from Crypto.Util.number import *

for i in range(10):
    p=getPrime(256)
    q=getPrime(256)
    n=p*q
    phi=(p-1)*(q-1)

    e=65537

    assert GCD(e,phi)==1
    d=inverse(e,phi)
    k=(e*d-1)//n+1
    k_true=(e*d-1)//phi

    print(k,k_true,(p+q)/n)

# 13171 13171 2.6403980529702084e-77
# 11373 11373 3.094573988641593e-77
# 62860 62860 2.5870984806949504e-77
# 34852 34852 2.157028756161272e-77
# 57358 57358 2.2575407162421756e-77
# 45752 45752 2.5694752230866774e-77
# 47664 47664 2.5649308341870815e-77
# 26374 26374 2.7843088654212493e-77
# 41277 41277 2.339750650247507e-77
# 54404 54404 2.7920854564905182e-77

方法一:

e*d-1=2^s*t,t为奇数。

m=base^{2^{i}*t},i 遍历(1,s),gcd(base,n)=1,base使用素数序列效果会更好

若满足以下条件:

m \not\equiv \pm1 \pmod{n},若无此条件约束会求得平凡因子1,n

m^{2} \equiv 1 \pmod{n} ,(m-1)*(m+1)=k*n,k为整数。

则GCD(m-1,n),GCD(m+1,n)为n的非平凡因子,即为p,q。

此方法是概率性算法,可能出现无法求解的情况,但平均有效率大于1/2.

方法二:

(x-p)*(x-q)=x^{2}-(p+q)*x+n=x^{2}-(n-\phi(n)+1)*x+n

求解\phi(n)然后解二次方程。

from gmpy2 import *
from hashlib import md5
#d泄露 分解n
d = 5
e = 88447120342035329077203801890175181441227843548712394915405983098804986074228491993716303861346713336901472423214577098721961679062412555594462454080858396158886857405021364693424253936899868042331165487633709535319154171592544118785565876198853503758641178366299573880796663815089204345025378660387680199869
n = 0x009d70ebf2737cb43a7e0ef17b6ce467ab9a116efedbecf1ead94c83e5a082811009100708d690c43c3297b787426b926568a109894f1c48257fc826321177058418e595d16aed5b358d61069150cea832cc7f2df884548f92801606dd3357c39a7ddc868ca8fa7d64d6b64a7395a3247c069112698a365a77761db6b97a2a03a5
 
t = e * d - 1
s = 0
 
while(t &1 == 0):
    t = t // 2
    s += 1
print(f's,t--{s},{t}')
# 此时 e * d - 1 = ( 2 ** s ) * t

for i in range(1,s):
    c1 = powmod(2,powmod(2,i,n) * t , n )
    c2 = powmod(2,powmod(2,(i-1),n) * t, n )
    
    print(f'round:{i}',c1,'---',c2)
    if(n-1>c2 >1 and c1 == 1 ):
        kp = c2 - 1
        p = gcd(kp,n)
        print('kp=',kp,kp>n)
        break
 
q = n // p
print(p<q) # True
assert p*q==n
print(f'factor--{p}--{q}')
# flag = md5(str(p).encode()).hexdigest()
# print(f"NSSCTF{{{flag}}}")

import gmpy2



k=(e*d-1)//n+1
print('k',k)
phi=(e*d-1)//k

a=1
b=-(n-phi+1)
c=n
p=(-b+gmpy2.iroot(b**2-4*a*c,2)[0])//2
print(p,n%p==0)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值