Introduction
Whilst doing some research on cryptography, I came across the Chaocipher.
This cipher was invented by the late John F. Byrne in 1918 and defied all
attempts to break it until details of the algorithm used were disclosed by his
family in 2010.
A paper entitled
Chaocipher Revealed : The Algorithm was published by Moshe Rubin in July
2010 and forms the basis of this article.
How does the cipher work?
For full details of how the cipher is applied, you should consult Mr Rubin's
paper which, by cryptographic standards, is very easy to read and understand.
Briefly, the idea is that you start with two alphabets: a 'left' alphabet (for
ciphertext) and a 'right' alphabet (for plaintext).
You then convert each letter in the plaintext to ciphertext by looking up the
index of the former in the right alphabet and then using that index of read off
the corresponding ciphertext letter from the left alphabet.
However, unlike a normal substitution cipher, you then make some permutations to
both the left and right alphabets before encrypting the next letter. Similar
operations are carried out after encrypting each letter until the plaintext is
exhausted.
Decryption follows a similar pattern except that the permutations used are
slightly different from those used in encryption.
This is a clever idea which is known as an 'autokey' cipher in cryptography
because the next key is generated from the previous one. Clearly, the
permutations used need to be such that they can be easily reversed by the
decryption process.
C# Implementation
Although a C# implementation is said to exist, I could not find it on the
internet and so have written my own.
The following console application is based on the algorithm described in Mr
Rubin's paper and uses the example which he gives so we can check that it is
working correctly. The resulting ciphertext is then decrypted back to the
plaintext.
No attempt has been made to optimize the code though, for a large piece of
plaintext, performance could almost certainly be improved by using unsafe code
and pointers to manipulate the character arrays.
The code is also available in the accompanying download:
using
System;
static
class Chao
{
private static
string lAlphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ";
private static
string rAlphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC";
public static
string Encrypt(string
plainText)
{
char[] left = lAlphabet.ToCharArray();
char[] right = rAlphabet.ToCharArray();
char[] pText = plainText.ToCharArray();
char[] cText =
new char[pText.Length];
char[] temp =
new char[26];
int index;
char store;
for(int i = 0; i
< pText.Length; i++)
{
Console.WriteLine("{0}
{1}", new string(left),
new string(right));
index =
Array.IndexOf(right, pText[i]);
cText[i] =left[index];
if (i == pText.Length - 1)
break;
// permute left
for(int j =
index; j < 26; j++) temp[j - index] = left[j];
for(int
j = 0; j < index; j++) temp[26 - index + j] = left[j];
store = temp[1];
for(int
j = 2; j < 14; j++) temp[j - 1] = temp[j];
temp[13] = store;
temp.CopyTo(left, 0);
// permute right
for(int
j = index; j < 26; j++) temp[j - index] = right[j];
for(int
j = 0; j < index; j++) temp[26 - index + j] = right[j];
store = temp[0];
for(int
j = 1; j < 26; j++) temp[j - 1] = temp[j];
temp[25] = store;
store = temp[2];
for(int
j = 3; j < 14; j++) temp[j - 1] = temp[j];
temp[13] = store;
temp.CopyTo(right, 0);
}
return new
string(cText);
}
public static
string Decrypt(string
cipherText)
{
char[] left = lAlphabet.ToCharArray();
char[] right = rAlphabet.ToCharArray();
char[] cText = cipherText.ToCharArray();
char[] pText =
new char[cText.Length];
char[] temp =
new char[26];
int index;
char store;
for(int i = 0; i
< cText.Length; i++)
{
// Console.WriteLine("{0} {1}", new string(left), new
string(right));
index =
Array.IndexOf(left, cText[i]);
pText[i] = right[index];
if (i == cText.Length - 1)
break;
// permute left
for(int j =
index; j < 26; j++) temp[j - index] = left[j];
for(int
j = 0; j < index; j++) temp[26 - index + j] = left[j];
store = temp[1];
for(int
j = 2; j < 14; j++) temp[j - 1] = temp[j];
temp[13] = store;
temp.CopyTo(left, 0);
// permute right
for(int
j = index; j < 26; j++) temp[j - index] = right[j];
for(int
j = 0; j < index; j++) temp[26 - index + j] = right[j];
store = temp[0];
for(int
j = 1; j < 26; j++) temp[j - 1] = temp[j];
temp[25] = store;
store = temp[2];
for(int
j = 3; j < 14; j++) temp[j - 1] = temp[j];
temp[13] = store;
temp.CopyTo(right, 0);
}
return new
string(pText);
}
}
class
Program
{
static void
Main()
{
string plainText =
"WELLDONEISBETTERTHANWELLSAID";
Console.WriteLine("The
original plainText is : {0}", plainText);
Console.WriteLine("\nThe
left and right alphabets after each permutation during encryption are\n");
string cipherText =
Chao.Encrypt(plainText);
Console.WriteLine("\nThe
ciphertext is {0}", cipherText);
string plainText2 =
Chao.Decrypt(cipherText);
Console.WriteLine("\nThe
recovered plaintext is {0}", plainText2);
Console.ReadKey();
}
}
Output
A screen-shot of the output is shown below.
The print out of the left and right alphabets after each permutation during the
decryption process has been suppressed as the output would otherwise have
exceeded the length of a maximized console window on my machine:
Conclusion
I am not sure how strong this cipher is by modern cryptographic standards but
clearly, relative to the effort needed to implement it, it is very strong
indeed!
Although the present implementation only covers upper-case letters, it would be
easy to adapt it to deal with larger character sets and, for those interested in
developing their own ciphers, it should make an excellent starting point.