Skip to content

Instantly share code, notes, and snippets.

@msjyryxdzzj
Last active January 14, 2024 15:33
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msjyryxdzzj/e3bd3dad74725c1d0212ccfa6ae2f9e8 to your computer and use it in GitHub Desktop.
Save msjyryxdzzj/e3bd3dad74725c1d0212ccfa6ae2f9e8 to your computer and use it in GitHub Desktop.
RWCTF 3rd - Crypto - Old Curse solve script
from Crypto.Util.number import *
PR.<qr>=PolynomialRing(ZZ)
def calc_params(e,N):
delta = 0.1
gama = 0.05
beta = log(e,N).n()
alpha = 0.25
return alpha,beta,delta,gama
def condition_check(alpha,beta,delta,gama):
print delta
print 7/6 + (1/3)*alpha-gama-(1/3)*sqrt((2*alpha+1)*(2*alpha+6*beta-6*gama+1))
return delta < 7/6 + (1/3)*alpha-gama-(1/3)*sqrt((2*alpha+1)*(2*alpha+6*beta-6*gama+1))
def calc_tau(alpha,beta,delta,gama):
return (1-2*delta-2*alpha-2*gama)/(2*(1+2*alpha))
def calc_XYZ(alpha,beta,delta,gama,N):
X = next_prime(floor(4*N^(beta+delta-1)))
Y = next_prime(floor(3*sqrt(2)*N^(1/2+alpha)))
Z = next_prime(floor(N^gama))
return X,Y,Z
def multivariate(pol,X,Y,Z,tau,mm,alpha,beta,delta,gama,e,N):
P.<x,y,z> = PolynomialRing(ZZ)
tt = floor(tau*mm)+1
#tt = 1
ff = x*y - (N)*x + z
polys = []
monomials = []
for k in range(mm+1):
for i1 in range(k,mm+1):
i2 = k
i3 = mm-i1
poly = x^(i1-k)*(z)^i3*ff^k*e^(mm-k)
polys.append(poly)
for k in range(mm+1):
i1 = k
for i2 in range(k+1,i1+tt+1):
i3 = mm-i1
poly = y^(i2-k)*(z)^(i3)*ff^k*e^(mm-k)
polys.append(poly)
polys = sorted(polys)
for poly in polys:
monomials += poly.monomials()
monomials = sorted(set(monomials))
nn = len(monomials)
BB = Matrix(ZZ,nn)
print len(polys)
print len(monomials)
for ii in range(nn):
#BB[ii, 0] = polys[ii](0, 0, 0)
for jj in range(nn):
if monomials[jj] in polys[ii].monomials():
#BB[ii, jj] = polys[ii].monomial_coefficient(monomials[jj]) * monomials[jj](X,Y,Z)
BB[ii,jj] = polys[ii](X*x,Y*y,Z*z).monomial_coefficient(monomials[jj])
#print BB
print monomials
BB = BB.LLL(delta=0.75)
print "LLL done"
#print BB
dims = nn
H = [(i, P(0)) for i in xrange(dims)]
H = dict(H)
for j in xrange(dims):
for i in xrange(dims):
H[i] += P((monomials[j] * BB[i, j]) / monomials[j](X,Y,Z))
poly = P(gcd(H[0],H[1]))
print poly
print -poly.monomial_coefficient(x)
print poly.monomial_coefficient(x*y)
return N - ceil((-poly.monomial_coefficient(x))/poly.monomial_coefficient(x*y))
def gen(p,q,Ep,Eq,delta,gama):
N = p*q
u = random_prime(floor(N^delta), proof=False, lbound=ceil(N^(delta-0.02)))
print u
print log(u,N).n()
w = random_prime(floor(N^gama), proof=False, lbound=ceil(N^(gama-0.02)))
print w
print log(w,N).n()
e = (w*inverse_mod(u,Ep*Eq))%(Ep*Eq)
print e
print log(e,N).n()
v = (e*u - w)/(Ep*Eq)
print v
print log(v,N).n()
return e,u,w
def main(e,N,mm):
P.<x,y,z> = PolynomialRing(ZZ)
alpha,beta,delta,gama = calc_params(e,N)
assert condition_check(alpha,beta,delta,gama)
pol = x*y- (N)*x + z
X,Y,Z = calc_XYZ(alpha,beta,delta,gama,N)
tau = calc_tau(alpha,beta,delta,gama)
res = multivariate(pol,X,Y,Z,tau,mm,alpha,beta,delta,gama,e,N)
return res
if __name__ == "__main__":
'''
N = 2445641520497188372893910329538675824331454921520163900426562393634418526897575682249916293416221269674459540700624274860236238684609738360751815410091617
e = 207753540686843587408555602893982678168821441852165899252123932416370824148707563812033872059010473801740084336709522813588017197501164099322578137710783
e = 1385541386350864526341998465216697876045250157636252495557496884777332366331828079007542764765138085082758016229583509718779067112153670966735233957418107
p = 68592042559830614325177858341490526647123827945850285759827931818992553395171
q = 35654886911465489386559478739125595731698572982484092580287175860557076482027
assert N == p*q
a = 0
b = 9
mm = 2
delta = 0.085
gama = 0.045
Ep = EllipticCurve(GF(p),[a,b])
Eq = EllipticCurve(GF(q),[a,b])
p_order = Ep.order()
q_order = Eq.order()
main(e,N,p,q,p_order,q_order,delta,gama,mm)
'''
'''
N = 43115265506687226436196728756959707266402158394261294759458139340520129183826747
e = 4429109683378321635373164354359544019395496659337936831132897706681971178351139
delta = 0.15
gama = 0.05
mm = 2
p = 6672224014662340178579721474326734152749
q = 6461903169309154483833797011785886506503
p_order = 6672224014662340178579721474326728185600
q_order = (43115265506687226436196728756959661642298658940914579533819094510831187730169600/p_order)
main(e,N,p,q,p_order,q_order,delta,gama,mm)
'''
a = 0x4a2e6dec145a807c30098f59a73305f5e0cadb3d6a90da183ded22d4dbee0865bbdbed56698289afb60a534a0af0226bbb94245671f747e820f6a70c928dfa07
b = 0x120a461de47b36eeacd572a40bea21b0ed1475503905d1c2a1bab2c812bbc8f548e638f126f84fcddc2188c9f2bd3ee282bc5cfe253424d4594ee72985b3fd8c
N = 80330528881183983072964816732300543404856810562533626369319300810697262966387144944887576330528743612839739692299784591097332512948890518183519167192046959230085412831864255497489112175176914874596237618253755256608956517757030073479666104923402013469283716999320744856718736837534911809839541660207743594867
mm = 2
e = 78452652317506438607956636739779994986676384637399723342738736371812868831141251164966879331214017314432739387076791674001159059604426825547538902010774841189596518785149221523738464397224366361779781148300651051284198636694801404816891957209985325619623109930150535820404950711233032177848101830061155574970
#e,u,w = gen(p,q,p_order,q_order,delta,gama)
res = main(e,N,mm)
L = ecm.factor(res)
print L
q_order = 131*1108897087*505386797752007*120659691081137900860528439558149439256036479214584879088476613192185895986414329679519081477454257879221194033908435726005914629
p_order = res//q_order
lbound = floor(sqrt(N)-N^(1/4))
ubound = ceil(sqrt(2*N)+N^(1/4))
assert lbound< p_order and p_order < ubound
phi = lcm(p_order,q_order)
E = EllipticCurve(Zmod(N),[a,b])
Stone = E(5316297494616251967087180573684467112077977207314228196651011473838683480275875989908990738740861375687186766156200219641981169308660139151062711296717379891376294785675104640775506724244803337279235747630215478504380272738204733311972022712834357078381541224632797503360732934454187646031643331529389570159,73177062713968648963738410812785853174528721431172461113561340178691492280271903912043554814810920745154304747328073913103230849027745226637330284520633847773874342467137552022725301429074046921710660867115557994943332628756632246059800601063580017261698262663178072317324978782579376388601713100806653808812)
d = inverse_mod(e,phi)
Heart = d*Stone
print long_to_bytes(Integer(Heart[0]))
R = Zmod(N)
PR.<xn> = PolynomialRing(R)
bits = 250
for i in range(8):
print i
f = p_order - i*2^250 - xn
f = f.monic()
roots = f.small_roots(X=2^bits, beta=0.4,epsilon = 1/150)
if len(roots) != 0:
r = Integer(roots[0]+i*2^250)
print "[+]found root : ",r
break
p = p_order - Integer(r)
q = N/p
assert N%p == 0
flag = long_to_bytes(Integer(Heart[0])^^(p*2^248))
print flag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment