Super Guessers won SECCON CTF 2021, with a clean all-solve. I have repeated in this CTF, i.e. won this CTF two years in a row, last year with a strong union of (mostly) Korean cybersecurity professionals. The writeups from last year is at https://rkm0959.tistory.com/165.

This year, there is no collab, only Super Guesser, which is cool :)

 

Due to some other busy work, I didn't participate fully and solved 3 out of 6 cryptography challenges, and others were done by Baaarkingdog. I also finished one misc challenge, (it was our final solve) but it built on work of many others. (I just finished the challenge)

 

Challenges were very clean and good, and not painfully difficult (this is usually expected from Japan I think, :))

 

Super Guesser's first "major" CTF win (without collab)

 

oOoOoO (by kurenaif)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import signal
from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime
import random
from flag import flag
 
message = b""
for _ in range(128):
    message += b"o" if random.getrandbits(1== 1 else b"O"
 
= getPrime(len(message) * 5)
= bytes_to_long(message) % M
 
print("M =", M)
print('S =', S)
print('MESSAGE =', message.upper().decode("utf-8"))
 
signal.alarm(600)
ans = input('message =').strip().encode()
 
if ans == message:
    print(flag)
else:
    print("🧙")
 
cs

 

Thinking about the effect of each "o" or "O" for the value of bytes_to_long(message), we see that this problem is essentially a subset sum problem over modulo $M$. Indeed, the problem is equivalent to solving the system $$ \sum_{i=0}^{127} [79^k \text{   or   } 111^k] \equiv S \pmod{M}$$ which is same as $$\sum_{i=0}^{127} [79^k \pmod{M} \text{   or   } 111^k \pmod{M}] \equiv S \pmod{M}$$ Since the left hand side is between $0$ and $128M$, we can just solve the following for $0 \le c \le 127$. $$\sum_{i=0}^{127} [79^k \pmod{M} \text{  or   } 111^k \pmod{M}] = (S \pmod{M}) + cM$$ which is now a standard knapsack problem, and can be solved via CJLOSS algorithm.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# https://github.com/jhs7jhs/LLL/tree/master/low-density-attack
 
def inthroot(a, n):
    return a.nth_root(n, truncate_mode=True)[0]
 
class HighDensityException(Exception):
    pass
 
 
class CJLOSSAttack:
 
    def __init__(self, array, target_sum, try_on_high_density=False):
        self.array = array
        self.n = len(self.array)
        self.target_sum = target_sum
        self.density = self._calc_density()
        self.try_on_high_density = try_on_high_density
 
    def _calc_density(self):
        return self.n / log(max(self.array), 2)
 
    def _check_ans(self, ans):
        calc_sum = sum(map(lambda x: x[0* x[1], zip(self.array, ans)))
        return self.target_sum == calc_sum
 
    def solve(self):
        if self.density >= 0.9408 and not self.try_on_high_density:
            raise HighDensityException()
 
        # 1. Initialize Lattice
        L = Matrix(ZZ, self.n + 1self.n + 1)
        N = inthroot(Integer(self.n), 2// 2
        for i in range(self.n + 1):
            for j in range(self.n + 1):
                if j == self.n and i < self.n:
                    L[i, j] = 2 * N * self.array[i]
                elif j == self.n:
                    L[i, j] = 2 * N * self.target_sum
                elif i == j:
                    L[i, j] = 2
                elif i == self.n:
                    L[i, j] = 1
                else:
                    L[i, j] = 0
 
        # 2. LLL!
        B = L.LLL()
 
        # 3. Find answer
        for i in range(self.n + 1):
            if B[i, self.n] != 0:
                continue
 
            if all(v == -1 or v == 1 for v in B[i][:self.n]):
                ans = [ (-B[i, j] + 1// 2 for j in range(self.n)]
                if self._check_ans(ans):
                    return ans
 
        # Failed to find answer
        return None
 
conn = remote('oooooo.quals.seccon.jp'8000)
 
REMOTE = True
 
if REMOTE:
    M = int(conn.recvline().split()[-1])
    S = int(conn.recvline().split()[-1])
    conn.recvline()
else:
    message = b""
    for _ in range(128):
        message += b"o" if rand.getrandbits(1== 1 else b"O"
    print(message)
 
    M = getPrime(len(message) * 5)
    S = bytes_to_long(message) % M
 
base = 0
for i in range(128):
    base += 79 * (256 ** i)
 
 
sums = ((S - base) * inverse(32, M)) % M
 
arr = [(256 ** i) % M for i in range(128)]
target_sum = sums
 
st = time.time()
 
for i in tqdm(range(128)):
    attack = CJLOSSAttack(arr, target_sum + i * M, True)
    res = attack.solve()
    if res != None:
        msg = ""
        for i in range(128):
            if res[i] == 0:
                msg += "O"
            else:
                msg += "o"
        msg = msg[::-1]
        conn.sendline(msg.encode())
        print(conn.recvline())
 
 
en = time.time()
 
print(en - st)
 
cs

 

XXX (by theoremoon)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import os
 
flag = os.getenv("FLAG""fake{fakeflag_blahblah}")
= int.from_bytes(flag.encode(), "big")
 
= random_prime(1 << int(x.bit_length() * 2.5))
Fp = GF(p)
 
params = []
while len(params) != 6:
    try:
        y = randint(2, x)
        a = randint(2, p-1)
        b = (y^2 - (x^3 + a*x)) % p
 
        EC = EllipticCurve(Fp, [a, b])
        EC(x, y)
 
        params.append([a, b])
    except ValueError:
        pass
 
print(p)
print(params)
 
cs

 

We have 796 bit prime $p$ and around 320 bit $x$, which is the flag.

We are given 6 parameters $(a_i, b_i)$ such that $y_i^2 \equiv x^3 + a_ix + b_i \pmod{p}$ and $y_i < x$. 

 

Subtracting, we see that $$(a_1 - a_j)x + (b_1 - b_j) \equiv y_1^2 - y_j^2 \pmod{p}$$ so $$-2^{640} < (a_1 - a_j) x + (b_1 - b_j) \pmod{p} < 2^{640}$$ which can be rewritten as $$ -2^{640} < (a_1 - a_j) x + (b_1 - b_j) + p c_j< 2^{640}$$ for $2 \le j \le 6$. Since we know all $a_j, b_j$ values, the only unknown is $x$ and $c_j$ values, and this can be plugged in my CVP repository. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 
# Directly taken from rbtree's LLL repository
# From https://oddcoder.com/LOL-34c3/, https://hackmd.io/@hakatashi/B1OM7HFVI
def Babai_CVP(mat, target):
    M = IntegerLattice(mat, lll_reduce=True).reduced_basis
    G = M.gram_schmidt()[0]
    diff = target
    for i in reversed(range(G.nrows())):
        diff -=  M[i] * ((diff * G[i]) / (G[i] * G[i])).round()
    return target - diff
 
 
def solve(mat, lb, ub, weight = None):
    num_var  = mat.nrows()
    num_ineq = mat.ncols()
 
    max_element = 0 
    for i in range(num_var):
        for j in range(num_ineq):
            max_element = max(max_element, abs(mat[i, j]))
 
    if weight == None:
        weight = num_ineq * max_element
 
    # sanity checker
    if len(lb) != num_ineq:
        print("Fail: len(lb) != num_ineq")
        return
 
    if len(ub) != num_ineq:
        print("Fail: len(ub) != num_ineq")
        return
 
    for i in range(num_ineq):
        if lb[i] > ub[i]:
            print("Fail: lb[i] > ub[i] at index", i)
            return
 
        # heuristic for number of solutions
    DET = 0
 
    if num_var == num_ineq:
        DET = abs(mat.det())
        num_sol = 1
        for i in range(num_ineq):
            num_sol *= (ub[i] - lb[i])
        if DET == 0:
            print("Zero Determinant")
        else:
            num_sol //= DET
            # + 1 added in for the sake of not making it zero...
            print("Expected Number of Solutions : ", num_sol + 1)
 
    # scaling process begins
    max_diff = max([ub[i] - lb[i] for i in range(num_ineq)])
    applied_weights = []
 
    for i in range(num_ineq):
        ineq_weight = weight if lb[i] == ub[i] else max_diff // (ub[i] - lb[i])
        applied_weights.append(ineq_weight)
        for j in range(num_var):
            mat[j, i] *= ineq_weight
        lb[i] *= ineq_weight
        ub[i] *= ineq_weight
 
    # Solve CVP
    target = vector([(lb[i] + ub[i]) // 2 for i in range(num_ineq)])
    result = Babai_CVP(mat, target)
 
    for i in range(num_ineq):
        if (lb[i] <= result[i] <= ub[i]) == False:
            print("Fail : inequality does not hold after solving")
            break
    
        # recover x
    fin = None
 
    if DET != 0:
        mat = mat.transpose()
        fin = mat.solve_right(result)
    
    ## recover your result
    return result, applied_weights, fin
 
 
= 238351830708404244219528012300346183698089704036958197073088590986781126046128139277876261847918986388464392075919752504036124478387675086320279831883061575773130731731512289308600548817918823754759741014480607490178191084213685771095081699
params = [[6172144681482249919102241290221732015313763389738784671051231003933641047772826421768174589186320089337803458199766489452275665899287350169335342506340065510519410797024900969144263201542965830579229871404323577793409021234362593354092041938215859743437160276358618194105173963536621422404142018824002222927344371846641995139103441786202367296704680389815780441043250270096100089370169391316241550354639472704197195039115443263083720157181161573037786722518518073244876576521645], [193846031065431615171138398907554474490243593010426445660159995023421690918389029501570918601414789147460375901577546434319012002193067152560178159337882412597981169953017381602553449608161376011387225337945790490301205500988070592667260307182624605832152240064165962388331595893516884552600324435147374044032575325900262356701606616541732441503871912325334315545721127713601115727804588364391211951651086408749934094159068720206922998283686393892033283362379079277585875317733125], [186116431294956584507622251083552464237708766317037184701883695099192545170797758914491959325056548294443112027689221562090922906211642613451222485059412249593287539268632182815867453113262026976033832305075048778306269837158521655897206104188291640755725711120730552161550568363878329035151394705358843149734090074525252662747799270008290175006002913694732659518178709233238519205580102532883270488509830279127451754878651121923932212399426641171488518541036604555898762653636767], [14769073770419338092925604251635464259163431252809312886992348718499763226318266949132454879939477850734192522871509505316678708215807987680150864086317446037666757885739819377613473418465497679258575389782360217355021067881102634318063257490919616852165947744756990575400745193091744707583913218090901120971522401412921713920030755420236486444344985420141669115268509030823280811858196495296299291522098961629224878356500400137160049480897176934761512803911650692781199738944358], [147919066213305504909474311411803269104114976277480371373734903513860210330631554119249090143860674441819199276919740940095535099825251133312941478015230935296046855247122689436697731644543102898280018067875178726421332069314230553359546674233189046301154960459915044289449599538936202863814191691219472024725663885482828960872087873090796952667099967198895490748125927000604303160065032535117589864975437392352615652017307656160862671237257143553966268386859872891179982158931538], [13745031646212926887771103525076366898061855140367447627348094520569424589936962364608246820234169073983776241922164875922628393545929977925429649776620225617026636689097094088686938946433246454600348030574125595670238566611181688648849700242626852637723346847761898432034196330200006970228231831316278507491404141071325164359383210554480496801017672657717855189744860778897395023272448045289999028710960807199386287807443723368642574520040320693565244086076826717435666078357317]]
 
# x 320 bit
 
# a1x + b1 + x^3 == y1^2 (mod p)
 
= Matrix(ZZ, 66)
lb = [0* 6
ub = [0* 6
for i in range(16):
    dif_a = (params[0][0- params[i][0]) % p 
    dif_b = (params[0][1- params[i][1]) % p 
    # -2^640 <= dif_a * x + dif_b <= 2^640 mod p
    M[0, i - 1= dif_a 
    M[i, i - 1= p
    lb[i - 1= - (1 << 640- dif_b
    ub[i - 1= (1 << 640- dif_b
M[05= 1
lb[5= 0
ub[5= 1 << 320
 
result, applied_weights, fin = solve(M, lb, ub)
 
= int(fin[0] % p)
 
 
print(long_to_bytes(x))
cs

 

Sign Wars

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Util.Padding import pad
import random
from secret import msg1, msg2, flag
 
flag = pad(flag, 96)
flag1 = flag[:48]
flag2 = flag[48:]
 
# P-384 Curve
= 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319
= -3
= 27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575
curve = EllipticCurve(GF(p), [a, b])
order = 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643
Z_n = GF(order)
gx = 26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087
gy = 8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871
= curve(gx, gy)
 
for b in msg1:
    assert b >= 0x20 and b <= 0x7f
z1 = bytes_to_long(msg1)
assert z1 < 2^128
 
for b in msg2:
    assert b >= 0x20 and b <= 0x7f
z2 = bytes_to_long(msg2)
assert z2 < 2^384
 
# prequel trilogy
def sign_prequel():
    d = bytes_to_long(flag1)
    sigs = []
    for _ in range(80):
        # normal ECDSA. all bits of k are unknown.
        k1 = random.getrandbits(128)
        k2 = z1
        k3 = random.getrandbits(128)
        k = (k3 << 256+ (k2 << 128+ k1
        kG = k*G
        r, _ = kG.xy()
        r = Z_n(r)
        k = Z_n(k)
        s = (z1 + r*d) / k
        sigs.append((r,s))
 
    return sigs
 
# original trilogy
def sign_original():
    d = bytes_to_long(flag2)
    sigs = []
    for _ in range(3):
        # normal ECDSA
        k = random.getrandbits(384)
        kG = k*G
        r, _ = kG.xy()
        r = Z_n(r)
        k = Z_n(k)
        s = (z2 + r*d) / k
        sigs.append((r,s))
 
    return sigs
 
 
def sign():
    sigs1 = sign_prequel()
    print(sigs1)
    sigs2 = sign_original()
    print(sigs2)
 
 
if __name__ == "__main__":
    sign()
cs

 

There are two mistakes - one is the insecure random of "prequel" which fixes the middle 128 bits, and the insecure python random which is used in the "original". The natural plan is to attack the "prequel" first using the insecure random via standard LLL, find the python random seed using some library, then directly find the random $k$ values for the "original". The latter part can be done very easily with some libraries, so we'll focus on the first one. We write the system as follows. For each 60 equations, we have $$ks \equiv z_1 + rd \pmod{n}$$ $$k \equiv s^{-1}z_1 + rs^{-1}d \pmod{n}$$ $$k_1 + z_1 \cdot 2^{128} + k_3 \cdot 2^{256} \equiv s^{-1}z_1 + rs^{-1}d \pmod{n}$$ $$ 0 \le k_1 = z_1(s^{-1} - 2^{128}) + rs^{-1}d - k_3 \cdot 2^{256} \pmod{n} < 2^{128}$$ $$0 \le z_1(s^{-1} - 2^{128}) + rs^{-1}d - k_3 \cdot 2^{256} + cn < 2^{128}$$ and now this can be plugged in CVP repository. Note that $d, z_1$ is fixed and $0 \le z_1 < 2^{128}$, $0 \le k_3 < 2^{128}$. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# Directly taken from rbtree's LLL repository
# From https://oddcoder.com/LOL-34c3/, https://hackmd.io/@hakatashi/B1OM7HFVI
def Babai_CVP(mat, target):
    M = IntegerLattice(mat, lll_reduce=True).reduced_basis
    G = M.gram_schmidt()[0]
    diff = target
    for i in reversed(range(G.nrows())):
        diff -=  M[i] * ((diff * G[i]) / (G[i] * G[i])).round()
    return target - diff
 
 
def solve(mat, lb, ub, weight = None):
    num_var  = mat.nrows()
    num_ineq = mat.ncols()
 
    max_element = 0 
    for i in range(num_var):
        for j in range(num_ineq):
            max_element = max(max_element, abs(mat[i, j]))
 
    if weight == None:
        weight = num_ineq * max_element
 
    # sanity checker
    if len(lb) != num_ineq:
        print("Fail: len(lb) != num_ineq")
        return
 
    if len(ub) != num_ineq:
        print("Fail: len(ub) != num_ineq")
        return
 
    for i in range(num_ineq):
        if lb[i] > ub[i]:
            print("Fail: lb[i] > ub[i] at index", i)
            return
 
        # heuristic for number of solutions
    DET = 0
 
    if num_var == num_ineq:
        DET = abs(mat.det())
        num_sol = 1
        for i in range(num_ineq):
            num_sol *= (ub[i] - lb[i])
        if DET == 0:
            print("Zero Determinant")
        else:
            num_sol //= DET
            # + 1 added in for the sake of not making it zero...
            print("Expected Number of Solutions : ", num_sol + 1)
 
    # scaling process begins
    max_diff = max([ub[i] - lb[i] for i in range(num_ineq)])
    applied_weights = []
 
    for i in range(num_ineq):
        ineq_weight = weight if lb[i] == ub[i] else max_diff // (ub[i] - lb[i])
        applied_weights.append(ineq_weight)
        for j in range(num_var):
            mat[j, i] *= ineq_weight
        lb[i] *= ineq_weight
        ub[i] *= ineq_weight
 
    # Solve CVP
    target = vector([(lb[i] + ub[i]) // 2 for i in range(num_ineq)])
    result = Babai_CVP(mat, target)
 
    for i in range(num_ineq):
        if (lb[i] <= result[i] <= ub[i]) == False:
            print("Fail : inequality does not hold after solving")
            break
    
        # recover x
    fin = None
 
    if DET != 0:
        mat = mat.transpose()
        fin = mat.solve_right(result)
    
    ## recover your result
    return result, applied_weights, fin
 
 
SIG1 = [(1212292064485743641866810867743144682151196516183590625761968617000822398163361711884853686433325688334478380747253314197268540776373741177673820089672023976732299858030846681305575389640921071188098294211283607291412628404706330635), (3002331126369368291669211963190479316181270425867006372504694602838148258650845274496999419158657648115996903989253516094000621518284822857020964974522983541224425681758135622160784082988267314022122458996489586892811938506732931748), (2027436533308764899209991485588745242726572506223476812115075621073491828230532459470909544094168000667447224998016826128948049631412381227970242480771408976962602375493955244402440727109476811862753343673422200707132102306861245065), (3076893909789462689537867740132457904172072881005206061617971217925492418613994039174521463508662170009245184625747523800973758418165064781275855199658315920145808589994209139192398347876290686870300287776343940629270010735723235385), (2847355782808806197939919647313647140258504760030314269534116364072965213070704395225589990776667615259753928962831528281625820520087035698954279133768588017050298800453267610958044101108252535161164763310762642756504428205563108030), (96111825038591776450760042051057221784840677440291925480707472994358019963419494393692853436993737162471073272685724031640471683802687061395705285266808842836983869848057857017127967668008272515010890509063551366550912420338902834), (193704946542352674542172177198907607324796334433313936905604761181111396829425135645725050926896072261932019897785752433781820944268337733283393291854175920938847482642777771696759267025446311242119383222969981818996711424713151752), (307790900438940328306052761758840429759948115164727557952163123828463556821686922966788802561970338213900449971474204893123418105561169402880287889300261310663472852291300562230045024356786173678817075957809203454759484532173136896), (1464370548997752878897005811756682877124929822582596291265520815978167357819329848489020002088547358328003754411957815935318488540400173648065087608623889419958306790544362968141852933585912044021990423536612481693468915965522445032), (261908477352543630034369756839067144196954528182274466642195566095248516871821600329131886625745213584731645212703181593531527201615623099098664942415943763347197253061444470827851943278116759392933621884906245655648264221554908273), (244498345810376316933877032372457940911578208767321728981050083872632198400389747370780151731837653925273160063435431519693975000372684536588360058886155393128374920715958105917368560178529829092541542334254564649031015390295526257), (553920294437904104764581573061957085591570061092174719886601499700728562281038469677765861165835479046619855640953820332957999843652613921660609152489318731466697459198872422541589848932160246010821103577261742306246402279741839395), (2996950493431261609277357721529305432786841213159568790816413323738922899176436266168900833024446316706737741780484823502790732595477415220062415069646202303453814634558339724957279860279173977141614843448086419994681526804050994011), (2866309924603819281627357046605310388033016195472503936421539771359173108420891910940478811543983832370505735490618332343362746546345028906807296090845637927648209201182279186066312617262402540993950717856425293636562311369826695241), (378114259668423403838212284029259514249288410739437126706868292460127326345327782068294403487987383609968291779346591512161086988707363568355555539355341485927942150807857139424735463213909258176919376930783632168090029799006962452), (677901939648733525017637617731648094056289750593529294758683896640584732639268336931042233126755630495021338556240321277628400501469478914168423023057684740585069176201105893608414023541256985765180901007757435611069875893412465586), (636694892605787225107332472471564669770939624410753441199699960451848432552294141764316468048178132765012151216158931835229197999276237723592037000880402276309404799202930304320555417861589116989270114086456362377584676026798317441), (152818457096074919203698138170133773621782557087026415545348924733684101916414879995060019242876149835575543884447902984115935788221541188290047888309109458147722093547866020985007410124451071701982135991689832422756636714734848410), (172613279506093800325054154137293455068375634778023351042619031999452920462863719097645276055378442507655204604208834414083024903566067346682354660036193755195663970474589205389345245255956774402052618861533800845720100684618788066), (2328521732655547501651955233090556838292397748945623745673249625390335023352847210089094722639360957209791596959958015864787645844524123645508552473833769050437498168559566442342764983309617043514215685980718642756051823094216138112), (387356135022076175434607989020899241170301101569048454924178898854529262315094126774573646627288266038701660890487832764799580566369130997255183073579096790304637375189258729225097121531798414933779603126159724061297478107963529944), (3439768646893390838671339859311719924747740853531006387248636420575889348156707615668515812299276564466486362040844132278070177934959080616216483052122171696315094028362684579162316990518944414668141213923548802330689237360305444057), (3688859614458031007666698255437975472757969314115795303982176324632059662400207607269437636034932760515162846193834420359599307803961599163637268447617008934461534173375543520973121462531279483793982707344429872033956688432496029494), (3573194536916502452706770842219093445311442693018914717166267706112448891200948713883172559660776903622367743125439438690463610329621441610277699868091296837875356478232771729649752351130839647804626642276143604085382240751091874980), (236776286341767235699403224625642009904348835636195582608287332474315798724372682892287196602724577545774326476292675694960089075991074464290708570332306998548315951489339220678741537951501152608587055469175810163056202380723484162), (3618330448423424686611091144916753775437233330942711484414738761882902453023199118960515811334820410984598035269646523965168344478037213105641624609514777278543321778037076016154890855496855531577133265749426868642365368798849451496), (3316297858119841597499909163777521901560984347888598143136540562737698614996449339035299643290243139821499045312070017522675770165519045405383886383499046920674272323023864859028070652034097791735019059447013185908178315975726718027), (3797752428753162173126965299851844403922178856100108468144637454368058245552900666707418196583128355677060102640641234014871750340380154692206012455554620218508761966344769331999972401940089831171697348255247018267326994810496665301), (15070137818594125814602299680168716864720001627224208532926723995952135882468975785406193478565358933576272709006777123198841569413454577310078272821534024280579100722414329202844057424863366193509058084349838170744321137899380851), (1616209832575520722906318999738339661192172523554486744307112693676812049600710017408701070879398678850193345653111735843125491563878831891747420494968566047358046579202101829199006631647636438358745741154644883785641557638179703196), (2714624658766719074007669846248032735233487204263703568649913383050542492130961879573264962344316643215748544120651329374852723618836996041990307719900335299612538156861129617267376582701400599574166091116228943846822827095705431420), (2031887359655925951105553114750638254032803910121163261793989360723014699277075536635754700415444012387792727956280521880244506505391597381900288791130929029500377960791610120410522262499720103003893165761379437860585723438454338357), (267708967921714471467723506064221112349826158934345364358708998025826767081005447171738069513040067776571894275071522811216118007709181671732510261424038689262085998138698823325592895788252084744051591190795979078528619437443272430), (2824226101206804127729354011029195186496860624375536228507282831715890883481128954379854056784897518550299421561161928337300861435742639020944587343125537033416178222051556584188414720653042082343068603170738957875834942311839398955), (2131378456624223628855820954039872835845010251807303397097435508524925064368177992255282354126562018570257561286512325973923581441774490467725510310356393118571760442289368631380634139185801852675014798484820655377425355874214608838), (39722474743387833224678753149279354828125762583247646588654751770915751868505197607364770688632870112536579796950351949243324150001215851803463575673078965313534368782887187770074096642168523503805499517384914614086023503127806847), (115194448773603655564094606533709336622035330188807646579676513003777897190496227493293488796641999820017536599578119564575441055199178132952897543045993451659948447588920651596150288550414960098453945167530353880987093029030638144), (3416233573439755709122849411177744941965931436413058574520291377382841999255954246519615715461858669239342434713678534816069361672535828713924897177961374080352312052306803897119805834580104455380505473277752161016451540002438069017), (621442051897740072011504091560693618933245764995402972270318562754278315343982217293879434014128069432869786099715135036609860976357406366810820445499231048373436931375253989834911997779342195269560660560149275988782146654615055395), (1793229684848547602830782936490072235066462210306743437688048246566077688411802761589482483406252097456295069619080025284454559391441356742861992714899157880349238554132025565451660342323497911181209889041052025003714876311648649308), (1672983856235947547421295836318356042025055970229101636452105150045002610339544319863045647610397094375366915424937532346909821898954875794104426207252965578694675212598600013619876939291316966520281348030524571180602992351937324549), (1838335752460076020201947769646276640856482938963220109271139275282297520072533901119178546917432459081163275750147036650204800420829652120261290123142229312040551658496656556239024215868372978503733453573308931372634821353503537954), (1267947432684618422596552802472654776850669055037987540244270059247718762503256634328288601539397329945397034771666631594434445787142355786158780673084733603186104893515951267587710628733125154787164728421585888101421671404571441460), (146015594617351346560500075300694393947381598003145417763267986145592871411838029880690182364472506375674344047832328595065903087426074566358753005915622433302916683368431103530322432724436087166807363512661383021500064699866636573), (171219169781254557814920575829446416011205889460892358356872461647126631567728984914233721594078451888096342939412315549321728923260877275319522523938368845573355479005888471636555747793775030205015093656278438688710952666664504896), (2724785056791392598269506783449151810158471437975870332538482625008481033885087305490317376868290988631522482015184318441987213600418235028717811172592400392968984874201495657937932256496057636260779718506455774046512049959224326533), (23125206105423712170494578086460408200155706950388584751758217770641881139847092343076320949651253557057860975699290617384558916714490913646402391877958626488085682864653677413549966260928717156654411337297014822767990795093863229), (103098597960845130869494743257457422899436526011640422957987492160138167492624069785276585061696310414321820344832643401470346181096624340649421457463749621102267436616681750603386976006189520143441710738979453350404845158395485486), (1636860910560199651212365750398397690181484613558547655291446641497917517958172377882377381090433513698860734338864112887327683770298631686858909410191002874101297863064763857850276211374735131663350575035482893318627486961140493060), (1259778308671278095582910251132597733955648031445631722608405942785297574441029840046657036973972985982268209474376318143629657739573817392351951162537846408025200449845703036545707816887229856135678162116712273281752461460773286157), (181497652032123650959223655414295958041151106384607975572474256632780650577616836949634350743060831465597489108209334623808735710466757897562443056494514986872251154643072124080945722371896930429940197336707416267350592331887509370), (3668577048929245086282985467342228128865995944346814445191804275310152215812194274062839605387614408790355690267045925427602196870003078247382997147130945403862270376348600679340464766087619183853473530884327535652383782148396318369), (2640099493588732368581278558877977760480703381845978438337933663672301604198913135581370935062115063860033739774575535441443644761879722810537983899640132591168390041946180094287752185744760148684344825560100034902852843703022913572), (2154946432228594948797406083929041431729108558047064441317560370365981159968680212853966538770749257512095299097416927426668476821276280862019979056999027369355304092859933896625743859680072036382523929860072977660288769061968841056), (1794505527014900467217440720010118642673301918855722262937438722916632125324813145594458295825885108668099232771777522763432714358352994467634787642451136567944768237186044385733037319457391071748311079692136983455628393624590912773), (1967937289800612864029158307717895143560424896053727268895238506843456393322683635877770661953097591892621145409325422558450199634522395989325930989798822306499440080795289426594476903491433232767149595712438138190142613146382805102), (505380800262261364869601601223519645321339476508954599347253392076265929087900023828440114237356661035975433450311925596265678131212259962460250737224350948937567171043241527736952385125964273084970352617767438577469728391374901104), (3502153594287647766462032319356908461277726659055111072994486704513978796124659803484760711945128263317322062761752824412900363309066203864154425415165066253353692376637520978763141267068333052991517573772819303004361631432100082761), (3038234415731701452117435993859519959031310137653289407796165597610284966699441298697775752670090357383797905056974836380054077835016119489703494179753668737802402599719907220000486624011084909818429478518718710302969894134810399414), (2339245531992437462440736321841401779272634163734815428936800191955309263153942372205612803502876195576125133523139724615969593765671009089175669046441351199855489516238368580612855661905474214253402259306074086838224100682009493110), (3904341008757165884977708872364484044477311247177295807558959581723664973232536113835726847119004889089092233017311324256166337102519478716198099822063504670413826816008063467295625641151486658627000887001654580846329391802379723304), (2519830924627601748312116334886559763064353240349381571587812659439381477901293750286255788919229511082147599152994331183736084868762605705341491981967451872193027043779034558377529784073696083378450370565887268611112401715464692322), (2149037099356302626497177599318246090521586923604767030421053570689481292891440797123499582150073080022303159826625730524538483293986209920139400952501355824771895617776073345360374702907548949007510552008565834914052456239691889902), (3736667361485077644469293932842173238852712369528681943796665561567540806936691086003507420402931879994590306404852717779215295739572760353458898043288811931339150166396214780752407992014275252723707803456409767620788479105600423376), (2388090713503838916880304675690146821420618916811705890655376883071253310267087711720336146802197143926484764308755936554798683087533081747521419888907675190192122029480300791517998074362122003489313160167552894436296245959628579534), (183981661779079639387767912912968952669274419578484331391801939427668777469255908242641065097011520406512451674019233280887100325540541044876347841631022975706016854603366960877001893277240119020663116400162762880357011028194015505), (378602385328785333142378817099918031446407205321592112598026536762336804397948090519557882906177242918963142284842872079530852252634619529204167324028013909690544367420298080750988365566999876311319237386168370876748621061304030325), (3307640129491042686640872589818551735379708971463163808590465406374118577023940782710267496689773835256884585279546132388782563029207071708238813265723145823101733798639269010838632868478704546695027802504168693070745244529700498871), (1966463041699590703926849934097114735454390699131647125733097337039928918020271617918472617633399750183304700844518815010332454096306874561434765152776137424843532232617982537812287828972466131420109345949260515569323587248864746943), (2587176937268537056992582242569382062061979459821447412360051125377818579696217207320820676281874530960554073910062112733332659612677892428319839726866498876500931386736309794894873372522229292842342178191364595143966422220824826073), (1276904545508489427343652715920481690243230564401721062929678793390429578528145744888104492940203839949694018904409311594689177180251431669445510565369712938818714831055440921516382728285369019679675944135089038247905820859659761517), (18657037708713137541950069000132078455625422456750701136984818700887232362463902027994904894720793772683543062426685125550573798542551697831171912361478992101952449490976854228951650529010822626202419835861052330070344633285976669), (370966626123274631489373371713944830397209082379966421574334705675684440607390729046710166014044405337048339195442854790007747398249736115034551686542360219836448905259482276520130644298771477774260329772071196479778643314968168876), (3117063074102807746766611769092212404639773273117300156591107891113289141031890343503907441813066092229217502848516136700267333965429842826985729957565986107482356086995641315664499740118242353501066703906197210995388334971341587044), (1642930556201007004591800850299567490493201931007187276638908917493617383284743147011041715760020584091096765469510513348678473612360711357762565221644167552517488898971900250507563637477504294039445796012121832852740292220571524010), (3681499962041062465040892759310110231183228860120021277252122028074737326840783816265376983312234213819385088847931621678377395564601107395386759737337329969405189315349034054067649380849056748928922052454754064625128419150919292053), (3708020466257981141972392525055381134311806280072102034785099044237748654993241809030317925240319853932251969444427615821341762768738218228176979267566826815656142437698746345759451195866137662375460664107143767858376489559348158119), (3190066521280779465306789205099108778717473987911260315727051572260101623236197633724827993183204124475783778902246111910037530034363325480855721128870881334951395240192762039726365170413466292618778748338552446589898886095541743053), (2271323493844614485303993512171373489107410793204360295734590409512840709130302883041863022486935932227606732222822037648033797699949313050109414984677478246381964295991074283362304879984221990727828373537248000765921622593274507531), (2696664222772104507144272464548466151936888957673831175606787628766631988315697294538210447335182266903691930441183033837552398136675647634120649336283866568054003022435569393484219100126804419072284913749466938666527692475735307495)]
SIG2 = [(104963988302970955749741680788544895088752286692167192845029255333318850946725031160235419175838141287024316530813834790284668131148498252310249426530965492667679223859021102993403672099203069041205214172414075756555276490789178956), (308521846705189220600241790186572857639357745133877020761812926227235071874727796803161402053138330175335887593661335069145156217342955289020258826302551823920792084376060949622353808056721610402437441970841628302496074418474626297), (240949052653375342761658280478597822389874312193038832185544802972978616688479225589286171599738119436498444684450209328776074819457901331657355801560516363178058099225535915537394781684440774078985119798155365962514386879323530606)]
 
 
= 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319
= -3
= 27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575
curve = EllipticCurve(GF(p), [a, b])
= 39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643
Z_n = GF(n)
gx = 26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087
gy = 8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871
= curve(gx, gy)
 
# ks == z1 + r * d mod n
# (k1 + z1 * 2^128 + k3 * 2^256)s == z1 + r * d mod n
# k1 + z1 * 2^128 + k3 * 2^256 == s^-1 (z1 + r * d) mod n
# k1 + z1 * (2^128 - s^-1) + k3 * 2^256 - s^-1 r d == 0 mod n
# -2^128 <= z1 * (2^128 - s^-1) + k3 * 2^256 - s^-1 r d mod n <= 0
 
num_sig = 20
= Matrix(ZZ, 2 * num_sig + 22 * num_sig + 2)
lb = [0* (2 * num_sig + 2)
ub = [0* (2 * num_sig + 2)
 
for i in range(num_sig):
    r, s = SIG1[i]
    M[0, i] = ((1 << 128- inverse(s, n)) % n 
    M[1, i] = (- r * inverse(s, n)) % n 
    M[2 + i, i] = 1 << 256
    M[2 + num_sig + i, i] = n 
    lb[i] = - (1 << 128)
    ub[i] = - 1
 
for i in range(num_sig):
    M[2 + i, num_sig + i] = 1
    lb[num_sig + i] = 1
    ub[num_sig + i] = 1 << 128
 
M[02 * num_sig] = 1
lb[2 * num_sig] = 1
ub[2 * num_sig] = 1 << 128
 
M[12 * num_sig + 1= 1
lb[2 * num_sig + 1= 1
ub[2 * num_sig + 1= n 
 
result, applied_weights, fin = solve(M, lb, ub)
flag1 = long_to_bytes(int(fin[1] % n))
z1 = int(fin[0] % n)
= int(fin[1] % n)
 
predictor = MT19937Predictor()
 
for i in range(80):
    r, s = SIG1[i]
    k = ((z1 + r * d) * inverse(s, n)) % n
    k1 = k & ((1 << 128- 1)
    predictor.setrandbits(k1, 128)
    k3 = k >> 256
    predictor.setrandbits(k3, 128)
 
ks = []
for i in range(3):
    ks.append(predictor.getrandbits(384))
 
d2 = ((ks[1* SIG2[1][1- ks[0* SIG2[0][1]) * inverse(SIG2[1][0- SIG2[0][0], n)) % n 
 
flag2 = long_to_bytes(int(d2))
 
print(flag1 + flag2)
cs

'CTF' 카테고리의 다른 글

CODEGATE 2022 Preliminary : Prime-Generator  (0) 2022.02.28
CODEGATE 2022 Preliminary : Dark Arts  (0) 2022.02.28
N1CTF 2021 Writeups  (1) 2021.11.22
PBCTF 2021 Writeups  (0) 2021.10.13
TSGCTF 2021 Writeups  (0) 2021.10.03