题目:
from random import randint
from gmpy2 import *
from Crypto.Util.number import *
def getprime(bits):
while 1:
n = 1
while n.bit_length() < bits:
n *= next_prime(randint(1,1000))
if isPrime(n - 1):
return n - 1
m = bytes_to_long(b'flag{************************************}')
p = getprime(505)
q = getPrime(512)
r = getPrime(512)
assert m < q
n = p * q * r
e = 0x10001
d = invert(q ** 2, p ** 2)
c = pow(m, 2, r)
cipher = pow(c, e, n)
print(n)
print(d)
print(cipher)
'''
7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409
7515987842794170949444517202158067021118454558360145030399453487603693522695746732547224100845570119375977629070702308991221388721952258969752305904378724402002545947182529859604584400048983091861594720299791743887521228492714135449584003054386457751933095902983841246048952155097668245322664318518861440
1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200
'''
考察知识点:
1.光滑数 RSA中利用光滑数进行模数分解-CSDN博客
2.nthroot
题解:
从题目可以得知公式,三角代表已知数
从公式可以得知需求出p,q,r,然后逆元出di,从而解出c,m,直接看代码
from Crypto.Util.number import *
from primefac import *
import gmpy2
from sympy import *
n=7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409
d = 7515987842794170949444517202158067021118454558360145030399453487603693522695746732547224100845570119375977629070702308991221388721952258969752305904378724402002545947182529859604584400048983091861594720299791743887521228492714135449584003054386457751933095902983841246048952155097668245322664318518861440
cipher = 1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200
e = 0x10001
# 1. 通过光滑数得到p,光滑数求解因子恰好为505bit位的参数p,继续用光滑数向下求解q,r会发现非常慢,可以通过已知条件求解q和r
p = williams_pp1(n)
# 得知505bit位的p
# 2. 继续通过d对p^2的逆元求解出q^2 mod p^2,但这里不是唯一解,因为p^2非素数,所以就要考虑用nthroot求解出q
# 即公式 q_2 = q ^ 2 mod p ^ 2;这里尝试通过暴力枚举k参也能得出q;
q_2 = gmpy2.invert(d, p ** 2)
# Find the solutions to ``x**n = a mod m`` when m is not prime.
q = nthroot_mod(q_2, 2, p ** 2)
# 3. 求得r
r = n // p // q
# 4. 继续逆元求解出c
fin = (p-1)*(q-1)*(r-1)
di = gmpy2.invert(e, fin)
c = gmpy2.powmod(cipher, di, n)
#5. nthroot求解出m
m = nthroot_mod(c, 2, r)
print(long_to_bytes(m))
#b'flag{fd462593-25e4-4631-a96a-0cd5c72b2d1b}'