# X Marked the Spot (crypto)

{% file src="/files/nPXrCXIenMm0udYrLkRN" %}

{% file src="/files/Iys5NTn9LWTzD2p0jPvY" %}

```python
from itertools import cycle

flag = b"uiuctf{????????????????????????????????????????}"
# len(flag) = 48
key  = b"????????"
# len(key) = 8
ct = bytes(x ^ y for x, y in zip(flag, cycle(key)))

with open("ct", "wb") as ct_file:
    ct_file.write(ct)
```

We are given the above encryption code, along with the produced ciphertext. Each character in the flag is XOR'ed with a character in the key. Since the length of the flag is 48 while the length of the key is 8, the key is cycled through 6 times.

Notice that the first 7 characters of the flag are known, along with the last character of the flag. The first 7 characters of the flag would be XOR'ed with the first 7 characters of the key, while the last character of the flag would be XOR'ed with the last character of the key.&#x20;

Let $$k\_i$$ be bit $$i$$ in the key, $$p\_i$$be a bit in the plaintext, and $$c\_i$$ be a bit in the ciphertext. A key property of XOR is that if $$p\_i \oplus k\_i = c\_i$$, then $$p\_i \oplus c\_i = k\_i$$. Therefore if we know the characters in the plaintext and ciphertext at an index $$i$$, we can perform an XOR operation between them to obtain the $$i$$-th character in the key, $$k\_i$$.

To retrieve the first 7 characters of the key, we XOR the first 7 characters of the plaintext with the first 7 characters of the ciphertext. To retrieve the last character of the key, we XOR the last character of the plaintext with the last character of the ciphertext. Once we have retrieved the key, we XOR it with the ciphertext to retrieve the plaintext!

```python
from itertools import cycle

with open("ct", "rb") as ct_file:
    data = ct_file.read()
assert len(data) == 48
# len(flag) = 48
flag_temp = b"uiuctf{}"
# retrieve key by XORing first 7 chars of pt and ct, and XORing their last char
key = bytes(x ^ y for x, y in zip(flag_temp, data[:7] + data[-1].to_bytes(1, "little")))
assert len(key) == 8
print(key)
# len(key) = 8
flag = b"uiuctf{"
for j in range(7, 48):
    flag += (data[j] ^ key[j % 8]).to_bytes(1, "little")
assert len(flag) == 48
print(flag) # uiuctf{n0t_ju5t_th3_st4rt_but_4l50_th3_3nd!!!!!}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://elijahchia.gitbook.io/ctf-blog/uiuctf-24/x-marked-the-spot-crypto.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
