munotes®

Transposition Systems

Get access to whole semester resourcesSemester Pass

Chapter Ninety

Syllabus topic Module 2, "Substitution and transposition systems"

Pages 323 to 327 of 378

In one line

A transposition cipher keeps every letter and rearranges them, so the ciphertext has exactly the same letters as the plaintext in a different order.

In the wording you can write in an examination: a transposition cipher enciphers by permuting the positions of the symbols of the plaintext according to the key, without altering the symbols themselves. The rail fence writes the text in a zigzag across a number of rows and reads it off row by row; the columnar transposition writes it in rows of fixed width and reads the columns in an order determined by the key.

The rail fence

The rule. Choose a number of rails. Write the text diagonally down and up across them. Read it off one rail at a time.

Worked by hand, three rails, on SENDTHEARMYATDAWN.

rail 0 S...T...R...T...N

rail 1 .E.D.H.A.M.A.D.W.

rail 2 ..N...E...Y...A..

Reading rail 0, then rail 1, then rail 2 gives STRTN EDHAMADW NEYA.

The key is the number of rails, and that is its whole weakness: with a text of any length only a handful of rail counts are worth trying, so the key space is a few dozen at most.

The columnar transposition

The rule. Write the text in rows of width equal to the key's length. Number the columns by the alphabetical order of the key's letters. Read the columns off in that numbered order.

Worked by hand, key ZEBRAS, on the same text.

The key's letters in alphabetical order are A, B, E, R, S, Z, so the column holding A is read first, then B, then E, then R, then S, then Z.

key Z E B R A S

order 6 3 2 4 1 5

row 1 S E N D T H

row 2 E A R M Y A

row 3 T D A W N X

Read column 5 first, which is T Y N; then column 2, N R A; then column 1... no: read the column whose key letter comes first alphabetically. A is in position 5, so T Y N. B is in position 3, so N R A. E is in position 2, so E A D. R is in position 4, so D M W. S is in position 6, so H A X. Z is in position 1, so S E T.

Ciphertext: TYN NRA EAD DMW HAX SET.

The padding problem

Seventeen letters do not fill three rows of six. One cell is left over, and the program fills it with X.

Three consequences, and all three are practical.

The ciphertext is longer than the plaintext. Anyone who sees the length knows something.

The padding must be removable. The recipient of SENDTHEARMYATDAWNX has to know that the final X is not part of the message. If the plaintext might legitimately end in X, they cannot.

munotes.in323

Transposition Systems

And where the padding is added matters. [Arthaśāstra-Inspired Cryptography as a Symmetric Cipher System] records a real bug in this book's own code: padding after the substitution step meant the inverse substitution turned the pad into a different letter, and a message round-tripped as SENDTHEARMYATDAWNYYYYYYY.

Both, run

"""Transposition, worked: rail fence and columnar."""
import string
A = string.ascii_uppercase

def clean(t):
    return "".join(c for c in t.upper() if c in A)

def rail_pattern(n, rails):
    out, r, step = [], 0, 1
    for _ in range(n):
        out.append(r)
        if r == 0:
            step = 1
        elif r == rails - 1:
            step = -1
        r += step
    return out

def rail_fence(text, rails, decrypt=False):
    n = len(text)
    pat = rail_pattern(n, rails)
    order = [i for rr in range(rails) for i in range(n) if pat[i] == rr]
    if not decrypt:
        return "".join(text[i] for i in order)
    out = [""] * n
    for pos, i in enumerate(order):
        out[i] = text[pos]
    return "".join(out)

def columnar(text, key, decrypt=False, pad="X"):
    k = [c for c in key.upper() if c in A]
    cols = len(k)
    order = sorted(range(cols), key=lambda i: (k[i], i))
    if not decrypt:
        body = text + pad * ((-len(text)) % cols)
        rows = [body[i:i + cols] for i in range(0, len(body), cols)]
        return "".join("".join(r[c] for r in rows) for c in order)
    rows_n = len(text) // cols
    chunks, at = {}, 0
    for c in order:
        chunks[c] = text[at:at + rows_n]
        at += rows_n
    return "".join(chunks[c][r] for r in range(rows_n) for c in range(cols))

MSG = clean("SEND THE ARMY AT DAWN")
print("plaintext", MSG, "(%d letters)" % len(MSG))

print()
print("rail fence, three rails: the pattern of rails, then the read-off")
pat = rail_pattern(len(MSG), 3)
for r in range(3):
    print("  rail %d  %s" % (r, "".join(MSG[i] if pat[i] == r else "." for i in range(len(MSG)))))
ct = rail_fence(MSG, 3)
print("  ciphertext %s" % ct)
print("  decrypted  %s" % rail_fence(ct, 3, decrypt=True))

print()
print("rail fence with two to five rails")
for rails in range(2, 6):
    c = rail_fence(MSG, rails)
    print("  %d rails  %-20s round trip %s" % (rails, c, rail_fence(c, rails, decrypt=True) == MSG))

print()
print("columnar transposition under the key ZEBRAS")
KEY = "ZEBRAS"
k = list(KEY)
order = sorted(range(len(k)), key=lambda i: (k[i], i))
body = MSG + "X" * ((-len(MSG)) % len(k))
rows = [body[i:i + len(k)] for i in range(0, len(body), len(k))]
print("  key      %s" % "  ".join(k))
print("  read in  %s" % "  ".join(str(order.index(i) + 1) for i in range(len(k))))
for r in rows:
    print("  row      %s" % "  ".join(r))
ct2 = columnar(MSG, KEY)
print("  ciphertext %s" % ct2)
print("  decrypted  %s" % columnar(ct2, KEY, decrypt=True))

print()
print("the repeated key letter, which is where a careless columnar breaks")
for key in ("ANNA", "ZEBRAS", "AAAA"):
    c = columnar(MSG, key)
    back = columnar(c, key, decrypt=True)
    print("  key %-8s ciphertext %-26s round trip %s" % (key, c, back.startswith(MSG)))

print()
print("letter counts are unchanged by transposition")
from collections import Counter
print("  plaintext  ", sorted(Counter(MSG).items()))
print("  ciphertext ", sorted(Counter(rail_fence(MSG, 3)).items()))
print("  identical:", Counter(MSG) == Counter(rail_fence(MSG, 3)))
munotes.in324

Transposition Systems

plaintext SENDTHEARMYATDAWN (17 letters)

rail fence, three rails: the pattern of rails, then the read-off
  rail 0  S...T...R...T...N
  rail 1  .E.D.H.A.M.A.D.W.
  rail 2  ..N...E...Y...A..
  ciphertext STRTNEDHAMADWNEYA
  decrypted  SENDTHEARMYATDAWN

rail fence with two to five rails
  2 rails  SNTERYTANEDHAMADW    round trip True
  3 rails  STRTNEDHAMADWNEYA    round trip True
  4 rails  SETEHAADNTRYANDMW    round trip True
  5 rails  SRNEAMWNEYADHADTT    round trip True

columnar transposition under the key ZEBRAS
  key      Z  E  B  R  A  S
  read in  6  3  2  4  1  5
  row      S  E  N  D  T  H
  row      E  A  R  M  Y  A
  row      T  D  A  W  N  X
  ciphertext TYNNRAEADDMWHAXSET
  decrypted  SENDTHEARMYATDAWNX

the repeated key letter, which is where a careless columnar breaks
  key ANNA     ciphertext STRTNDAAWXEHMDXNEYAX       round trip True
  key ZEBRAS   ciphertext TYNNRAEADDMWHAXSET         round trip True
  key AAAA     ciphertext STRTNEHMDXNEYAXDAAWX       round trip True

letter counts are unchanged by transposition
  plaintext   [('A', 3), ('D', 2), ('E', 2), ('H', 1), ('M', 1), ('N', 2), ('R', 1), ('S', 1), ('T', 2), ('W', 1), ('Y', 1)]
  ciphertext  [('A', 3), ('D', 2), ('E', 2), ('H', 1), ('M', 1), ('N', 2), ('R', 1), ('S', 1), ('T', 2), ('W', 1), ('Y', 1)]
  identical: True

Reading the output

The rail pattern is printed, so the zigzag is visible rather than described. Rail 0 takes every fourth letter, rail 2 takes every fourth offset by two, and rail 1 takes the rest.

Four rail counts all round-trip, which is the minimum test for any cipher: encipher, decipher, compare.

The columnar working is printed as the grid, with the key, the reading order and the rows, so the hand method and the program agree line for line.

Three keys including a repeated letter all round-trip. ANNA has two Ns, and the two N columns must be read in a fixed order or the message does not come back. The program sorts by the letter and then by the position, which is a stable sort, and that is what makes ANNA work. A sort that is not stable would give two different column orders on two different machines, and the message would decipher on one and not the other.

And the last block is the defining property. The letter counts of the plaintext and of the ciphertext are identical, and the program compares them rather than asserting it.

munotes.in325

Transposition Systems

What that property means for an attacker

Frequency analysis is useless against a pure transposition. The ciphertext's letter frequencies are the plaintext's, which are English's, and they say nothing about the key.

But the same fact identifies the cipher. An attacker who sees a ciphertext with normal English letter frequencies and no readable words knows at once that it is a transposition and not a substitution. The defining property is also the giveaway.

And what does break it. Anagramming: try likely arrangements and look for common letter pairs. A transposition preserves which letters are present, so a pair like TH must be somewhere, and the attacker looks for arrangements that bring likely pairs together. For the rail fence, trying every rail count is enough.

Why both primitives are needed

SubstitutionTransposition
Changesthe identity of the lettersthe position of the letters
Preservespositionidentity, and therefore the letter counts
Broken byfrequency analysisanagramming, or trying the small key space
Betrays itself byan abnormal frequency profilea normal frequency profile with no words

Neither alone survives. Substitution leaves the frequencies to be read; transposition leaves the letters to be rearranged.

Composed, each covers the other's weakness. The substitution disturbs the frequencies so anagramming has less to go on, and the transposition breaks up the letter positions so frequency analysis cannot be confirmed by reading words. That is why every practical classical system used both, and it is what MU's label "substitution and transposition systems" is naming as a pair.

Quick revision

  • Transposition permutes positions and leaves symbols alone, so the letter counts are exactly preserved.
  • Rail fence: zigzag across a number of rails, read off rail by rail. The key is the rail count, so the key space is tiny.
  • Columnar: rows of the key's width, columns read in the alphabetical order of the key's letters.
  • Padding is needed to fill the last row, which lengthens the ciphertext, must be removable, and must be added at the right stage.
  • A repeated key letter needs a stable sort, or the column order is not reproducible.
  • Frequency analysis is useless against a transposition, and the normal frequency profile is what identifies it as one.
  • Neither primitive survives alone; composed, each covers the other's weakness.

Test yourself

1. Encipher ATTACK with a three-rail fence, showing the rails.

Rail 0 takes A and C; rail 1 takes T, A and K; rail 2 takes T. Reading rail by rail gives AC TAK T, that is, ACTAKT.

2. Why must a columnar transposition sort a repeated key letter by position as well as by letter?

Because two identical key letters give two columns with the same sort key, and an unstable sort may order them either way. The order must be the same when enciphering and deciphering, so the position is used as a tie-break.

munotes.in326

Transposition Systems

3. What does the preservation of letter counts cost the attacker, and what does it give them?

It costs them frequency analysis, since the ciphertext's frequencies are the language's and say nothing about the key. It gives them the identification: a ciphertext with normal letter frequencies and no readable words is a transposition.

4. Why is a composition of the two primitives stronger than either?

Because substitution disturbs the frequency profile, which is what anagramming a transposition relies on for confirmation, and transposition scatters the positions, which is what reading words off a substitution relies on. Each covers the other's weakness.

munotes.in327

The rest of this subject

These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.

Issue
Done!