ICTCM 12  •  Burlingame, CA, 1999

Tutorial on Hill ciphers

Alphabet

alf = Characters["ABCDEFGHIJKLMNOPQRSTUVWXYZ.? "]

m  =  Length[alf]

Encode alphabet

Range[m]  -  1

Key matrix

A  =  { {17, 5, 20},  {23, 9, 3},  {11, 2, 
            12} };
A  //  MatrixForm

n  =  Length[A]

Example 1: encipher one n-gram

plaintxt  =  {"W",  "A",  "N"}

inNums  =  
      Flatten@Table[
          Position[
              alf,   plaintxt[[j]]] - 
            1,  {j,  1,  3}]

A  .  inNums

outNums  =  Mod[A  . inNums,  m]

ciphertxt  =  
      alf[[outNums  +  1]]

Example 2: encipher plaintext string

plaintxt  =  {"W", "A", "N", "T", " ", "H", "\
E", "L", "P", "."}

inNums  =  
      Flatten @ 
        Table[Position[
              alf,   plaintxt[[j]]] - 
            1,  {j,  1,  Length@plaintxt}]

Length[inNums]
n

inNums  =  Join[inNums,  Table[Last[inNums],  {2}]]

inMat  =  Partition[inNums,  n];  
    inMat  //  MatrixForm

inMat  =  Transpose[inMat];  inMat  //  MatrixForm

outMat  =  Mod[A   .  inMat,  m] ;   outMat  //  
      MatrixForm

outMat  =  Mod[outMat,  m];   outMat  //  MatrixForm

outNums  =  Flatten @ Transpose[outMat]

ciphertxt  =  
      alf[[outNums  +  1]]

Example 3: advantage of polygraphic cipher

New key matrix:

A  =  { {8, 6, 9, 5},  {6, 9, 5, 10},  {5, 8, 4, 9},  {10, 6, 11, 
          4} };  A  //  MatrixForm
n  =  Length[A];

txt1  =  "DESTROY PLANE";
txt2  =  "DEPLOY PLANES";
plaintxt1  =  Characters @ txt1
plaintxt2  =  Characters @ txt2

inNums1  =  
        Flatten @ 
          Table[Position[
                alf,   plaintxt1[[
                  j]]] - 1,  {j,  1,  
              Length@plaintxt1}];
inNums2  =  
        Flatten @ 
          Table[Position[
                alf,   plaintxt2[[
                  j]]] - 1,  {j,  1,  
              Length@plaintxt2}];

{Length[inNums1],  Length[inNums2],  n}

inNums1  =  
        Join[inNums1,  
          Table[Last[inNums1],  {3}]];
inNums2  =  
        Join[inNums2,  Table[Last[inNums2],  {3}]];

inMat1  =  
        Transpose @ Partition[inNums1,  n];
inMat2  =  Transpose @ Partition[inNums2,  n];

outMat1  =  
        Mod[A   .  inMat1,  m] ; 
outMat2  =  Mod[A   .  inMat2,  m] ;

outNums1  =  
        Flatten @ Transpose[outMat1];
outNums2  =  Flatten @ Transpose[outMat2];

StringJoin[
      ciphertxt1  =  
        alf[[outNums1  +  
            1]]]
StringJoin[
      ciphertxt2  =  
        alf[[outNums2  +  
            1]]]

⚠  Totally different!

Main

Copyright © 1999 by Murray Eisenberg