Tags: png xor 

Rating:

# Fast Speedy!

> You can’t connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future.

## Challenge

This is basically a XOR cipher on a picture, with a unknown key and a known key generation function

## Cipher

```python
def drift(R, B):
n = len(B)
ans, ini = R[-1], 0
for i in B:
ini ^= R[i-1]
R = [ini] + R[:-1]
return ans, R
```
Notice that the order of `B` doesn't matter since XOR is commutative

```python
r = random.randint(7, 128)
s = random.randint(2, r)
R = [random.randint(0, 1) for _ in xrange(r)]
B = [i for i in xrange(s)]
random.shuffle(B)
```
Here `random.shuffle(B)` doesn't matter as XOR is commutative. Here we get bounds for the size of `R` and `B`

```python
for i in range(len(flag)):
ans, R = drift(R, B)
A = A + [ans]
enc = enc + [int(flag[i]) ^ ans]
```
Encryption basically takes the first output of `drift` and XORs it into the flag. Looking at drift, the first `r` outputs is basically `R[::-1]`, and we use this to bruteforce possible `R` and `B`

## Bruteforce

The first `16` characters of a PNG file is likely to be `0x89504e470d0a1a0a0000000d49484452`, so we simply take the first few bits, run drift on all possible values of `B` and check if it matches, else take more bits, this is done at [findR.py](findR.py).

Large `R` length may not be correct as it basically takes most of the known text to predict `R`, so we choose the smallest output

```
r = 13
b = 5
R = [0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1]
```

Since XOR is its own inverse, we simply rerun the script, but the encrypted file is used as input and output is the decrypted file. The decrypted file is a picture of the flag

> Flag : `CCTF{LFSR__In___51mPL3___w0rD5}`

Original writeup (https://github.com/Ariana1729/CTF-Writeups/blob/master/2019/CryptoCTF/Fast%20Speedy%21/README.md).