Tags: crypto 

Rating:

# Now We Can Play!! Writeup

### Harekaze 2019 - crypto 200

We must recover plaintext `m`, which is flag. We first analyze how ciphertext `c1` and `c2` were generated.

``` python
x = randint(2, p)
r = randint(2, p)
h = pow(g, x, p)
c1 = pow(g, r, p)
c2 = m * pow(h, r, p) % p
```

We know public key `p`, `g`, and `h`. By solving the equations, we get the following formula,

``` python
c2 = m * pow(g, x * r, p) % p
= m * pow(pow(g, r, p), x, p) % p
= m * pow(c1, x, p) % p
```

Now it is time for analyzing `decrypt()` function.

It returns `m_` which is generated by

``` python
rand = randint(2 ** 16, 2 ** 17)
m_ = pow(3, rand, p) * c2 * inverse(pow(c1, sk, p), p) % p
```

Solve the equation again, having a feeling that the equation is very similar to the upper equation having `c1` and `c2`. Since `x == sk`,

``` python
x = sk
c2 = m * pow(c1, sk, p) % p
m = c2 * inverse(pow(c1, sk, p)) % p
m_ = pow(3, rand, p) * m % p
m = m_ * inverse(pow(3, rand, p)) % p
```

Therefore, by bruteforcing to know the value of `rand`, we directly recover `m`! We only have to brute for maximally `2 ** 16` times, so it is possible. By sending a single request with `in_c1 = c1` and `in_c2 = c2`, we may successfully recover the flag `m`. We checked the candidates by using the fact that the flag must be printable.

By bruteforcing `rand` for about 1 or 2 seconds, we get the flag:

```
HarekazeCTF{im_caught_in_a_dr3am_and_m7_dr3ams_c0m3_tru3}
```

Full exploit code: [solve.py](solve.py)

Original problem: [problem.py](problem.py)

Original writeup (https://github.com/pcw109550/write-up/tree/master/2019/Harekaze/Now_We_Can_Play).