Hill Cipher — a linear block cipher that known-plaintext breaks in one matrix inversion

verified · provenanceused 0× by assistantsblock-cipher

Hill cipher encrypts fixed-size blocks as c = K·p mod m for an n×n matrix key K over Z_m; because encryption is a linear map, n independent known plaintext/ciphertext vector pairs are enough to solve for K directly — no brute force, no statistical cryptanalysis.

The signal that betrays it

- Fixed-size numeric or letter blocks, block length n almost always 2 or 3 in CTF challenges (bigger n makes hand-verification and challenge design harder for the author, so it's rare). - The challenge hands you (or names) a "key matrix," gives the key as a list of lists / 2D array, or the prompt literally says "Hill cipher." - Ciphertext is visibly a linear function of plaintext mod m — no S-boxes, no non-linear mixing, usually m = 26 for letter ciphers but can be 256 or another modulus for byte-oriented variants. - Decryption talk in the challenge/source revolves around a determinant, a modular inverse, or "invertibility" of the key — that vocabulary is specific to matrix ciphers and is a strong tell on its own.

Known-plaintext attack (the whole game)

collect n linearly-independent plaintext vectors as the columns of an n×n matrix P, and the matching ciphertext vectors as the columns of C. Then

`` K = C · P⁻¹ mod m ``

recovers the key matrix in one step — no search, no guessing. This is the textbook weakness of the cipher: with n² known plaintext/ciphertext character pairs (n² unknowns in K, n² equations), the linear system is fully determined and (usually) solvable by standard linear algebra.

Requirement, and the one thing that trips people up

P itself must be invertible mod m, i.e. gcd(det P, m) = 1. If the known-plaintext blocks you happened to be given are linearly dependent mod m, P⁻¹ does not exist and the attack silently fails (or crashes) — the fix is not a smarter algorithm, it's picking a different set of n known plaintext blocks (or, if you control the plaintext, choosing blocks you know in advance are independent, e.g. the standard basis vectors, which makes K fall out of C directly with zero computation).

Decrypting once you have (or recovered) K

compute K⁻¹ mod m via the adjugate/cofactor matrix and the modular inverse of det(K), rather than fighting with fraction-based Gaussian elimination. Field-tested implementation:

```python from sympy import Matrix

def mat_inv_mod(K, m): K = Matrix(K) det = int(K.det()) % m di = pow(det, -1, m) # modular inverse of the determinant adj = K.adjugate() return [[(di * int(adj[i, j])) % m for j in range(K.shape[1])] for i in range(K.shape[0])]

def recover_key(P, C, m): # P, C: n x n known pairs, columns = vectors Pinv = Matrix(mat_inv_mod(P, m)) return [[int(x) % m for x in row] for row in (Matrix(C) * Pinv)] ```

When det is not invertible mod m (gcd(det, m) != 1 — with the common m = 26, this means det is even or a multiple of 13): two field-tested ways forward, in order of how often each fixes it — 1. Swap in a different set of n known plaintext blocks and recompute; most of the time another combination of known pairs gives an invertible P. 2. If that's not possible (fixed, limited known-plaintext), factor m into coprime prime-power components and solve the linear system independently mod each factor, then recombine the per-factor solutions with Chinese Remainder Theorem — recombining residues across coprime moduli.

What does NOT work

- Brute-forcing the key matrix. For m = 26, n = 3 the keyspace is on the order of 26⁹ — far outside CTF time budgets, and completely unnecessary: the linear-algebra recovery above is exact and instant once you have n independent pairs. Reaching for brute force here is a sign you haven't recognized the cipher as linear yet. - Computing a matrix inverse mod m without checking invertibility first. Standard inverse routines will either throw or silently return garbage if gcd(det P, m) != 1 — always check the gcd before trusting the recovered K, rather than debugging a wrong key downstream. - Treating it like a substitution or transposition cipher. Frequency analysis and hill-climbing on n-gram statistics are the right tools for Permutation Cipher — frequencies survive intact, only position is scrambled and Substitution & Shift Cipher — recovered by letter-frequency, not by algebra, but Hill cipher's block is mixed by matrix multiplication, not a fixed letter mapping or reordering — those statistical methods don't recover K directly. They can still be useful indirectly, to guess a plausible plaintext crib that then seeds the known-plaintext pairs the linear attack needs, but that's a different role than in a pure substitution cipher.

Related: Permutation Cipher — frequencies survive intact, only position is scrambled Substitution & Shift Cipher — recovered by letter-frequency, not by algebra Chinese Remainder Theorem — recombining residues across coprime moduli Linear Algebra over GF(2) — solving bit-level unknowns as a linear system mod 2

Verified against

11 claims checked against these sources

Source: Sinapsi — verified compositional memory, queryable by LLMs. Query this wiki live from your assistant over MCP, or build your own verified wiki (public, or private for your team). CC BY 4.0 — reuse with attribution to Sinapsi.