Skip to content

Commit 3a6e416

Browse files
committed
Participate DiceCTF 2021
1 parent b0c0ddf commit 3a6e416

25 files changed

+75865
-0
lines changed

Diff for: DiceCTF/2021/garbled/block_cipher.py

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
SBoxes = [[15, 1, 7, 0, 9, 6, 2, 14, 11, 8, 5, 3, 12, 13, 4, 10], [3, 7, 8, 9, 11, 0, 15, 13, 4, 1, 10, 2, 14, 6, 12, 5], [4, 12, 9, 8, 5, 13, 11, 7, 6, 3, 10, 14, 15, 1, 2, 0], [2, 4, 10, 5, 7, 13, 1, 15, 0, 11, 3, 12, 14, 9, 8, 6], [3, 8, 0, 2, 13, 14, 5, 11, 9, 1, 7, 12, 4, 6, 10, 15], [14, 12, 7, 0, 11, 4, 13, 15, 10, 3, 8, 9, 2, 6, 1, 5]]
2+
3+
SInvBoxes = [[3, 1, 6, 11, 14, 10, 5, 2, 9, 4, 15, 8, 12, 13, 7, 0], [5, 9, 11, 0, 8, 15, 13, 1, 2, 3, 10, 4, 14, 7, 12, 6], [15, 13, 14, 9, 0, 4, 8, 7, 3, 2, 10, 6, 1, 5, 11, 12], [8, 6, 0, 10, 1, 3, 15, 4, 14, 13, 2, 9, 11, 5, 12, 7], [2, 9, 3, 0, 12, 6, 13, 10, 1, 8, 14, 7, 11, 4, 5, 15], [3, 14, 12, 9, 5, 15, 13, 2, 10, 11, 8, 4, 1, 6, 0, 7]]
4+
5+
def S(block, SBoxes):
6+
output = 0
7+
for i in range(0, len(SBoxes)):
8+
output |= SBoxes[i][(block >> 4*i) & 0b1111] << 4*i
9+
10+
return output
11+
12+
13+
PBox = [13, 3, 15, 23, 6, 5, 22, 21, 19, 1, 18, 17, 20, 10, 7, 8, 12, 2, 16, 9, 14, 0, 11, 4]
14+
PInvBox = [21, 9, 17, 1, 23, 5, 4, 14, 15, 19, 13, 22, 16, 0, 20, 2, 18, 11, 10, 8, 12, 7, 6, 3]
15+
16+
def permute(block, pbox):
17+
output = 0
18+
for i in range(24):
19+
bit = (block >> pbox[i]) & 1
20+
output |= (bit << i)
21+
return output
22+
23+
def encrypt_data(block, key):
24+
25+
for j in range(0, 3):
26+
block ^= key
27+
block = S(block, SBoxes)
28+
block = permute(block, PBox)
29+
30+
block ^= key
31+
32+
return block
33+
34+
35+
def decrypt_data(block, key):
36+
37+
block ^= key
38+
39+
for j in range(0, 3):
40+
block = permute(block, PInvBox)
41+
block = S(block, SInvBoxes)
42+
block ^= key
43+
44+
return block
45+
46+
47+
def encrypt(data, key1, key2):
48+
encrypted = encrypt_data(data, key1)
49+
encrypted = encrypt_data(encrypted, key2)
50+
return encrypted
51+
52+
53+
def decrypt(data, key1, key2):
54+
decrypted = decrypt_data(data, key2)
55+
decrypted = decrypt_data(decrypted, key1)
56+
return decrypted
57+

Diff for: DiceCTF/2021/garbled/circuit.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"inputs" : [1, 2, 3, 4],
3+
"outputs" : [7],
4+
"gates" : [
5+
{"id" : 5, "type" : "AND", "in" : [1, 2]},
6+
{"id" : 6, "type" : "AND", "in" : [3, 4]},
7+
{"id" : 7, "type" : "AND", "in" : [5, 6]}
8+
]
9+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
This file is provided as an example of how to load the garbled circuit
3+
and evaluate it with input key labels.
4+
5+
Note: the ACTUAL `g_tables` for this challenge are in `public_data.py`, and are not used in this example.
6+
7+
It will error if the provided inputs are not valid label keys,
8+
ie do not match either of the `keys` made by `generate_garbled_circuit.py`
9+
"""
10+
11+
import json
12+
13+
from yao import evaluate_circuit
14+
from generate_garbled_circuit import g_tables, keys
15+
16+
17+
circuit_filename = "circuit.json"
18+
with open(circuit_filename) as json_file:
19+
circuit = json.load(json_file)
20+
21+
22+
inputs = {}
23+
for i in circuit["inputs"]:
24+
v = keys[i][1]
25+
inputs[i] = v
26+
27+
evaluation = evaluate_circuit(circuit, g_tables, inputs)
28+
print("")
29+
print(evaluation)
30+

Diff for: DiceCTF/2021/garbled/flag.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import hashlib
2+
import json
3+
4+
from yao import evaluate_circuit
5+
from public_data import g_tables
6+
7+
8+
def xor(A, B):
9+
return bytes(a ^ b for a, b in zip(A, B))
10+
11+
12+
##########################################################
13+
14+
15+
circuit_filename = "circuit.json"
16+
with open(circuit_filename) as json_file:
17+
circuit = json.load(json_file)
18+
19+
20+
inputs = {
21+
1: 11693387,
22+
2: 11338704,
23+
3: 7371799,
24+
4: 2815776,
25+
}
26+
27+
evaluation = evaluate_circuit(circuit, g_tables, inputs)
28+
print(evaluation)
29+
30+
31+
##########################################################
32+
33+
34+
msg = "{}:{}:{}:{}".format(inputs[1], inputs[2], inputs[3], inputs[4])
35+
msg = msg.encode('ascii')
36+
37+
m = hashlib.sha512()
38+
m.update(msg)
39+
m.digest()
40+
41+
xor_flag = b'\x90),u\x1b\x1dE:\xa8q\x91}&\xc7\x90\xbb\xce]\xf5\x17\x89\xd7\xfa\x07\x86\x83\xfa\x9b^\xcb\xd77\x00W\xca\xceXD7'
42+
43+
print(xor(m.digest(), xor_flag))

Diff for: DiceCTF/2021/garbled/generate_garbled_circuit.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from yao import GarbledCircuit
2+
import json
3+
4+
5+
circuit_filename = "circuit.json"
6+
with open(circuit_filename) as json_file:
7+
circuit = json.load(json_file)
8+
9+
# creates a new garbled circuit each time
10+
gc = GarbledCircuit(circuit)
11+
12+
g_tables = gc.get_garbled_tables()
13+
keys = gc.get_keys()
14+
15+
16+
print("g_tables = {}".format(repr(g_tables)))
17+
print("\nkeys = {}".format(repr(keys)))

Diff for: DiceCTF/2021/garbled/obtain_flag.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""
2+
once you've found the input labels which make the circuit return `true`,
3+
then concatenate them together, hash them,
4+
and xor with the provided string to obtain the flag
5+
"""
6+
7+
import hashlib
8+
import json
9+
10+
from yao import evaluate_circuit
11+
from public_data import g_tables
12+
from private_data import keys, flag
13+
14+
15+
def xor(A, B):
16+
return bytes(a ^ b for a, b in zip(A, B))
17+
18+
19+
##########################################################
20+
21+
22+
circuit_filename = "circuit.json"
23+
with open(circuit_filename) as json_file:
24+
circuit = json.load(json_file)
25+
26+
27+
# ?????????????????
28+
inputs = {
29+
1: ?????????????????,
30+
2: ?????????????????,
31+
3: ?????????????????,
32+
4: ?????????????????
33+
}
34+
35+
36+
evaluation = evaluate_circuit(circuit, g_tables, inputs)
37+
38+
# circuit should return `true`
39+
for i in circuit['outputs']:
40+
assert evaluation[i] == keys[i][1]
41+
42+
43+
##########################################################
44+
45+
46+
msg = "{}:{}:{}:{}".format(inputs[1], inputs[2], inputs[3], inputs[4])
47+
msg = msg.encode('ascii')
48+
49+
m = hashlib.sha512()
50+
m.update(msg)
51+
m.digest()
52+
53+
xor_flag = b'\x90),u\x1b\x1dE:\xa8q\x91}&\xc7\x90\xbb\xce]\xf5\x17\x89\xd7\xfa\x07\x86\x83\xfa\x9b^\xcb\xd77\x00W\xca\xceXD7'
54+
55+
56+
print( xor(m.digest(), xor_flag) )
57+
58+
assert xor(m.digest(), xor_flag) == flag

Diff for: DiceCTF/2021/garbled/output.txt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Ungarbling Gate 5
2+
Valid Combination Found
3+
(11693387, 188483) => 16554183
4+
(11693387, 11338704) => 2692508
5+
(12215201, 188483) => 16554183
6+
(12215201, 11338704) => 16554183
7+
Ungarbling Gate 6
8+
Valid Combination Found
9+
(7371799, 5588127) => 7903130
10+
(7371799, 2815776) => 15328025
11+
(9872293, 5588127) => 7903130
12+
(9872293, 2815776) => 7903130
13+
Ungarbling Gate 7
14+
Valid Combination Found
15+
(16554183, 15328025) => 2938161
16+
(16554183, 7903130) => 2938161
17+
(2692508, 15328025) => 13264649
18+
(2692508, 7903130) => 2938161

Diff for: DiceCTF/2021/garbled/public_data.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
g_tables = {5: [(5737111, 2983937),
2+
(15406556, 16284948),
3+
(14172222, 14132908),
4+
(4000971, 16383744)],
5+
6: [(8204186, 1546264),
6+
(229766, 3208405),
7+
(9550202, 13483954),
8+
(13257058, 5195482)],
9+
7: [(1658768, 11512735),
10+
(1023507, 9621913),
11+
(7805976, 1206540),
12+
(2769364, 9224729)]}

Diff for: DiceCTF/2021/garbled/solver/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

Diff for: DiceCTF/2021/garbled/solver/Cargo.lock

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: DiceCTF/2021/garbled/solver/Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "solver"
3+
version = "0.1.0"
4+
authors = ["Yechan Bae <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
once_cell = "1.5.2"

0 commit comments

Comments
 (0)