Semi-ADFGX 18+
Semi-ADFGX 18+
Platform: grodno_new_year_2026 | Category: Crypto | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-01-10 | Status: Solved Techniques: bigram_frequency_analysis, known_plaintext_attack, pattern_matching
Summary
Files provided: - Cipher.txt (310 characters) - the ciphertext to decrypt - Intercepted_Codes.txt (860600 characters) - known plaintext for cryptanalysis (Project Gutenberg book "A Farewell to Arms" by Ernest Hemingway)
Semi-ADFGX 18+ - Grodno New Year 2026
Description
Новый год наступил. Поздравляем вас! Флаг в формате grodno{a-z_}
The New Year has arrived. Congratulations! Flag in the format grodno{a-z_}
Files provided:
Cipher.txt(310 characters) - the ciphertext to decryptIntercepted_Codes.txt(860600 characters) - known plaintext for cryptanalysis (Project Gutenberg book "A Farewell to Arms" by Ernest Hemingway)
Analysis
Step 1: Ciphertext Structure
The ciphertext consists of bigrams (pairs of characters):
CECWFYFYRNRWCPRETWRWRNRECWGNRWCWCPRPRWGEREGNGNRNRWTECEGNCAFWCYGECWFWRW...
Breaking into bigrams:
CE CW FY FY RN RW CP RE TW RW RN RE CW GN RW CW CP RP RW GE RE GN GN RN RN RW ...
Step 2: Identify Character Sets
First characters (rows): C, F, G, R, T (5 characters) Second characters (columns): A, E, N, P, W, Y (6 characters)
This is a 5x6 Polybius square - a modified ADFGX cipher (standard ADFGX uses 5x5). The "18+" in the title hints at this: 5+6+5+2 = 18 (or simply 5*6 = 30 > 26 letters + space).
Step 3: Frequency Analysis
Using the large known plaintext (Intercepted_Codes.txt - Hemingway's "A Farewell to Arms"), I performed frequency analysis on bigrams:
python read-only • copy allowedfrom collections import Counter with open('Intercepted_Codes.txt', 'r') as f: known = f.read() # Split into bigrams bigrams = [known[i:i+2] for i in range(0, len(known)-1, 2)] freq = Counter(bigrams) # Top frequencies for bg, count in freq.most_common(30): print(f"{bg}: {count} ({count/len(bigrams)*100:.2f}%)")
Key finding: Bigram RW appears with ~18.6% frequency - this matches the expected frequency of SPACE in English text.
Verification: Average "word" length (characters between RW bigrams) was ~4.37, matching typical English word length.
Step 4: Build Substitution Mapping
Using frequency analysis and pattern matching with common English words (THE, THIS, AND, etc.):
| Bigram | Plaintext | Frequency Rank |
|---|---|---|
| RW | SPACE | 1 (18.6%) |
| RE | E | 2 |
| CY | T | 3 |
| CW | A | 4 |
| CN | O | 5 |
| CA | I | 6 |
| CP | N | 7 |
| CE | H | 8 |
| FW | S | 9 |
| GN | R | 10 |
| RP | D | 11 |
| TP | L | 12 |
| TW | W | 13 |
| TA | U | 14 |
| RN | Y | 15 |
| GE | M | 16 |
| TN | G | 17 |
| TE | C | 18 |
| FP | F | 19 |
| GY | B | 20 |
| FY | P | 21 |
| GW | K | 22 |
| RY | V | 23 |
| FN | J | 24 |
| GA | X | 25 |
| RA | Q | 26 |
| FE | Z | 27 |
| |
Solution
Decryption Script
python read-only • copy allowed#!/usr/bin/env python3 # Complete bigram to character mapping mapping = { 'RW': ' ', # SPACE 'RE': 'E', 'CY': 'T', 'CW': 'A', 'CN': 'O', 'CA': 'I', 'CP': 'N', 'CE': 'H', 'FW': 'S', 'GN': 'R', 'RP': 'D', 'TP': 'L', 'TW': 'W', 'TA': 'U', 'RN': 'Y', 'GE': 'M', 'TN': 'G', 'TE': 'C', 'FP': 'F', 'GY': 'B', 'FY': 'P', 'GW': 'K', 'RY': 'V', 'FN': 'J', 'GA': 'X', 'RA': 'Q', 'FE': 'Z' } def decrypt(ciphertext): plaintext = [] for i in range(0, len(ciphertext), 2): bigram = ciphertext[i:i+2] if bigram in mapping: plaintext.append(mapping[bigram]) else: plaintext.append('?') return ''.join(plaintext) with open('Cipher.txt', 'r') as f: cipher = f.read().strip() decrypted = decrypt(cipher) print(f"Decrypted: {decrypted}") # Convert to flag format (spaces to underscores) flag = 'grodno{' + decrypted.lower().replace(' ', '_') + '}' print(f"Flag: {flag}")
Decrypted Message
HAPPY NEW YEAR AND MERRY CHRISTMAS TO ALL REDACTED OF THE NEW YEAR CTF FROM OUR TEAM WE WOULD BE DELIGHTED TO SEE YOU AT OUR GRAND FINALE IN FEBRUARY
Critical observation: There are THREE consecutive spaces between "TEAM" and "WE" (three RW bigrams in a row: RWRWRW). This must be preserved as three underscores (___) in the flag.
Lessons Learned
- Modified ciphers: The "Semi-ADFGX" uses a 5x6 grid instead of standard 5x5, allowing for 30 symbols (26 letters + space + extras)
- Space detection: In substitution ciphers, the most frequent symbol is usually SPACE (~18% in English)
- Word length verification: Average English word length (~4.5 chars) helps confirm space identification
- Preserve exact spacing: Multiple consecutive spaces in the plaintext must be preserved in the flag format