题目:
from Crypto.Util.number import *
from sage.all import *
from random import randrange
from secret import flag
m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 65537
r = bin(getPrime(len(flag)))[2:]
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
a = randrange(1, n)
c = (pow(m-pow(a,e,n), d, n)) % n
z = sum([int(r[i])*a**i for i in range(len(r))])
assert z < a**15 + 1
z = z % n
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
print(f'z = {z}')
题目理论难度不高,就是爆破质数,解方程,其中m较小可以把a消元,然后small_root,刚开始groebner_basis()和resultant消元发现指数比较高,因为有其实有多个f,两次resultant然后HGCD,搞出指数比较小的多项式,自己数据测试,9位没有问题,所以开始爆破,15位质数加9位flag需要3个小时,修改多线程跑:
from sage.all_cmdline import * # import sage library
from sage.all import *
from sage.matrix.matrix2 import Matrix as Matrix2
from Crypto.Util.number import *
import multiprocessing
def resultant(f1, f2, var):
#print(f1.sylvester_matrix(f2, var))
return Matrix2.determinant(f1.sylvester_matrix(f2, var))
n = 18958523822965779912899827783107438587572040487657111002474465900654251879648263776126782079490757516910092179229455697277114063200369560902566011503634573360990937108599191248791849618222649751050364361142600937548721273695606870531223115536894668583705065413241189513987778142820106936724774404027632297204326276900214510048550175919812310454623719455076518243383150380368352788245272891910180838780789265307926922228219671680149003036378499914252991087458570463044465887439954979441914227099761352286375336573082314068827094531345166273341200406447201114205915685170884295487124853039513234346915988003083904836693
e = 65537
c = 7686325199783272501572663174944755197791969370073187592251283865295440441060782400934009069787663356292165611134077915144925528467882885709675333515694288666120491594067996922521358065728072307779844654129380190278856814240484104370146630764792937658249106660318159393183856951836389587053477192829545069963314314238475766679268156189975051160344008244559582485586459952479020733368116753984144655302562187636209261364527605350759877694549049990708347877181830797691918826618366455511891171006294630191265136416467827504525021358151857386350805405256624532016401764802206666925927135797484939694162365798975882694400
z = 17950614509301690602331343526239959553361375297339190587035556501079164302293518648188343348695236634911677063321150112475964510884955885124571880690217875346815645822477251375686977571543320490617041697266656309287159844665671440176711392792168744385352881631876228518237664899306901002781611277601364328780219360646320253657773434189290477727573012009061692650151046975693283805592667681572001657620919743316515115813954895134531216761690636659433546138824119350927121917046759668488138718761936764212549027785798985119280676435812256960695225986500366400430644284664200908678552035575318170314847737926483287943789
from tqdm import tqdm
def test_sj(zs,s_i,e_i,c1,flenxx):
def GCD(a, b):
def HGCD(a, b):
if 2 * b.degree() <= a.degree() or a.degree() == 1:
return 1, 0, 0, 1
m = a.degree() // 2
a_top, a_bot = a.quo_rem(x**m)
b_top, b_bot = b.quo_rem(x**m)
R00, R01, R10, R11 = HGCD(a_top, b_top)
c = R00 * a + R01 * b
d = R10 * a + R11 * b
q, e = c.quo_rem(d)
d_top, d_bot = d.quo_rem(x**(m // 2))
e_top, e_bot = e.quo_rem(x**(m // 2))
S00, S01, S10, S11 = HGCD(d_top, e_top)
RET00 = S01 * R00 + (S00 - q * S01) * R10
RET01 = S01 * R01 + (S00 - q * S01) * R11
RET10 = S11 * R00 + (S10 - q * S11) * R10
RET11 = S11 * R01 + (S10 - q * S11) * R11
return RET00, RET01, RET10, RET11
q, r = a.quo_rem(b)
if r == 0:
return b
R00, R01, R10, R11 = HGCD(a, b)
c = R00 * a + R01 * b
d = R10 * a + R11 * b
if d == 0:
return c.monic()
q, r = c.quo_rem(d)
if r == 0:
return d
return GCD(d, r)
for i in tqdm(range(s_i,e_i)):
if e_i>(len(zs)-2):
break
a=zs[i]
flenxxtmp=8*flenxx-1
#a=30047
flag=b"flag{"+b"\x00"*flenxx+b"}"
mbase = bytes_to_long(flag)
r = bin(a)[2 :]
P = PolynomialRing(Zmod(n), names=('x', 'y',)); (x, y,) = P._first_ngens(2)
f=-z
for i in range(len(r)):
f=f+int(r[i])*(x**i)
f2=x**e+c1-y*256-mbase
#print(type(f2))
F = [f,f2]
I = Ideal(F).groebner_basis()
#print(I)
f3=I[0]
f4=I[1]
h1=(resultant(f3,f,x))
h2=(resultant(f4,f,x))
R = PolynomialRing(Zmod(n), names=('y',))
h1=R(h1)
h2=R(h2)
h3=GCD(h1,h2)
h1=h3.monic()
res=h1.small_roots(X=2**flenxxtmp, beta=0.4)
if len(res)>0:
print(flenxx,a,res)
break
for flen in range(0,1):
flenxx=9-flen
print("flenxx=",flenxx)
i=next_prime(2**(5+flenxx))
c1=pow(c,e,n)
print("c1=",c1)
zs=[]
while i<2**(6+flenxx):
zs.append(int(i))
i=next_prime(i)
xcs=5
kk=len(zs)//xcs+1
for k in range(xcs):
p = multiprocessing.Process(target=test_sj, args=(zs,kk*k,kk*(k+1),c1,flenxx,))
p.start()
print(k," start!!!")
#9 27673 [1373504846084034408822] =>Ju5t_tr1v
后面再看了一下,直接快速幂更加快,1个小时,多线程15分钟内
from sage.all_cmdline import * # import sage library
from sage.all import *
from sage.matrix.matrix2 import Matrix as Matrix2
from Crypto.Util.number import *
import multiprocessing
def resultant(f1, f2, var):
#print(f1.sylvester_matrix(f2, var))
return Matrix2.determinant(f1.sylvester_matrix(f2, var))
n = 18958523822965779912899827783107438587572040487657111002474465900654251879648263776126782079490757516910092179229455697277114063200369560902566011503634573360990937108599191248791849618222649751050364361142600937548721273695606870531223115536894668583705065413241189513987778142820106936724774404027632297204326276900214510048550175919812310454623719455076518243383150380368352788245272891910180838780789265307926922228219671680149003036378499914252991087458570463044465887439954979441914227099761352286375336573082314068827094531345166273341200406447201114205915685170884295487124853039513234346915988003083904836693
e = 65537
c = 7686325199783272501572663174944755197791969370073187592251283865295440441060782400934009069787663356292165611134077915144925528467882885709675333515694288666120491594067996922521358065728072307779844654129380190278856814240484104370146630764792937658249106660318159393183856951836389587053477192829545069963314314238475766679268156189975051160344008244559582485586459952479020733368116753984144655302562187636209261364527605350759877694549049990708347877181830797691918826618366455511891171006294630191265136416467827504525021358151857386350805405256624532016401764802206666925927135797484939694162365798975882694400
z = 17950614509301690602331343526239959553361375297339190587035556501079164302293518648188343348695236634911677063321150112475964510884955885124571880690217875346815645822477251375686977571543320490617041697266656309287159844665671440176711392792168744385352881631876228518237664899306901002781611277601364328780219360646320253657773434189290477727573012009061692650151046975693283805592667681572001657620919743316515115813954895134531216761690636659433546138824119350927121917046759668488138718761936764212549027785798985119280676435812256960695225986500366400430644284664200908678552035575318170314847737926483287943789
from tqdm import tqdm
c1=pow(c,e,n)
print("c1=",c1)
def jfc_test(zs,s_i,e_i,flenxx):
for k in tqdm(range(s_i,e_i)):
a=zs[k]
flenxxtmp=8*flenxx-1
#a=30047
flag=b"flag{"+b"\x00"*flenxx+b"}"
mbase = bytes_to_long(flag)
r = bin(a)[2 :]
P = PolynomialRing(Zmod(n), names=('x', 'y',)); (x, y,) = P._first_ngens(2)
f=-z
for i in (range(len(r))):
f=f+int(r[i])*(x**i)
f2=x
F = 1
for i in bin(e)[2:][::-1]:
if i == '1':
F = (F*f2)%f
f2 = (f2*f2)%f
f2=F+c1-y*256-mbase
#print(f2)
h1=(resultant(f2,f,x))
R = PolynomialRing(Zmod(n), names=('y',))
h1=R(h1)
h1=h1.monic()
res=h1.small_roots(X=2**flenxxtmp, beta=0.4)
if len(res)>0:
print(flenxx,a,res)
break
for flen in range(0,1):
flenxx=9-flen
print("flenxx=",flenxx)
i=next_prime(2**(5+flenxx))
zs=[]
while i<2**(6+flenxx):
zs.append(int(i))
i=next_prime(i)
zs=zs[::-1]
flenxx=9-flen
print("flenxx=",flenxx)
xcs=5
kk=len(zs)//5+1
for k in range(xcs):
p = multiprocessing.Process(target=jfc_test, args=(zs,kk*k,kk*(k+1),flenxx,))
p.start()
print(k," start!!!")
只能说自己还是菜啊。。。。