DASCTF 2024暑期挑战赛------1z_RSA
题目:
from Crypto.Util.number import *
from sympy import *
import os
from secrets import flag
nbit =130
e = 3
l = getPrime(505)
m = bytes_to_long(flag + os.urandom(64))
assert len(flag) == 29
while True:
p, q = getPrime(nbit), getPrime(nbit)
PQ = int(str(p<<120)+str(q))
QP = int(str(q<<120)+str(p))
if isPrime(PQ) and isPrime(QP):
break
n = PQ * QP
PP = nextprime((PQ >> 190) * (QP & (2 ** 190 - 1)))
QQ = nextprime((QP >> 190) * (PQ & (2 ** 190 - 1)))
N = PP * QQ
M = pow(m,1,l)
c = pow(m,e,N)
print('n =', n)
print('M =', M)
print('l =', l)
print('c =', c)
'''
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322
l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189
c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923
'''
分析代码,需要求出m
要得到N
的值,那么就得求出PQ
和QP
。看一下PQ
和QP
的取值方式,知道\(PQ=p*2^{120}*10^{40}+q\)、\(QP=q*2^{120}*10^{39}+p\),所以\(n=PQ*QP=p * q * (2 ^{240} * 10^{79} + 1) + (p^2 + 10 * q^2) * 2^{120} * 10^{39}\),分析一下知道\(2 ^{240} * 10^{79} + 1\)的比特位数大概是503
左右,\((p^2 + 10 * q^2) * 2^{120} * 10^{39}\)的比特位数大概是510
左右,两者相差不大,那么两边同时除以\(2 ^{240} * 10^{79} + 1\),得\(p*q=n//(2 ^{240} * 10^{79} + 1) \pm x\),这里x
的值并不大,可以自行设置个区间进行爆破,那么p*q
的值我们是可以知道的,要想求出两个未知数p q
还需要知道一个方程才能解出来,我们回到最开始的\(n=PQ*QP=p * q * (2 ^{240} * 10^{79} + 1) + (p^2 + 10 * q^2) * 2^{120} * 10^{39}\),既然我们知道p*q
的值我们可以转化一下等式为\(n-p * q * (2 ^{240} * 10^{79} + 1)=(p^2 + 10 * q^2) * 2^{120} * 10^{39}\),化简一下\(p^2 + 10 * q^2=\frac{n-p * q * (2 ^{240} * 10^{79} + 1)}{2^{120}*10^{39}}\),这就是我们第二个方程式了,最后写脚本求出p q
。注:n - p * q * (2 ^{240} * 10^{79} + 1)必须能被2^{120} * 10^{39}整除。
exp:
from sympy import *
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
for x in range(1500):
pq=n//(2**240*10**79+1)-x
if (n-pq*(2**240*10**79+1))%(2**120*10**39)==0:
p2_q2=(n-pq*(2**240*10**79+1))//(2**120*10**39)
p=Symbol('p')
q=Symbol('q')
pq1=pq-p*q
pq2=p**2+10*q**2-p2_q2
s=solve((pq1,pq2))
print(s)
#p: 1213149261930568621267125437333569321667, q: 855604426214387476576649090490109822073
最后求出N
,接下来求解m
。
那么我们可以用coppersmith
求出k
。
exp:
from sympy import *
p = 1213149261930568621267125437333569321667
q = 855604426214387476576649090490109822073
PQ = int(str(p<<120)+str(q))
QP = int(str(q<<120)+str(p))
PP = nextprime((PQ >> 190) * (QP & (2 ** 190 - 1)))
QQ = nextprime((QP >> 190) * (PQ & (2 ** 190 - 1)))
N = PP * QQ
#N = 763933528218428362740063144747893290714655295576768532896029874141179804730143020017430379534079773751531037961074867132893544981605022026151484151321515584652838724809597675412676810669583078026377048734720511960708515190930979
#sage
from Crypto.Util.number import *
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322
l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189
c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923
N = 763933528218428362740063144747893290714655295576768532896029874141179804730143020017430379534079773751531037961074867132893544981605022026151484151321515584652838724809597675412676810669583078026377048734720511960708515190930979
PR.<x> = PolynomialRing(Zmod(N))
f = c - (M+x*l)^3
f = f.monic()
roots = f.small_roots(X=2^239,epsilon = 0.02)
k = roots[0]
m = M+k*l
print(long_to_bytes(m))
#DASCTF{Ar3_Y0u_Su93_Abt139??}