Tags: crypto 


## Short description

For each input bit, a `key` number and `fake` number is generated. A random `keystream` is generated and a corresponding public list, such that
public[i] = [fake[i], key[i]] if keystream[i] else [key[i], fake[i]]
The input is XORed with the random `keystream` to generate the ciphertext and this is output together with `public`. But `fake` was generated by just XORing values from `key`, and based on this, we can guess which values from `public` are from `fake`. The others must be from `key`, allowing us to recover the `keystream` and decrypt the flag.

## Exploit script

The following script finds the values that must have come from `key`, one by one from last to first:

key = []
k = 0
for i in range(ln):
for a, b in public:
if a == k:
elif b == k:
k = xor_list(key[-ln // 3:])
The `keystream` can then be recovered and the flag decrypted:
keystream = recover_keystream(key, public)
flag = bits_to_bytes(xor(enc, keystream))

Click the link for a much more detailed writeup.

Original writeup (https://nissen96.github.io/CTF-writeups/writeups/2021/pbctf/Alkaloid-Stream.html).