已知条件:
p1 = r**5 + r**4 - r**3 + r**2 - r + 2024
q1 = r**5 - r**4 + r**3 - r**2 + r + 2024
即p和q是p1和q1的下一个素数
q*p=n
可以尝试找到未知的真实r,而真实的r必然在n的十次方根附近,即:
r = int(mpmath.nint(mpmath.root(mpmath.mpf(n), 10)))
获取到r的近似值后,我往上下查找,通过遍历r近似值的附近值,计算对应p1,q1后找到最近的p,q,并验证p*q是否等于n,获得真实p,q后即可解开此题。
from sympy import nextprime
import mpmath
# 设置所需的精度,例如50位小数
mpmath.mp.dps = 50
#已知p*q=n
n = 1058756604181685917958185571746711428601045466594619627088399455470892502310139608978164573773765910533535849969889860275644658086339362201840191861497991951344100284004205747279828567835277683
#根据公式,n开10次方是r的近似值
r = int(mpmath.nint(mpmath.root(mpmath.mpf(n), 10)))
'''找到未知的真实r'''
def r_test(r,n):
for i in range(r,r+10):
p1 = i**5 + i**4 - i**3 + i**2 - i + 2024
q1 = i**5 - i**4 + i**3 - i**2 + i + 2024
p =nextprime(p1)
q =nextprime(q1)
if p*q==n:
return p,q
for i in range(r-1,r-10,-1):
p1 = i**5 + i**4 - i**3 + i**2 - i + 2024
q1 = i**5 - i**4 + i**3 - i**2 + i + 2024
p =nextprime(p1)
q =nextprime(q1)
if p*q==n:
return p,q
p,q = r_test(r,n) #通过r的近似值和n获取p,q
from sympy import mod_inverse
#已知e(加密指数)
e = 65537
# 计算私钥d
d = mod_inverse(e, (p - 1) * (q - 1))
# 已知密文c
c = 643011921358774538378881505518732362708757638007688649119354348647468190640688857686213431516881297805187671774564672497176686191162897918672339254715366498963369868410476737543157157149810569
# 解密密文
m = pow(c, d, n)
# 将解密后的消息m转换成可读的格式
print("解密后的消息:", m.to_bytes((m.bit_length() + 7) // 8, 'big').decode())