Description
This is the Custom Cyclical Cipher! Download the ciphertext here. Download the encoder here. Enclose the flag in our wrapper for submission. If the flag was "example" you would submit "picoCTF{example}".
Setup
Download ciphertext and convert.py to the same directory.
Run the provided script locally with Python 3.
wget https://artifacts.picoctf.net/c_titan/47/ciphertext && \
wget https://artifacts.picoctf.net/c_titan/47/convert.pySolution
- Step 1Implement the inverseTranslate convert.py into a decryptor: swap lookup1/lookup2 roles, replace (cur - prev) with (cur + prev), and keep prev synced with the decrypted index.
python3 decrypt.py ciphertext > decrypted.txtLearn more
The C3 cipher is a cyclical differential cipher - a custom substitution scheme where each character's encoding depends on the previously encoded character. This "chaining" property means you cannot decrypt any character without first knowing all the characters that came before it, making it a simple form of cipher feedback.
To reverse such a cipher, you need to invert every operation in reverse order. If encryption computed
cur = (plaintext_index + prev) % alphabet_size, then decryption must computeplaintext_index = (cur - prev) % alphabet_size. The key insight is that modular arithmetic is always reversible: addition is undone by subtraction, and multiplication by a coprime is undone by multiplication by its modular inverse.The lookup table swap is equally important: during encryption, the plain character is looked up in
lookup1to get an index, which is then looked up inlookup2to get the cipher character. Reversal means: look up the cipher character inlookup2to get the index, then look up that index inlookup1to get the plain character.In real cryptography, this style of "cipher feedback" is formalized in stream cipher modes like CFB (Cipher Feedback Mode) used with AES. The vulnerability of simple cyclical ciphers is that if the alphabet is small, an attacker can mount a known-plaintext attack by just trying all possible starting states.
- Step 2Run the extraction scriptReuse the provided snippet that prints chars at i == n^3. Port it to Python 3 so it prints the hidden phrase that becomes the flag body.
python3 cubic_extract.py decrypted.txtLearn more
Embedding a secret by sampling at cubic indices (positions 1, 8, 27, 64, 125...) is a steganographic technique - the message is hidden within a larger body of text, with only specific positions carrying meaningful data. Anyone reading the full decrypted text sees innocuous content; only someone who knows to sample at
i = n³recovers the hidden flag.Steganography (hiding the existence of a message) differs from cryptography (hiding the content of a message). This challenge combines both: the outer cipher is cryptographic, while the cubic sampling is steganographic. Real-world malware sometimes uses similar index-based encoding to embed command-and-control instructions inside seemingly normal traffic.
In Python 3, iterating with
enumerate()and checking ifiis a perfect cube (by computinground(i**(1/3))**3 == i) is the idiomatic approach. Alternatively, you can precompute the cubic indices up to the file length. The key lesson is: always read the provided scripts carefully - the extraction logic is already given to you, just needing a Python 2 to Python 3 port. - Step 3Wrap the flagEnclose the final string in picoCTF{...} for submission.
Learn more
The
picoCTF{...}flag format is a standard wrapper used across all picoCTF challenges. This convention follows the CTF flag format pattern used by most major competitions (e.g.,CTF{...},flag{...},HTB{...}), which allows automated scoring systems to detect valid flag submissions by regex matching.When a challenge says "enclose the flag in our wrapper," it usually means the raw output of your decryption is the inner content - the competition infrastructure prepends the prefix and wrapping braces for display purposes. Always verify your wrapper format against the challenge instructions, as some challenges expect the entire string including the prefix.
This step also reinforces the habit of double-checking your answer before submission. Many CTF players lose points by submitting answers with trailing whitespace, incorrect case, or missing wrapper components. In competitive CTF play, a wrong submission rarely has a penalty, but it's good practice to verify thoroughly before submitting.
Related guides
Base64, Hex, and Common CTF Encodings Explained
This challenge uses a custom substitution cipher. The encodings guide covers classical ciphers, Caesar/ROT variants, and the identification techniques that help you recognize what you are dealing with.
Flag
picoCTF{adl...}
The cubic sampling script prints the final flag body.