Writeup: HackCon 2019 - AgainAndAgainAndAgain
Information
- category : crypto
- points : 467
Description
Someone was thinking encrypting again and again helps, prove them wrong.
c = 196353764385075548782571270052469419021844481625366305056739966550926484027148967165867708531585849658610359148759560853
File : q1.py
Writeup
Content of q1.py :
1 | def encrypt(m): |
We have : n = p * q, p, q, c. To encrypt a message m the script does : (m ^ 2) % n = c.
The encryption remembers RSA, however in this case we have e = 2 which is not a possible exponent in RSA because gcd(2, phi(n)) = 2 and so the inverse of e in phi(n) is not possible. This cryptosystem with exponent 2 is the Rabin cryptosystem.
Decrypting a ciphertext c we get 4 different results. To decrypt we need to:
- Compute
mp = c ^ (1/4 * (p + 1)) mod p- Compute
mq = c ^ (1/4 * (q + 1)) mod q - Both can be expressed as :
mp = sqrt(c) mod pmq = sqrt(c) mod q- Use Tonelli-Shanks algorithm to compute both of them.
- Compute
- Compute
- Use Extended Euclidean algorithm to find
ypandyqs.t.yp * p + yq * q = gcd(p, q) = 1 - Use the Chinese remainder theorem to find the fours square roots of
c mod n:r1 = (yp * p * mq + yq * q * mp) mod nr2 = n - r1r3 = (yp * p * mq - yq * q * mq) mod nr4 = n - r3
Difficulty
During encryption the challenger encrypts the flag n times, we don’t know how many times (n) because we don’t know the flag. To solve the problem we can imagine the following graph :

Where recursively during the decryption we create 4 times more nodes at each level. In the level i there will be 4^i nodes.
To solve this problem we can implement a BFS. Implementing a DFS is not a valid approach. We don’t have the graph structure and we need to create one on the fly, with a DFS we don’t know where to stop “searching”.
BFS pseudocode:
1 | procedure BFS(G,start_v): |
Exploit
1 | #!/usr/bin/env python3 |
Flag
d4rk{r3p3t1t1v3_r4b1n_1s_th4_w0rs7_3vaaaaaar!}code