print('n =', n) print('M =', M) print('l =', l) print('c =', c)
''' n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691 M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322 l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189 c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923 '''
from Crypto.Util.number import long_to_bytes import itertools import sys
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality()
f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = Sequence([], f.parent()) for i inrange(m + 1): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots return []
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
lenght = [39,40] for i in lenght: for j in lenght: print((i, j)) R.<x,y> = PolynomialRing(Zmod(n^2)) PQ = x*2^120*10^i + y QP = y*2^120*10^j + x f = n - PQ*QP roots = small_roots(f,(2^130,2^130),m=1,d=4) if roots !=[]: # print(roots) p,q = roots[0] print(p,q) break
from Crypto.Util.number import * from sympy import nextprime import itertools
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality() f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = Sequence([], f.parent()) for i inrange(m+1): base = N^(m-i) * f^i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1/factor)
H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B*monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots
return []
nbit = 130 PR.<p,q> = PolynomialRing(Zmod(n)) f = n-((2*p+1)*2^120*10^39+(2*q+1))*((2*q+1)*2^120*10^40+(2*p+1)) bounds = (2^(nbit-1),2^(nbit-1)) res = small_roots(f,bounds,m=1,d=2) p,q = 2*int(res[0][1])+1,2*int(res[0][0])+1 print(p,q)
法三:解方程
n = pq(2^{240}10^{x+y}+1)+p^22^{120}10^{x}+q^22^{120}10^{y}\ =pq*(2^{240}10^{79}+1)+(p^2+10q^2)*2^{120}*10^{39}
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
for i in trange(2**10): pq = n // (2**240 * 10**79 + 1) - i pq2 = (n - pq*(2**240 * 10**79 + 1)) // (2**120 * 10**39) if (n - pq*(2**240 * 10**79 + 1)) % (2**120 * 10**39) == 0: # 倍数 p, q = sympy.symbols('p q') flag = sympy.solve([pq - p*q,pq2-(p**2+10*q**2)],[p,q]) break
p = abs(flag[0][0]) q = abs(flag[0][1]) print(p,q)
c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923
for mp in GF(PP)(c).nth_root(e, all=True): for mq in GF(QQ)(c).nth_root(e, all=True): m = long_to_bytes(crt([ZZ(mp), ZZ(mq)], [PP, QQ])) ifb'DASCTF'in m: print(m) break
法二:明文低位泄露
题目中还有这样一个条件 M = pow(m,1,l) m = m_high+M M+kl = m 已知: l = getPrime(505) m = bytes_to_long(flag + os.urandom(64)) assert len(flag) == 29 m的位数是(29+64)8
M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322 l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189 c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923 p = 1213149261930568621267125437333569321667 q = 855604426214387476576649090490109822073