> For the complete documentation index, see [llms.txt](https://writeups.ayweth20.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://writeups.ayweth20.com/2025/404ctf-2025/cryptanalyse/message-lointain.md).

# Message lointain

**Catégorie:** Cryptanalyse - **Difficulté:** Intro

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

**Description:**

<figure><img src="/files/ap6tyTkRFnoEYdHsSqSW" alt=""><figcaption></figcaption></figure>

Solution:

Ici il s'agit d'un chall très simple où le flag a été chiffré avec la fonction `encrypt` :&#x20;

<figure><img src="/files/1vsy7NbpAKXCUNbNZvSQ" alt=""><figcaption></figcaption></figure>

Le but ici est de créer une fonction decrypt afin de lui donner notre flag et retrouver l'original.

Voici les étapes à suivre :&#x20;

* Pour chaque caractère chiffré, retrouver son indice `y` dans `charset`.
* Retrouver l'entier `x` tel que `pow(2, x, n+1) == y`.
* En déduire le caractère clair d’indice `x` dans `charset`.

Avec ces infos, la création de la fonction est très rapide :&#x20;

```python
inverse_pow2 = {}
for x in range(n):
    y = pow(2, x, n+1)
    inverse_pow2[y] = x  # y est l'indice chiffré, x est l'indice original

def decrypt(ciphertext):
    decrypted = []
    for char in ciphertext:
        if char in charset:
            y = charset.index(char)
            if y in inverse_pow2:
                x = inverse_pow2[y]
                decrypted.append(charset[x])
            else:
                # Cas rare si y ne correspond à aucun pow(2, x, n+1)
                decrypted.append('?')
    return ''.join(decrypted)

print("DECRYPTED FLAG : ", decrypt("828x6Yvx2sOnzMM4nI2sQ"))
```

Et voilà le résultat :&#x20;

<figure><img src="/files/EdcOtpESZ5w6beYxF6KR" alt=""><figcaption></figcaption></figure>

<details>

<summary>🚩FLAG</summary>

`404CTF{C0nstEllAt!0n}`

</details>
