Skip to content

feat: close the dCode / CrypTool 2 coverage gaps - #7

Merged
0xdiid merged 2 commits into
mainfrom
feat/dcode-cryptool-gap-closure
Jul 30, 2026
Merged

feat: close the dCode / CrypTool 2 coverage gaps#7
0xdiid merged 2 commits into
mainfrom
feat/dcode-cryptool-gap-closure

Conversation

@0xdiid

@0xdiid 0xdiid commented Jul 30, 2026

Copy link
Copy Markdown
Owner

No description provided.

0xdiid and others added 2 commits July 30, 2026 14:29
A capability audit against dCode and CrypTool 2 (docs/gap-analysis.md) found four
real holes and one CLI-surface gap. All five are closed. Every cipher is validated
against a published vector before its cracker is trusted, and every cracker is
plant-gated on settings it planted itself.

New cipher types:

* polybius  — existed as PolybiusSquare inside 22 files but was not a registry
  entry, so `butt encode polybius` did not work. Solved outright: each coordinate
  pair is one plaintext letter, so relabelling turns it into the monoalphabetic
  problem the substitution solver already handles.
* collon    — the last missing 5x5 grid cipher. Annealing the square (the obvious
  attack) scored 0/5 in 45s; the ciphertext can only contain ten distinct letters,
  which makes it another monoalphabetic solve. 5/5 in 1.7s.
* ubchi     — WWI German double columnar reusing one key. The reuse is the
  weakness: widths 2..8 are under 46000 orders, so the permutation is enumerated.
* chaocipher — Byrne's dynamic alphabets; matches Exhibit 1 exactly. crack returns
  [] by design: one wrong cell corrupts the whole remaining decrypt, so a nearly
  correct key scores like a random one and there is no gradient to climb.
* m94       — Jefferson cylinder with the documented 25-disk table. Positions j and
  j+width share a disk, making the disk order a bipartite assignment solved exactly
  by Hungarian plus an n-gram climb: a full 25-disk order from 228 letters in <1s.
* enigma    — M3, rotors I-VIII, reflectors B/C, rings, plugboard. Matches
  AAAAA -> BDZGO and the canonical 26-letter output. crack is Gillogly's three
  phases; a 60-rotor-order sweep runs in ~2.5 min.

buttcrack.wrappers — the transport layer a puzzle wraps around its cipher, wired
into `butt transform`: repeating-key XOR with key-length recovery, base32/85/N,
ROT47/5/18, keyboard geometry, phone keypad, tap code, NATO, Braille, and a generic
Transcriptor. New flags: --xor, --apply, --wrap, --transcribe, --list-wrappers.

stats --autocorrelation / --friedman — both computations already existed but were
unreachable from the CLI and ungated. Exposing them showed neither was fit to
report, and both had been feeding diagnose and cipher_id all along:

* Scoring lags against the 1/26 floor makes every lag significant for
  monoalphabetic or transposed text, so a harmonic search always found a period.
  Now gated on IoC and reported as a refusal. 4/4 false positives removed.
* Ranking a period by its own lag is backwards — English is anti-correlated at
  distance 2-3, so a true period-2 key reads z<0 at lag 2 while lags 4, 6, 8 spike.
  Plant gate 3/12 -> 18/19.
* A key repeating a letter d apart makes lag d genuinely coincide, so
  candidate_periods reports the ladder instead of one confidently wrong number.

Also hardened: XOR key length is chosen by a length-penalised quadgram score (raw
fitness rises monotonically with key length, so the winner was always max_keysize),
and letters-in/letters-out wrappers must read as English before being reported.

The word-length leak gate now covers 10 ciphers instead of 2, with a matching
assertion for the coordinate ciphers whose output is digits.

Not implemented, with reasons in the wrappers docstring: ROT8000, PGP word list,
periodic table, DTMF, semaphore, pigpen. Enigma and Chaocipher are excluded from
`auto` because their searches take minutes, not the seconds `auto` budgets.

Tests: 970 fast tests pass; 179 are new.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CI's lint gate was failing on this branch: two I001 unsorted-import
blocks (ciphers/__init__.py, ciphers/collon.py) and five files whose
compact multi-entry dict/expression layout ruff format rejects.

Formatting only — no behavior change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159mM39E2XA2ExfLsB1VUXW
@0xdiid
0xdiid merged commit 57b2620 into main Jul 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant