basic-mod2

Published: July 20, 2023

Description

The follow-up to basic-mod1 swaps the modulus to 41 and asks for the modular inverse of each value before mapping 1-26 to letters, 27-36 to digits, and 37 to underscore.

Convert the provided numbers into a Python list so you can iterate through them easily.

For each entry compute the modular inverse `pow(n, -1, 41)` (Python's built-in handles it) and subtract 1 to use zero-based indexing.

Translate the resulting values into the alphabet/digit/underscore character set and assemble the flag.

wget https://artifacts.picoctf.net/c/180/message.txt
cat message.txt
cat message.txt | sed -e "s/^/[/" | sed 's/ *$//' | sed -e "s/$/]/" | sed -e "s/ /, /g"
python3 mod2.py

Solution

  1. Step 1Reuse the parsing trick
    The same sed pipeline from basic-mod1 turns the raw numbers into a Python-friendly array, letting you focus on the math instead of text processing.
    Learn more

    Reusing tools and patterns across related challenges is a core CTF skill. Recognizing that the input format is identical to basic-mod1 means you can adapt your existing script rather than starting from scratch - you only need to swap the decoding logic, not the parsing.

    The sedpipeline that wraps space-separated numbers into a Python list is a general-purpose pattern that works any time you have whitespace-delimited integers on a single line. Keeping such one-liners in a personal "toolbox" or snippet library speeds up CTF solving considerably.

  2. Step 2Compute modular inverses
    Python's `pow(value, -1, 41)` returns the multiplicative inverse modulo 41. Because the alphabet in this challenge is 1-indexed, subtract 1 before indexing into `ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_`.
    Learn more

    The modular multiplicative inverse of a number a modulo m is the value x such that a * x ≡ 1 (mod m). It only exists when a and m are coprime (share no common factors other than 1). Since 41 is prime, every value from 1 to 40 has an inverse - which is why 41 was chosen as the modulus.

    Python 3.8+ supports pow(a, -1, m) as a direct shortcut for computing the modular inverse using the extended Euclidean algorithm internally. Before this addition, you would have needed a helper function or the sympy library. The extended Euclidean algorithm is also the mathematical backbone of RSA key generation.

    The 1-indexed alphabet (mapping 1→A instead of 0→A) is a common twist that trips up solvers used to zero-indexed arrays. Subtracting 1 after computing the inverse aligns the result with Python's zero-based string indexing.

  3. Step 3Build the string
    Append each character to a string prefixed with `picoCTF{` and close it with `}` once all characters are decoded.

Flag

picoCTF{1NV3R53LY_H4RD_8A05...}

Modular inverses rarely show up in intro problems, but Python's `pow` handles them without extra libraries.

Want more picoCTF 2022 writeups?

Useful tools for Cryptography

Related reading

What to try next