HGAME 2024 week4(crypto)
HGAME 2024 week4(crypto)
lastRSA
这题如何求leak0我想了很久,但实际上套个Franklin-Reiter相关消息攻击的板子就能求得leak0,代码如下:
n=136159501395608246592433283541763642196295827652290287729738751327141687762873360488671062583851846628664067117347340297084457474032286451582225574885517757497232577841944028986878525656103449482492190400477852995620473233002547925192690737520592206832895895025277841872025718478827192193010765543046480481871
enc1=2481998981478152169164378674194911111475668734496914731682204172873045273889232856266140236518231314247189371709204253066552650323964534117750428068488816244218804456399611481184330258906749484831445348350172666468738790766815099309565494384945826796034182837505953580660530809234341340618365003203562639721024
enc2=2892413486487317168909532087203213279451225676278514499452279887449096190436834627119161155437012153025493797437822039637248773941097619806471091066094500182219982742574131816371999183859939231601667171386686480639682179794271743863617494759526428080527698539121555583797116049103918578087014860597240690299394
c=87077759878060225287052106938097622158896106278756852778571684429767457761148474369973882278847307769690207029595557915248044823659812747567906459417733553420521047767697402135115530660537769991893832879721828034794560921646691417429690920199537846426396918932533649132260605985848584545112232670451169040592
e = 41
t = 114514
def franklinReiter(n,e,c1,c2):
PR.<x> = PolynomialRing(Zmod(n))
g1 = (x+2*t)^e-(c1-2023)*(x+2*t)+enc1-2024
g2 = (x*2*t)^e-(c2-2023)*(x*2*t)+enc2-2024
def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()
return -gcd(g1, g2)[0]
leak0=franklinReiter(n,e,enc1,enc2)
#leak0=13168452015078389807681744077701012683188749953280204324570483361963541298704796389757190180549802771265899020301416729606658667351017116721327316272373584
然后由于leak0是p^(q>>13),这里注意一下,刚开始我把这个看成了次方,实际上是异或。对于这种异或类的网上是有现成的板子,请参考大佬的博客,
然后把大佬的代码拿来改了改,最后脚本如下:
#print(bin(leak0)[0:15])
#1111101101101 前十三位已知
a1=str(bin(leak0)[15:])
def find(p,q):
x = len(p)
tmp0 = '1111101101101'+ p + (499-x)*"0"
tmp1 = '1111101101101'+ p + (499-x)*"1"
tmq0 = q + (512-x)*"0"
tmq1 = q + (512-x)*"1"
if(int(tmp0,2)*int(tmq0,2) > n):
return
elif(int(tmp1,2)*int(tmq1,2) < n):
return
pp = int(tmp0,2)
if(n % pp == 0):
print(pp)
return 0
else:
if(a1[x] == "1"):
find(p+"1",q+"0")
find(p+"0",q+"1")
else:
find(p+"0",q+"0")
find(p+"1",q+"1")
tempp = ""
tempq = ""
find(tempp,tempq)
# 13167244882304693277785720567493996610066918256369682594482416913362069704726831109204371100970154866396462315730687841430922916219416627940866383413192931
得到p值后就是常规的RSA解密了,代码如下:
p=13167244882304693277785720567493996610066918256369682594482416913362069704726831109204371100970154866396462315730687841430922916219416627940866383413192931
q=n/p
phi=(p-1)*(q-1)
e=65537
d = inverse_mod(e,phi)
long_to_bytes(int(pow(c,d,n)))
# b'hgame{Gr0bn3r_ba3ic_0ften_w0rk3_w0nd3rs}'
transformation
这是一道曲线题,根据代码可判断出是Twisted Edwards Curves,跟cryptoctf 2021 RoHald这题类似,脚本如下:
from math import gcd
def ison(C, P):
"""
Verification points are on the curve
"""
c, d, p = C
u, v = P
return (u**2 + v**2 - cc * (1 + d * u**2*v**2)) % p == 0
def a_and_b(u1,u2,v1,v2):
"""
Helper function used to simplify calculations
"""
a12 = u1**2 - u2**2 + v1**2 - v2**2
b12 = u1**2 * v1**2 - u2**2 * v2**2
return a12, b12
def find_modulus(u1,u2,u3,u4,v1,v2,v3,v4):
"""
Compute the modulus from four points
"""
a12, b12 = a_and_b(u1,u2,v1,v2)
a13, b13 = a_and_b(u1,u3,v1,v3)
a23, b23 = a_and_b(u2,u3,v2,v3)
a24, b24 = a_and_b(u2,u4,v2,v4)
p_almost = gcd(a12*b13 - a13*b12, a23*b24 - a24*b23)
for i in range(2,1000):
if p_almost % i == 0:
p_almost = p_almost // i
return p_almost
def c_sq_d(u1,u2,v1,v2,p):
"""
Helper function to computer c^2 d
"""
a1,b1 = a_and_b(u1,u2,v1,v2)
return a1 * pow(b1,-1,p) % p
def c(u1,u2,v1,v2,p):
"""
Compute c^2, d from two points and known modulus
"""
ccd = c_sq_d(u1,u2,v1,v2,p)
cc = (u1**2 + v1**2 - ccd*u1**2*v1**2) % p
d = ccd * pow(cc, -1, p) % p
return cc, d
P = (423323064726997230640834352892499067628999846, 44150133418579337991209313731867512059107422186218072084511769232282794765835)
Q = (1033433758780986378718784935633168786654735170, 2890573833121495534597689071280547153773878148499187840022524010636852499684)
S = (875772166783241503962848015336037891993605823, 51964088188556618695192753554835667051669568193048726314346516461990381874317)
T = (612403241107575741587390996773145537915088133, 64560350111660175566171189050923672010957086249856725096266944042789987443125)
u1, v1 = P
u2, v2 = Q
u3, v3 = S
u4, v4 = T
p = find_modulus(u1,u2,u3,u4,v1,v2,v3,v4)
cc, d = c(u1,u2,v1,v2,p)
C = cc, d, p
assert ison(C, P)
assert ison(C, Q)
assert ison(C, S)
assert ison(C, T)
print(f'Found curve parameters')
print(f'p = {p}')
print(f'c^2 = {cc}')
print(f'd = {d}')
F = GF(p)
c = F(cc).sqrt()
print(c)
#p = 67943764351073247630101943221474884302015437788242536572067548198498727238923
#c^2 = 12908728488299650872377430201970332178171657588185291326485782119189255844928
#d = 8779982120820562807260290996171144226614358666469579196351820160975526615300
#c=7143899698109428282870539364581968579753042129945786627292343174759297201080
然后已知曲线参数后,要求G的值,如果是ECC,直接eG*inverse_mod(e,p)。类似地先转为ECC上的点,求出G后再转换为在这条曲线上的G,也是有现成的板子,代码如下:
a = 1
e = 0x10001
eG = (40198712137747628410430624618331426343875490261805137714686326678112749070113, 65008030741966083441937593781739493959677657609550411222052299176801418887407)
F = GF(p)
dd = F(d*c^4)
A = F(2) * F(a+dd) / F(a-dd)
B = F(4) / F(a-dd)
a = F(3-A^2) / F(3*B^2)
b = F(2*A^3-9*A) / F(27*B^3)
def edwards_to_ECC(x,y):
x1 = F(x) / F(c)
y1 = F(y) / F(c)
#now curve is a*x^2+y^2 = 1+dd*x^2*y^2
x2 = F(1+y1) / F(1-y1)
y2 = F(x2) / F(x1)
#now curve is By^2 = x^3 + Ax^2 + x
x3 = (F(3*x2) + F(A)) / F(3*B)
y3 = F(y2) / F(B)
#now curve is y^2 = x^3 + ax + b
return (x3,y3)
def ECC_to_edwards(x,y):
x2 = (F(x) * F(3*B) - F(A)) / F(3)
y2 = F(y) * F(B)
#now curve is By^2 = x^3 + Ax^2 + x
x1 = F(x2) / F(y2)
y1 = F(1) - (F(2) / F(x2+1))
#now curve is a*x^2+y^2 = 1+dd*x^2*y^2
x_ = F(x1) * F(c)
y_ = F(y1) * F(c)
#now curve is a*x^2+y^2 = c^2(1+d*x^2*y^2)
return (x_,y_)
E = EllipticCurve(GF(p), [a, b])
order = E.order()
eG = E(edwards_to_ECC(eG[0],eG[1]))
t = inverse(e,order)
G = t*eG
G = ECC_to_edwards(G[0],G[1])
flag = "hgame{" + hex(int(G[0])+int(G[1]))[2:] + "}"
print(flag)
# hgame{7c91b51150e2339628f10c5be61d49bbf9471ef00c9b94bb0473feac06303bcc}

浙公网安备 33010602011771号