> For the complete documentation index, see [llms.txt](https://ravins-organization.gitbook.io/ctf-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ravins-organization.gitbook.io/ctf-writeups/2024/picoctf-2024/crypto/custom-encryption.md).

# Custom Encryption

https\://play.picoctf.org/practice/challenge/412?originalEvent=73\&page=2

**Description**

Can you get sense of this code file and write the function that will decode the given encrypted file content. Find the encrypted file here [flag\_info](https://artifacts.picoctf.net/c_titan/93/enc_flag) and [code file](https://artifacts.picoctf.net/c_titan/93/custom_encryption.py) might be good to analyze and get the flag.

In the code file, we see

```python
from random import randint
import sys


def generator(g, x, p):
    return pow(g, x) % p


def encrypt(plaintext, key):
    cipher = []
    for char in plaintext:
        cipher.append(((ord(char) * key*311)))
    return cipher


def is_prime(p):
    v = 0
    for i in range(2, p + 1):
        if p % i == 0:
            v = v + 1
    if v > 1:
        return False
    else:
        return True


def dynamic_xor_encrypt(plaintext, text_key):
    cipher_text = ""
    key_length = len(text_key)
    for i, char in enumerate(plaintext[::-1]):
        key_char = text_key[i % key_length]
        encrypted_char = chr(ord(char) ^ ord(key_char))
        cipher_text += encrypted_char
    return cipher_text


def test(plain_text, text_key):
    p = 97
    g = 31
    if not is_prime(p) and not is_prime(g):
        print("Enter prime numbers")
        return
    a = randint(p-10, p)
    b = randint(g-10, g)
    print(f"a = {a}")
    print(f"b = {b}")
    u = generator(g, a, p)
    v = generator(g, b, p)
    key = generator(v, a, p)
    b_key = generator(u, b, p)
    shared_key = None
    if key == b_key:
        shared_key = key
    else:
        print("Invalid key")
        return
    semi_cipher = dynamic_xor_encrypt(plain_text, text_key)
    cipher = encrypt(semi_cipher, shared_key)
    print(f'cipher is: {cipher}')


if __name__ == "__main__":
    message = sys.argv[1]
    test(message, "trudeau")

```

So, I asked ChatGPT to help me reverse the whole script, and gave it my values of a and b, along with the cipher that is inside the flag\_info file. That resulted in the following code:

```python
from random import randint

def generator(g, x, p):
    return pow(g, x) % p

def encrypt(plaintext, key):
    cipher = []
    for char in plaintext:
        cipher.append(((ord(char) * key*311)))
    return cipher

def is_prime(p):
    v = 0
    for i in range(2, p + 1):
        if p % i == 0:
            v = v + 1
    if v > 1:
        return False
    else:
        return True

def dynamic_xor_decrypt(cipher_text, text_key):
    decrypted_text = ""
    key_length = len(text_key)
    for i, char in enumerate(cipher_text):
        key_char = text_key[i % key_length]
        decrypted_char = chr(ord(char) ^ ord(key_char))
        decrypted_text += decrypted_char
    return decrypted_text[::-1]

def decrypt(cipher, key):
    plaintext = ""
    for encrypted_value in cipher:
        decrypted_value = encrypted_value // (key * 311)
        plaintext += chr(decrypted_value)
    return plaintext

def reverse_test(cipher, text_key):
    p = 97
    g = 31
    if not is_prime(p) or not is_prime(g):
        print("Enter prime numbers")
        return
    a = 88
    b = 26
    u = generator(g, 1, p)
    v = generator(g, b, p)
    shared_key = generator(v, a, p)
    semi_cipher = decrypt(cipher, shared_key)
    decrypted_text = dynamic_xor_decrypt(semi_cipher, text_key)
    print(f'Decrypted message is: {decrypted_text}')

if __name__ == "__main__":
    cipher = [97965, 185045, 740180, 946995, 1012305, 21770, 827260, 751065, 718410, 457170, 0, 903455, 228585, 54425, 740180, 0, 239470, 936110, 10885, 674870, 261240, 293895, 65310, 65310, 185045, 65310, 283010, 555135, 348320, 533365, 283010, 76195, 130620, 185045]
    reverse_test(cipher, "trudeau")

```

Now, running this gives me the output of

![](https://175444261-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyxEI13wXOyST4LLTOUiS%2Fuploads%2FAETNOGHvyGbgucmH0oS6%2FScreenshot%202024-03-27%20at%209.08.04%20PM.png?alt=media\&token=0bed055a-2871-4d49-9778-cadfad2339df)

Thus, giving us the flag

```
picoCTF{custom_d2cr0pt6d_019c831c}
```
