NahamCon Winter CTF 2025: Crypto Challenge Writeups
Welcome to my writeups for the cryptography challenges from NahamCon Winter CTF 2025! This winter-themed CTF brought some interesting crypto puzzles that tested our understanding of classical ciphers and mathematical transformations.
Challenge: Linear Lines
Category: Cryptography
Difficulty: Easy-Medium
Description: A function, not a shift, guards the text. Can you unlock it and give it to me wrapped in flag{}?
Ciphertext: ODEXRKFAKVHAVKXFROLRBFOXRT
Analysis
The challenge description gives us a crucial hint: “A function, not a shift” - this immediately points us away from simple Caesar ciphers toward more complex mathematical transformations. The word “linear” in the challenge name further suggests we’re dealing with a linear mathematical function.
This combination of clues strongly indicates an affine cipher, which uses a linear mathematical function for encryption and decryption.
Understanding Affine Ciphers
The affine cipher is a type of monoalphabetic substitution cipher that uses mathematical functions:
Encryption Formula: E(x) = (ax + b) mod 26
Decryption Formula: D(x) = a^(-1)(x - b) mod 26
Where:
aandbare the key componentsamust be coprime to 26 (valid values: 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25)bcan be any value from 0-25a^(-1)is the modular multiplicative inverse ofamodulo 26
Solution Approach
I used two methods to solve this challenge:
Method 1: Automated Tool (Quick Solution)
For a quick solution, I used the excellent ciphey tool:
pip install cipheyecho "ODEXRKFAKVHAVKXFROLRBFOXRT" | cipheyThis tool automatically detects and decrypts various cipher types, making it perfect for CTF scenarios.
Method 2: Manual Analysis (Educational)
For a deeper understanding, I wrote a script to brute force all possible affine cipher keys:
def affine_decrypt(ciphertext, a, b): # Calculate modular multiplicative inverse of a def mod_inverse(a, m): for i in range(1, m): if (a * i) % m == 1: return i return None
a_inv = mod_inverse(a, 26) if a_inv is None: return None
result = "" for char in ciphertext: if char.isalpha(): # Convert to 0-25 range x = ord(char.upper()) - ord('A') # Apply decryption formula decrypted = (a_inv * (x - b)) % 26 result += chr(decrypted + ord('A')) else: result += char
return result
# Valid values of 'a' (must be coprime to 26)valid_a = [1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25]ciphertext = "ODEXRKFAKVHAVKXFROLRBFOXRT"
for a in valid_a: for b in range(26): decrypted = affine_decrypt(ciphertext, a, b) if decrypted and "LINEAR" in decrypted: print(f"a={a}, b={b}: {decrypted}")The Solution
After testing all possible key combinations, I found the correct parameters:
- a = 21, b = 17
- Decrypted text:
LINEARSTRUCTURESALWAYSLEAK
This makes perfect sense! The plaintext “LINEAR STRUCTURES ALWAYS LEAK” is a clever reference to the mathematical nature of the affine cipher and a common principle in cryptanalysis.
Key Insights
- Challenge Design: The hint “function, not a shift” was crucial for identifying the cipher type
- Mathematical Foundation: Understanding that affine ciphers are linear transformations helped narrow down the approach
- Cryptanalysis Principle: The decrypted message itself teaches us that linear cryptographic structures often have weaknesses that can be exploited
Flag
Wrapping the solution in the required format: flag{LINEARSTRUCTURESALWAYSLEAK}
Lessons Learned
This challenge beautifully demonstrates several important concepts:
- Cipher Identification: Learning to recognize cipher types from contextual clues
- Mathematical Cryptography: Understanding how mathematical functions can be used for encryption
- Brute Force Techniques: When the key space is small enough, exhaustive search becomes viable
- Tool Usage: Knowing when to use automated tools vs. manual analysis for learning
The affine cipher, while more complex than Caesar ciphers, still falls into the category of classical ciphers that are vulnerable to frequency analysis and brute force attacks due to their limited key space.
This writeup is part of my NahamCon Winter CTF 2025 series. Check out my other writeups for more challenges from this excellent CTF!
Next reads
View all →21 Dec
Advent of CTF 2025: Day 1 - The Mission Begins
A beginner-friendly cryptography challenge involving multi-step encoding conversion using CyberChef to decode binary data into the final flag.
27 Jan
Probably Just Fine - TryHackMe First Shift CTF Writeup
A step-by-step SOC investigation through TryHackMe's First Shift CTF scenario, covering threat intel lookups, file hash analysis, and report-driven attribution insights.
22 Dec
Advent of CTF 2025: Day 5 - Kramazon
Web exploitation challenge targeting a malicious e-commerce platform with cookie manipulation and privilege escalation vulnerabilities.
Get posts by email
One email when I publish, not a drip, not weekly. Sign up and I'll only write when there's something new.
You won't get mail just for signing up. Unsubscribe any time.