2023闽盾杯CTF Crypto


2023闽盾杯线上初赛

这高职组比本科组难的可不是一点,建议做高职组的题,本科组看看就好

本科组


DDSA

就是dsa签名,然后私钥取值太小了,考虑用格解一下就出了。DSA签名)

这题总结一下就一个式子

这一看就像hnp

尝试1

尝试失败,这里$m^{-1}$太大了,1024bits,而私钥$pri$只有384。


Solution

对于

如果$x,C$均是小bits,那么很容易求解

这里考虑$m$是一个小于512bits,即小于64字节的flag。实际上最后算出来m很小很合理吧

实际上m<512bits也能格出来,但是最好是已知flag的长度,构造相应的格。可以把512换成$len(flag)*8$就好了

exp

prime_p = 254843759712120770192107797102254314236912507988317949449773952808056853528137124034192193635099026436082859359975257478069529928753465466553898924428657727410192480025664330547720267491593689914315716652925690802124634579341155119238992435231736067051804606192447508930100501670982605518547228404550199336703
prime_q = 127421879856060385096053898551127157118456253994158974724886976404028426764068562017096096817549513218041429679987628739034764964376732733276949462214328863705096240012832165273860133745796844957157858326462845401062317289670577559619496217615868033525902303096223754465050250835491302759273614202275099668351
generator = 2
public_key = 67243435243013084147486854556817234112402511481243660325565023251853355494433326575673419694681555652669449040366620819266474334253578972440047168279142184141910485872726393507923996391796227576994885784959692699388957187699662551912804856807879764447982440118185734843107861320087767180763032071844141444498
# FLAG= *******************************
hash_value = '1cd920cc96d95280c96dd519df9ef49fed44c0ccfc80202372d1d196ea52ccb1'
value_r = 55738970979693187681378167695787130117222895714960965190485398883361826593727577547551100491285488657995662094510198245807164881975668033129508588482949937072551764160574163358989597712065236233432502150653495180122562651440328815420270936429340024510654195118602283837975822678425908768515924976212206091388
value_s = 16167384383010337939063062611160328697878797853686180912699394152331808942993583340068941838844464059078517385061012722104618040645796346201205622044690989665622791251498050801728558982153896995503905626972211668853043513769350513237538819164197920332285202321957958655237257294973629465658550364418471213584


A=ZZ(inverse(int(hash_value, 16),prime_q)*value_r %prime_q)
B=ZZ(inverse(int(hash_value, 16),prime_q)*value_s %prime_q)
RR=RationalField(1024)

M=Matrix(RR,3,3)
M[0,0]=prime_q
M[1,0]=-A
M[2,0]=B
M[1,1]=2^(384+512)/2^1024
M[2,2]=2^(512)
M.LLL()

ouput

[                                                                                  69926697342996842887242115923853189774766274334095360573032015342436014501831440985383441433582944809103120272795169946324148984957367     -4675373325063939104739945235827575248496868545626607019126848342129312834075044302850501316166275362512389953001439866250519368074174211293886561786517651216509348739682931/85070591730234615865843651857942052864                                                                                                                                                                                                                        0]
[                                                                               -2569496255658063235601118995298115608880492725906081262130343374668068659687383552778218112682613341296900248310780989355131614412322960 -1135023758615815894126524437513022891668024259751630182806622050992906298140981319621419926380873488776139112853608476249678752133179075267713602818637291365395212559394616633/340282366920938463463374607431768211456                                                                                                                                                                                                                        0]
[                                                                                                                                                                                 136143999223146436085508460097629742205                        1279477295944917452736163764530539372838401754918551671693014895273072460317224622035796315759721010075556615772779019675040286213110560900266669591412185/85070591730234615865843651857942052864                                                              13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096]
long_to_bytes(136143999223146436085508460097629742205)
#b'flag{51b72e34bd}'

高职组

未知题目名字

def Linear_Recurrence(a, b, p1, p0):
    def one_round(p0, p1):
        return vector([a * p0 - b * p1, p0])

    def Iteration(msg):
        Ns = N['p0, p1']
        (p0, p1) = Ns._first_ngens(2)
        if msg == 0: 
            return vector([p0, p1])
        half = Iteration(msg // 2)
        full = half(*half)
        if msg % 2 == 0: 
            return full
        else: 
            return one_round(*full)

    return list(Iteration(msg)(p1, p0))

先看一下关键代码吧。不知道从何讲起。是一个递推的过程。具体的话还是自己推导一两组。

这里就很绕

$msg=0b1$的情况

先进入

half = Iteration(msg // 2)

然后返回值是

(p0,p1)

进入下一步判断

if msg % 2 == 0: 
            return full
        else: 
            return one_round(*full)

返回

(a*p0-b*p1,p0)

$msg=0b10$的情况

最终算下来是

(a*(a*p0-b*p1)-b*p0,a*p0-b*p1)

改成矩阵表达

后来就变成矩阵的运算了,这块递推还是自己看比较好。我直接说结论。

下面我们的问题就转成矩阵运算的形式了。

题目只给出了$Iteration(msg)$的第一位,也就是上面矩阵运算结果的第一位

题目给出了四组结果,我把他们放进一个矩阵里面

其中A,B,C,D为已知值

对M进行Jordan形式展开

其中p为变换矩阵,N为Jordan标准型,不知道的话可以搜一下学一学。

A=Matrix([[6,-9],[1,0]])
B=Matrix([[8,-15],[1,0]])
C=Matrix([[10,-21],[1,0]])
D=Matrix([[12,-35],[1,0]])
M=Matrix(Zmod(n),8)
M[:2,:2]=A
M[2:4,2:4]=B
M[4:6,4:6]=C
M[6:8,6:8]=D

pp=[]
for i,j in zip(p1,p0):
    pp.extend([i,j])
P=vector(Zmod(n),pp)
N, p_mat = M.jordan_form(transformation=True)

print('[+] jordan normal for M:')
for i in N:
    print(i)
print()

print(p_mat[0],p_mat[2],p_mat[4],p_mat[6])
p_mat*N*p_mat.inverse()==M
[+] jordan normal for M:
(7, 0, 0, 0, 0, 0, 0, 0)
(0, 7, 0, 0, 0, 0, 0, 0)
(0, 0, 5, 0, 0, 0, 0, 0)
(0, 0, 0, 5, 0, 0, 0, 0)
(0, 0, 0, 0, 3, 1, 0, 0)
(0, 0, 0, 0, 0, 3, 0, 0)
(0, 0, 0, 0, 0, 0, 3, 0)
(0, 0, 0, 0, 0, 0, 0, 3)

(0, 0, 0, 0, 3, 1, 0, 0) (0, 0, 1, 0, 0, 0, 1, 0) (1, 0, 0, 0, 0, 0, 0, 1) (0, 1, 0, 1, 0, 0, 0, 0)
True

Jordan矩阵N的k次方为

这个设个未知数就出来了

然后对于

可以合并成8行1列的向量,其中包含未知数

然后对于结果矩阵R只知道第0,2,4,6次项。所以我只需要取出变换矩阵p的第0,2,4,6行

(0, 0, 0, 0, 3, 1, 0, 0) (0, 0, 1, 0, 0, 0, 1, 0) (1, 0, 0, 0, 0, 0, 0, 1) (0, 1, 0, 1, 0, 0, 0, 0)

所以可以得出四个等式

对于后三个等式可以使用方程组的形式求出$3^k$,然后带入到第一个等式中。

完整exp

n=11804750425314341166655294609956038824495116221943590894858505947410759351607136441144196903190475378440445092747129737540647561067572663758842764663528623
a=[6, 8, 10, 12]
b=[9, 15, 21, 35]
p1=[17027883529565117987, 13551665172578294059, 18081141142904161561, 13275652618816985233]
p0=[18177295635603276407, 9505549336920753997, 17072082071431584061, 16118933928114157831]
result=[6715126204564078483354097016702154195859560615336978179500784599440726731556460786176876281922114292082298209354294249945666601248273278019142982495548499, 4379561838842115509931384332618722657166452997822099791164364587216285794747780604876884600694225090103483422215182991395962186513067282566687397746631208, 11380336831236011142546980046782778043332687939355967888606834900673350834797688518380957032417484667750078206083786031138224320350566812889985447618141458, 526989697864292158597239327808519596353997593440974938523160676683040397918271560686917364053908467826619196125006111568110489627217548695566322373320619]

A=Matrix([[6,-9],[1,0]])
B=Matrix([[8,-15],[1,0]])
C=Matrix([[10,-21],[1,0]])
D=Matrix([[12,-35],[1,0]])
M=Matrix(Zmod(n),8)
M[:2,:2]=A
M[2:4,2:4]=B
M[4:6,4:6]=C
M[6:8,6:8]=D

pp=[]
for i,j in zip(p1,p0):
    pp.extend([i,j])
P=vector(Zmod(n),pp)
N, p_mat = M.jordan_form(transformation=True)

print('[+] jordan normal for G:')
for i in N:
    print(i)
print()

print(p_mat[0],p_mat[2],p_mat[4],p_mat[6])
p_mat*N*p_mat.inverse()==M
# p_mat.inverse()*P

ll=p_mat.inverse()*P
sol=Matrix(Zmod(n),3)
sol[0,0]=ll[6]
sol[0,1]=ll[2]
sol[1,0]=ll[7]
sol[1,2]=ll[0]
sol[2,1]=ll[3]
sol[2,2]=ll[1]
rt=vector(Zmod(n),result[1:])

x_3=(sol.inverse()*rt)[0]
long_to_bytes(ZZ((result[0]-3*x_3*ll[4]+x_3*ll[5])*inverse(ZZ(x_3*ll[5]),n) %n))

#b'flag{b7a5c586-dda1-4cf8-90b2-e912543e09be}\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x18'



  目录