Purple Pill CTF 2024 - Legend[crypto]
Purple Pill CTF 2024 writeup for the challenge legend (crypto)
Difficulty : Easy (imo)
Team : Phreaks 2600
Description :
- FR : Nous fournissons notre chiffrement pour le système de points secrets de MegaCorp, nous pensons que tout est sécurisé, pouvez-vous essayer ?
- EN : We provide our encryption for MegaCorp’s secret points system, we think everything is secure, can you check?
Author : Yogosha
TL;DR
- The flag is converted to binary
- For bit = ‘1’: $ a^{e} \equiv n \mod p $ is stored
- For bit = ‘0’: $ -n \mod p $ is stored
- Using legendre symbol, we can recover if it was a 1 or 0 and recover the flag
Introduction
We are provided a simple custom encryption algorithm using modular arithmetic and powers. We also got the output of the encryption.
player.py
|
|
Reading the code, it’s easy to understand that we will have to work with the output to recover the value.
Solving
Reading source code
Source code is quite simple to read.
Two number are defined :
- $ a = 288260533169915 $ (which is not prime)
- $ p = 1007621497415251 $ (which is prime)
These number will be used to generate the encrypted values.
We got the encrypt_flag()
function :
encrypt_flag()
|
|
Each character of the flag is converted to binary and prepended with zeros (if necessary) to make it to a length of 8 plaintext = ''.join([bin(i)[2:].zfill(8) for i in flag])
which returns a long string of zeros and ones.
Then for every bit, a random value $ e < p $ is generated and a value n = $ a^{e} \mod p $.
If the bit value is 1, n is stored untouched, else -n % p
is stored in ciphertext
.
The ciphertext
list is returned and that’s it.
Finding the vulnerability
For this one I had the cursed idea to think I could find e
which refer to the problem of the discrete logarithm (finding x such as $ g^{x} \equiv y \mod p $ with g,y and p known) but that’s not the point of the challenge.
Another idea I got is to try to find if encrypted ‘1’ values have common propreties and same with ‘0’ bits.
Since n is the result of a power, we can think of quadratic residues
Saying that n
is quadrtic means that it exists a k
such that $ n \equiv k^{2} \mod p $.
It simply mean that $n$ is the result of a number to the power of 2 modulo p.
So I thought that it should work not only with the power of 2 but any power.
We can now if a number is a quadratic residue using LEGENDre symbol
. (more here)
There is a nice module on cryptohack teaching about these.
In shorts, we compute $ n^{\frac{p-1}{2}} \mod p $
- if 1 : it is a quadratic residue
- if -1 : it is not
We can test it with this code snippet :
|
|
Which outputs 10 ‘1’. So, $ a^{e} \mod p$ generates quadratic residues.
We can write $ n^{\frac{p-1}{2}} \equiv 1 \mod p $.
So : $ (-n)^{\frac{p-1}{2}} \equiv -1 \equiv p - 1 \equiv 1007621497415250 \mod p $
We can now recover every bit value by calculating the quadratic residues.
Solve script
solve_legend.py
|
|
FLAG : PPC2024{legendre_symbol?was_it?}
Conclusion
That was a nice way to remind me some basics of modular arithmetic. It was only after solving that I noticed that the name of the challenge was an hint.