Skip to content

Commit e37d0e8

Browse files
committed
added old tdcnet challenge
1 parent df8c1b5 commit e37d0e8

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

content/chall_files/roll/handout.zip

1.27 KB
Binary file not shown.

content/ctf/roll.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: "Roll"
3+
date: 2023-09-17
4+
author: "cavefxa"
5+
category: "crypto"
6+
summary: "Challenge from TDCNET-CTF 23 - Download the challenge files: [roll.zip](/chall_files/roll/handout.zip)"
7+
---
8+
9+
### Challenge Description
10+
Hans Peter walks his dog, phew - what a commitment! He is going to play some D&D with his friends later, phew - what a commitment!
11+
12+
### Solution
13+
I made a `custom` commitment scheme for this challenge. I tried to hint subtly in the description, that the challenge is related to the Pedersen commitment scheme.
14+
15+
A commitment scheme is a cryptographic primitive that allows one to commit to a chosen value (or chosen statement) while keeping it hidden to others, while maintaining the ability to reveal the committed value later.
16+
17+
This can be very useful for online casinos, for example: Natalie wants to play online roulette, she puts in the money, and clicks play. After the play button was pressed, she received a commitment from the casino, and the roulette table begins to spin - she losses, and the value is revealed - showing that she was not being tricked.
18+
19+
The specifically suspicious thing about this code is the `verify()` function:
20+
```python
21+
def verify(param, c, r, x):
22+
q, g, h = param
23+
return pow(c, (q-1)//2, q) == pow((pow(g,x,q) * pow(h,r,q) % q), (q-1)//2, q)
24+
```
25+
26+
We're using Legendre's Symbol to check if both of the parameters are quadratic residues. We take a quick look at the numbers being given to `verify`:
27+
28+
```python
29+
if verify(keygen, c, r, secret_roll) == verify(keygen, c, r, your_roll):
30+
```
31+
32+
We see that the first part is:
33+
34+
```python
35+
pow(c, (q-1)//2, q)
36+
```
37+
38+
And we already know `c`. This is generated as such:
39+
40+
```python
41+
c,r = commit(keygen, secret_roll)
42+
print(f"Here's my commitment, so you'll trust me!")
43+
print(f"{c = }")
44+
```
45+
46+
We have 6 possible options here for the commitment:
47+
48+
```
49+
commit(keygen, 1)
50+
commit(keygen, 2)
51+
commit(keygen, 3)
52+
...
53+
commit(keygen, 6)
54+
```
55+
56+
Let's go back to the following code:
57+
58+
```python
59+
pow(c, (q-1)//2, q)
60+
```
61+
62+
Whenever `c` is a quadratic residue, the result of the above calculation will always yield a quadratic residue. What if all the rolls are quadratic residues?
63+
64+
Below is a crude solve script:
65+
```python
66+
while True:
67+
q, g, h = get_q(), get_g(), get_h()
68+
param = q, g, h
69+
commit_qr = pow(get_com(), (q-1)//2, q)
70+
71+
# Check if all commitments equal 1 when raised to (q-1)//2
72+
if all(pow(commit(param, i)[0], (q-1)//2, q) == 1 for i in range(1, 7)):
73+
io.sendline(b"Y" if commit_qr == 1 else b"G")
74+
else:
75+
io.sendline(b"G")
76+
77+
io.interactive()
78+
```
79+
80+
And then we get the flag:
81+
`TDCNET{th3y_s33_me_r0ll1n_th3Y_h4t!nG}`

0 commit comments

Comments
 (0)