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}
posted @ 2024-03-01 12:46  Rota13  阅读(42)  评论(0)    收藏  举报