Three concerns I’m seeing in your post —
Standard MQ arsenal (Sage, CMS, Magma, linearization) → silent. Hours in.
“Kente” feels like a hint, but the system isn’t surfacing the structure.
Hints over flags — you want the win to feel earned.
You’ve done the right things in the right order, and the wall isn’t where it usually is. Let me hand you the angle nobody asks first.
Translating your question into plain words:
“Every thread is a switch. The right pattern of switches spells the flag. But standard solvers won’t lock onto that pattern.”
Under the hood that’s just MQ over GF(2) — nothing exotic. So why does the kente metaphor keep coming back at you?
Because the puzzle’s name is the math problem.
There’s a paper from March 2025 that defines exactly the structure your kente metaphor describes. Except they don’t call it kente — they call it the Regular Multivariate Quadratic problem.
Joux & Mora — The regular multivariate quadratic problem (arXiv: 2503.07342)
Kente cloth |
RMQ math |
| Cloth = row of fixed-width strips |
Vector of length n = lw split into w blocks of length l |
| Each strip carries one specific pattern |
Each block has exactly one nonzero entry |
| Whole cloth = woven pattern of strips |
The solution is a regular vector |
Bonus: Joux is also the inventor of the Crossbred algorithm — the SOTA tool that beats every standard MQ solver on this size range. Same author. Six months apart. Problem and matching weapon.
⚡ The 30-second test (run this now)
Open system.txt in Sage. Check how dense your equations actually are:
M = matrix(GF(2), [[1 if v in eq.variables() else 0 for v in vars] for eq in eqs])
print(M.density())
| Result |
Verdict |
| Density < 0.3 (sparse) |
Kente hypothesis alive → go to next section |
| Density ≈ 0.5 (random) |
Kente was flag content not method → check raw file bytes / strings |
Either way, 30 seconds in you’ve ruled out a 4-hour rabbit hole. That’s already a win.
🎯 If density says "sparse" — the structural fix
Add three families of equations to your system before the next groebner_basis() call. These are §4.1 of the paper — the structural information your tools haven’t been exploiting:
|
Equation |
What it forces |
 |
xᵢ,j₁ · xᵢ,j₂ = 0 (every pair in a block) |
At most one nonzero per block |
 |
Σⱼ xᵢ,j = 1 (per block) |
Exactly one per block — this one pays, eliminates one var per block |
 |
xᵢ,j² = xᵢ,j |
Field equations (Sage adds these via BooleanPolynomialRing) |
🔍 Don't yet know `l` (block width) or `w` (block count)? Open here
Two ways to find them in 5 minutes:
- Variable indexing. If vars are named
x_0_1, x_0_2, ..., x_1_1, ... — that two-index pattern is your l and w.
- Total count factorize. If vars are flat
x_0, x_1, ..., factorize the count. Kente strips come in tidy ratios — 60 = 6×10, 48 = 6×8, 64 = 8×8. Try the ones that look weave-shaped.
If neither works, post the variable-naming pattern in this thread — I (or someone) can probably eyeball it.
| What’s bugging you |
What to actually do |
Time |
| Sage hangs / OOM |
You’re solving the unstructured version. Add the equations above. Retry. |
30 min |
| Want a CPU-only fallback |
libfes-lite — stupidly fast for n ≤ 50 |
1 hour |
| File parsing is eating the evening |
hadipourh/mqchallenge converts to Sage in one shot |
5 min |
| Stuck after the structural fix |
CryptoHack Discord #challenge-hints |
Same hour |
🛠️ Do This In This Order — the full playbook
Quick re-ground for anyone who skipped here: the team’s stuck on a 500-point boolean MQ challenge. Hypothesis: structured Regular-MQ. This block is the toolkit end-to-end.
Already know F4/F5 + Macaulay matrices? Skip to Step 3. Steps 1–2 are setup most of you’ve already done.
Discord etiquette while the event is live: don’t post your equations. Just say “MQ over GF(2), n=, m=, structure looks regular-block — what would you reach for?” That gets the right pointer without bending any rules.
| Situation |
Move |
Density < 0.3, vars indexed xᵢ,j |
Kente = RMQ → Step 3 |
| Density ≈ 0.5, var names random |
Check raw file bytes / strings |
n ≤ 40, 8+ CPU cores |
libfes-lite finishes before the rewrite does |
n > 60, any GPU available |
mqsolver is the tool |
🌱 New to CTFs and curious what's even happening here? Welcome
A Capture-The-Flag (CTF) is a security puzzle competition — teams race to find a hidden string called the flag by solving challenges. Sometimes it’s reverse-engineering, sometimes web vulns. Here it’s pure math.
The math underneath this thread:
- GF(2) — a tiny number system where the only numbers are
0 and 1. Adding flips bits. Multiplying behaves like AND. That’s it.
- Multivariate quadratic — a bunch of equations where each one mixes pairs of variables (like
x·y + x + 1 = 0). Solving them simultaneously is the hard part.
- The flag here gets encoded as a long string of
0s and 1s. Figure out which variables are 1 and which are 0, decode the bytes, that’s the flag.
Why it’s hard: with 64 switches there are already 18 quintillion possible patterns. You can’t just try them — you exploit structure. That’s what the rest of this thread is doing.
Want a friendly intro? CryptoHack has a polished beginner path — start with their Mathematics and Symmetric Ciphers sections.
🐛 Why your Sage probably hung (failure-mode diagnosis)
| Tool |
What broke |
groebner_basis() |
F4/F5 memory blows up at degree-of-regularity ≥ 4 for unstructured systems above ~30 vars. Fix: add structural equations first (Step 3 above). |
| CryptoMiniSat raw ANF→CNF |
Naïve encoding makes 1 clause per monomial — astronomical CNF. Fix: use Bosphorus as preprocessor. |
Magma GroebnerBasis |
Best implementation on the planet, same structural blind spot. Sneaky fix: check your academic license isn’t capping at 600s and silently truncating output. |
📓 Why this is the meta-strategy that solves most CTF MQ challenges
Almost every CTF MQ challenge above 200 points is built on a published cryptanalysis paper. The puzzle author isn’t inventing new math — they’re scaffolding a known attack. Two moves repeat across solved writeups:
- Title is the pointer. “MPKC,” “HFE-Lite,” “Rainbow’s Last Dance,” “Kente” — search the title against arXiv and IACR ePrint.
- Once you find the paper, follow Section 3 (the exploit plan) literally. Most published cryptanalyses ship with a 3–5 step exploit recipe. CTF authors don’t usually deviate.
The pcw109550 PlaidCTF MPKC writeup is the cleanest demonstration — they searched the challenge’s source comments, found Chen et al. 2020/053, and copy-pasted the paper’s Section 3 into Sage. Whole solve is 80 lines.
Same trick is almost certainly the one for Kente.
Honest tell — I personally lean on libfes-lite for any boolean MQ under 50 vars. Once watched it crack a 40-var system in about 9 minutes on a 2019 laptop while Sage was still computing the Macaulay matrix. Not glamorous, just stupidly fast where it works — and “stupidly fast where it works” is exactly what you want when there’s a clock running.
You said “hints over flags — we want to feel the win.”
The win you’re chasing is the moment you spot why the puzzle is named what it’s named.
If the density test comes back low, that moment is ten minutes away. The rest of the path is mostly typing. 
One quick question back at you — when you ran linearization, what fell out of the kernel? Empty, dimension 1, or higher?
That single number tells me which step of the playbook you’re actually on.