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为奇数。
,i 遍历(1,s),gcd(base,n)=1,base使用素数序列效果会更好
若满足以下条件:
,若无此条件约束会求得平凡因子1,n
,(m-1)*(m+1)=k*n,k为整数。
则GCD(m-1,n),GCD(m+1,n)为n的非平凡因子,即为p,q。
此方法是概率性算法,可能出现无法求解的情况,但平均有效率大于1/2.
方法二:
求解然后解二次方程。
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)