Step 238. ★ Midterm Check: Independently Solving 5 Medium Crypto Problems — The Write-up Forbidden Zone
Level 3 — Real-World CTF & Advanced Offensive Skills | Difficulty ★★★★☆ | Estimated time: 15+ hours (spread over several days)
Prerequisites: the entire Crypto track from Steps 227~237. The classification routine and the RSA attack checklist are second nature.
⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime. Today’s stages, Dreamhack and picoCTF, are legal learning platforms officially opened by their operators.
- What you need: an account with access to unsolved medium-difficulty Crypto problems (Dreamhack difficulty 2~3 recommended), Python, a notes document, a timer.
- Caution: a checkup chapter with no new techniques. Server screens are marked as screen examples.
The Crypto track’s graduation exam. One rule — independently solve 5 medium-difficulty problems with no write-ups. "Knowing" the math and "wielding it as attack code" are different things. Do you draw every weapon you learned across 10 chapters by yourself, in front of a problem nobody explains? This is where that’s measured.
1. Learning Objectives
By the end of this chapter, you will be able to:
- Apply problem-selection criteria (random, pre-exposure blocked) for a fair check
- Run the independent solve with a 3-hour cap per problem and the classification-first routine
- Leave a process record including classification clues, attacks attempted, failure reasons, and breakthrough points
- Apply the self-verification method that distinguishes implementation bugs from attack failures
- Organize frequently used attack code into a crypto utility module
2. Background Knowledge — Today’s Tools and Concepts
Today’s Tools at a Glance
| Category | Details |
|---|---|
| Language/environment | Python + every attack tool you’ve built so far (inverse calculator, XOR tools, RSA attacks, toy hash, ECC operations) |
| Today’s procedure | Random selection → 3-hour cap → classification record → 5-problem verdict → write-up docs + utility module |
| Concepts needed | The definition of independent solving, implementation bug vs attack failure, the self-authored-problem verification method |
| Today’s deliverable | A 5-problem record table + 5 solution documents + crypto utility module v1 |
2-1. Why 5 Problems — and Why Not "Consecutive"?
One thing differs from Step 202 (the web check) — this time it’s not 3 consecutive but 5 problems completed. Crypto has large type variance between problems, so to prevent the accident of luckily drawing only types you know in a row, a larger sample is better. Solve all 5, but any problem whose write-up you saw is voided and replaced with a new one. The counter doesn’t reset — it replaces.
2-2. Fair Selection
- Unsolved only: only problems with no solve record are candidates
- Difficulty range: Dreamhack difficulty 2~3 (medium), or mid-point-score on picoCTF
- No pre-filtering by type: draw by random number from the candidate list. Check only the title and type label; do not read the detailed description
[Screen example — selection record]
candidates: 24 unsolved Dreamhack Crypto difficulty 2~3 problems
randoms: 4, 11, 19, 7, 22 → problems A~E confirmed
rules: 3 hours per problem, no write-up searches, technique docs only
2-3. The Ground Rules — 3 Hours and Classification First
Shorter than the web check’s 4 hours — in Crypto, the right classification makes the attack code fast, and the wrong classification means you won’t solve it anyway. So the route is classification-centered too:
0:00~0:20 Observe — list every given number/file, record digit counts and shapes
0:20~0:40 Classify — fix 2 candidates, design a verification experiment for each
0:40~2:30 Attack — eliminate in checklist order, write code
2:30~3:00 Wrap up — if solved, verify by reproduction; if not, record the stuck point
2-4. Distinguishing Implementation Bugs from Attack Failures — the Self-Authored-Problem Method
The unique challenge of independent Crypto solving. When your code doesn’t crack it, if you can’t tell whether the attack theory is wrong or the code is wrong, diagnosis is impossible. The answer is authoring your own problem:
1. Create a small problem of the same type yourself (a problem you know the answer to)
2. Run your attack code on that problem
3. If it solves → the code is fine; the attack theory (classification) is wrong → regress to classification
If it doesn't → a code bug → debug on the small problem
We’ve done this throughout the book — Step 234’s toy hash and Step 237’s mini problems were all self-authored problems. In the check, that habit becomes your stuck-point diagnostic.
2-5. The Utility Module — A Command Typed Twice Becomes a Function
Over 5 problems, you’ll catch yourself reusing the same code — modular inverses, byte↔integer conversion, exhaustive XOR, recovering d from factordb results. The check’s final deliverable is a crypto_util.py collecting these repeats. This module keeps growing past the next track (Forensics).
3. Follow Along
3-1. Declaring the Check
Before starting, fix the rules at the top of your document.
[Screen example — check declaration]
- problems: Dreamhack Crypto difficulty 2~3, 5 randoms from unsolved
- rules: 3 hours per problem, no write-up searches; technique docs and factordb allowed
- verdict: complete all 5 (reproduction verification included); viewing a write-up means replacement
- deliverables: record table + 5 solution documents + crypto_util.py v1
3-2. Working a Problem — Classification First (Screen Example)
[Screen example — problem B, first 40 minutes]
- given: output.txt — n (1024-bit), e=65537, c, plus "hint: p and q are friends"
- digit observation: n is normal size, e normal too → factordb? not there
- 2 candidates: ① Fermat factorization (the hint's "friends" = p≈q) ② Wiener (e is normal, so unlikely)
- verification experiment: is a²-n a perfect square near isqrt(n)? → hit after 47 tries
How to read it: translating the hint phrase ("friends") into a mathematical condition (p ≈ q) was the entire classification. With the translation right, the attack code is what you already wrote in Step 230.
3-3. When Stuck — Diagnose with a Self-Authored Problem (Screen Example)
[Screen example — problem D, at 1:50]
- type estimate: common modulus (same n, e1=7, e2=11, c1, c2)
- egcd(7, 11) → 7·(-3) + 11·2 = 1 → computed m = c1^-3 · c2^2 mod n
- result doesn't look like plaintext. Stuck.
- self-authored problem: generated the same structure with small primes → my code works correctly
- conclusion: code is sound → re-examine classification → the n's in the two ciphertexts were actually different (similar values). Reclassify.
How to read it: because you first proved "my code is correct on a small problem," you could push the failure’s cause outside the code (observation/classification). This single diagnosis saves 3 hours.
3-4. Environment Rules During the Check
For the measurement to be fair, unify the environment too.
- Block notifications: turn off messenger and email alerts. An interrupted 3-hour block resets your focus
- Keep the notes window open: always keep the record document up next to your coding window. Classification candidates must be written before attacking — writing them after contaminates the measurement
- Fix your tools: go with your usual Python environment and editor. Don’t test new libraries on check day — mixing tool variables blurs the measurement
- A physical timer: run a separate visible timer, not a corner of your screen. Let a device, not your memory, enforce the cap
3-5. Judging Success — Reproduction and Formulas
Same criteria as Step 202:
- From the top — rerun the attack script alone in a fresh session
- Explain each step of the path with a one-line "why this attack" — in Crypto, including the formulas is mandatory (why a cube root works, why φ(n) appears)
- If the explanation stalls, that problem isn’t complete yet — shore it up in the solution-document phase
3-6. Handling Failure — Replacement and Retraining Addresses
The procedure when you exceed 3 hours.
- Turn off the timer and take your hands off
- Confirm the stuck point’s category via a self-authored problem and record it — was it a code bug, a classification error, or a completely unknown type?
- If it was an unknown type, that technique’s chapter is your retraining address — leave it in the classification table as "unsolved — review Step N"
- Remove this problem from the valid record and draw a new random problem to fill the 5
Failed problems become future practice problems. Retry them in a week or two and you’ll see how your classification eye has changed.
3-7. After the Check — 5 Solution Documents and the Utility Module
[Screen example — solution document format]
# Solution: Problem OOO
- **Given and observations**: (numbers and digit counts)
- **Classification**: 2 candidates → confirmed type, grounds for confirmation
- **Attack**: theory used (formulas) + code
- **Verification**: reproduction result, whether a self-authored problem was used
- **Utility candidates**: functions from this problem to extract into the module
Then collect the "utility candidates" from all 5 documents into crypto_util.py v1. Minimum contents: modinv, iroot (integer nth root), xor_brute, int<->bytes conversion, rsa_from_pq (p, q → d, decrypt).
4. Missions & Exercises
Mission — Independently Solving 5 Crypto Problems
- Randomly select 5 medium-difficulty Crypto problems per 2-2’s criteria and leave a selection record
- Apply the 3-hour cap and 2-3’s routine (observe → classify → attack → wrap up) to each
- For stuck problems, separate the cause into code/classification using 3-3’s self-authored-problem verification
- After completing all 5, write each solution document in the 3-7 format
- Organize frequently used code into
crypto_util.pyv1
Exercises
Exercise 1. Explain why this check uses 5-problem completion, unlike the web check (3 consecutive).
Exercise 2. Write the three steps of the "self-authored-problem verification method" in order, and connect each step’s verdict to the cause it points to.
Exercise 3. Explain the boundary between allowed and forbidden research on Crypto problems, using factordb as an example.
Exercise 4. Think about why the utility module is organized "after" the check, not "during" it.
5. Model Answers & Completion Criteria
Mission Model Answer
The skeleton of a completed check record:
[Screen example — 5-problem record table]
problem | time | classification (verified after) | breakthrough point | verdict
A | 1:10 | small e (e=3) | c+k·n cube root, k=41 | success (reproduced)
B | 0:55 | Fermat | a²-n square, hit at 47 | success (reproduced)
C | over 3:00 | (unconfirmed) | both candidates eliminated | fail → replaced
D | 2:35 | common modulus | reclassified after self-authored problem | success (reproduced)
E | 1:20 | single-byte XOR | 256 exhaustive + distinguisher | success (reproduced)
F(replacement)| 1:45 | factordb hit | p,q lookup → recover d | success (reproduced)
→ 5 problems completed including C's replacement
How to verify: ① was the selection random? ② does each success carry a reproduction procedure? ③ do the solution documents contain formula-based "why"s? ④ do stuck problems show traces of self-authored-problem diagnosis? ⑤ does crypto_util.py actually import and work?
Exercise Answers
Answer 1. Because Crypto’s variance between types is large, 3-in-a-row can’t rule out the possibility of "known types happening to come consecutively." Raising the sample to 5 forces type diversity, measuring classification ability broadly. In exchange, the consecutive condition is relaxed, and only write-up-viewed problems get replaced.
Answer 2. ① Create a small problem of the same type yourself (one you know the answer to). ② Run your attack code on it. ③ If it solves, the code is sound so the cause is classification/theory → regress to observation. If it doesn’t, it’s a code bug → debug on the small problem. The point is confirming the failure’s category first.
Answer 3. factordb is a tool — "a public DB of factorizations of n." Allowed is consulting a general tool; forbidden is viewing that problem’s write-up. That said, searching by problem title can surface a factorization that’s effectively the answer, so honest measurement states "whether factordb is allowed" explicitly in the opening declaration (recommended: allowed — it’s a tool used in the field too).
Answer 4. Because organizing midway blurs the boundary between "code for this problem" and "reusable functions," and one-off code ends up in the module. Only after 5 problems does "what repeated" show up as data, and only repeats earn module citizenship. Organizing is retrospective work after measurement.
Completion Criteria Checklist
- [ ] I left a random-selection record (candidate pool and random results)
- [ ] I kept the 3-hour cap and the observe → classify → attack → wrap-up routine per problem
- [ ] My process record includes classification clues, attacks attempted, failure reasons, breakthrough points
- [ ] I viewed no write-ups (only allowed tools like technique docs and factordb)
- [ ] On stuck problems, I separated code vs classification with a self-authored problem
- [ ] I verified each success by reproduction and wrote a formula-inclusive solution document
- [ ] Mission: 5 problems completed + 5 solution documents + crypto_util.py v1 complete
6. Common Pitfalls & Fixes
Wall 1. Starting to code without classifying
Symptom: your hands go to the editor the moment output.txt opens.
Cause: the web track’s "payload first" habit. In Crypto, code without classification burns the most time.
Fix: no keyboard for the first 20 minutes — fix it as time for copying the numbers to paper and noting digit counts. There’s a declarative reason the observation stage leads 2-3’s routine.
Wall 2. Endlessly patching, unsure whether the code or the theory is wrong
Symptom: you’ve been fixing the same function for an hour.
Cause: suspecting only the code, without 2-4’s separation.
Fix: switch to a self-authored problem immediately — a 5-minute small problem ends the diagnosis. Patching comes after diagnosis.
Wall 3. The 3 hours evaporate
Symptom: you cling to one attack and blow past the cap.
Cause: fixation on one candidate without an elimination order.
Fix: give each candidate a 40-minute internal cap. An eliminated candidate isn’t a failure — it’s data for the classification table. Past 2.5 hours, spend the rest on organizing the record.
Wall 4. You solved it but can’t explain it
Symptom: the flag came out, but the "why" column of the solution document stalls.
Cause: the code solved first and understanding hasn’t caught up — common in Crypto, and dangerous.
Fix: hold that problem’s verdict. Work the attack’s formulas by hand once (with small numbers). Once the hand derivation works, the document writes itself.
Wall 5. The utility module becomes a grab-bag
Symptom: functions that never repeated end up in the module.
Cause: the guess "I might use it later."
Fix: one criterion — only code used 2+ times across the 5 problems goes to the module. The rest stays inside solution documents. A module is a record of repetition, not inventory.
Wall 6. Making the self-authored problem too big
Symptom: the test problem you built for diagnosis itself won’t solve, doubling your stuckness.
Cause: the self-authored problem’s purpose is "confirming my code’s soundness," not difficulty — but you built it near the original problem’s size.
Fix: same structure, minimal size — 3~4-digit primes and a one-character message are enough. The criterion: a size where you can know the answer within 5 minutes of starting.
7. Summary
Today’s Concepts
| Concept | One-line explanation |
|---|---|
| Independent solving | Cracking a problem with no write-up, using only technique docs and tools |
| 5-problem completion | A sample size accounting for type variance — viewed problems get replaced |
| Observe → classify → attack | The standard route of a Crypto check — the first 20 minutes are hand and paper |
| Self-authored verification | A diagnostic that first proves code soundness on a problem whose answer you know |
| Reproduction + formulas | The verdict for Crypto success — dual verification of result and reason (formulas) |
| crypto utility module | A personal armory collecting only code repeated 2+ times |
Today’s Procedure
| Stage | What to do |
|---|---|
| Select | 5 randoms from unsolved medium difficulty, fix the declaration |
| Proceed | 3 hours per problem, observe → classify → attack → wrap up |
| Diagnose | When stuck, separate code/classification with a self-authored problem |
| Judge | Credit on reproduction success + formula explanation; replace if a write-up was viewed |
| Review | 5 solution documents + crypto_util.py v1 |
An Instinct More Important Than Commands
This check asks one thing — does your classification routine stand on its own in front of a bare list of numbers. The right answer isn’t completing 5 problems; it’s the density of observations and eliminations recorded along the way, and the habit of reaching for a self-authored problem when stuck. If you’ve passed this stretch, you’re no longer "someone who learned cryptography" but "someone who attacks ciphers." You’ve earned the right to exit the Crypto track’s door.
Once every box is checked, Step 238 is complete. Click the checkbox in the sidebar to save your progress.