I wrote about
a simple reciprocal substitution cipher
before and today I will write about a simple transposition cipher. In a
substitution cipher, the letters stay in their positions, but they change their
identities. They may be changed to another letter or symbol. The ROT-13
algorithm (see previous link) and the Caesar cipher are two examples of a
substitution cipher.
In a transposition cipher, the letters keep their identities, but their
positions are switched (or transposed). An example of a transposition cipher is
the Scytale (rhymes with Italy) tool used in ancient Greece to encrypt messages
sent to troops and officers during battle.
The Scytale is a rod in which the sender wraps a strip of parchment paper and
writes the message on that strip. The messenger then carries the message to the
receiver, who must have another Scytale of the same diameter of the one used to
create the encrypted message. The receiver wraps the strip on his Scytale and is
able to read the message.
The Scytale points to an interesting concept in cryptography: it's really
difficult to keep an algorithm secret. The security of a cipher should not be
dependent on keeping the method of encryption a secret. In the case of Scytale,
the method of encryption is the rod used, but there is another aspect: the
diameter of the rod is also important. The diameter is the key of the
algorithm.
The Implementation
The implementation of the algorithm is really simple and there are many methods
one can use to achieve the same goal. The approach I used breaks down the plain
text into a list of characters and then splits this list into chunks of size
equal to the key. The next step is to read the first character of each chunk and
then the second character of each chunk and so on until all characters are
read. The algorithm look like this in CSharp:
public string Encrypt(string plaintext, int key) {
var chars = plaintext.ToList();
var chunks = (int)Math.Ceiling(((double)chars.Count() / (double)key));
var inters = new List<list>();
int i = 0, j = 0;
while (i = inters[l].Count())
buff.Append("+");
else
buff.Append(inters[l][k]);
l++;
}
k++;
}
return buff.ToString();
}
Note that we have to pad the last chunk if the chunk size is not equal to the
key size. Also not that this is not a reciprocal algorithm, as is the case with
the ROT-13 implementation. In order to decrypt a message to plain text you need
to run it through another function that does things backwards. Note how this
code is very similar to the encryption code, but things are down in a different
order:
public string Decrypt(string ciphertext, int key) {
var chars = ciphertext.ToList();
var chunks = (int)Math.Ceiling(((double)chars.Count() / (double)key));
var inters = new List<list>();
int i = 0, j = 0;
while (i < key) {
inters.Add(chars.Skip(j).Take(chunks).ToList());
++i; j += chunks;
}
StringBuilder buff = new StringBuilder();
int k = 0;
while (k < chunks) {
int l = 0;
while (l < inters.Count()) {
buff.Append(inters[l][k]);
l++;
}
k++;
}
return buff.ToString();
}
Using the Algorithm
To use the Scytale cipher algorithm, you simply have to call the Encrypt and
Decrypt functions of the Scytale class and send it a message to encrypt or
decrypt along with the key size. In the example code below the Main function
uses command line arguments passed in:
static void Main(string[] args) {
Scytale scytale = new Scytale();
string msg = args[0]; //"HELPMEIAMUNDERATTACK";
int key = Int32.Parse(args[1]);
string cipher = scytale.Encrypt(msg, key);
string plain = scytale.Decrypt(cipher, key); ;
Console.WriteLine("Message: " + msg);
Console.WriteLine("Cipher: " + cipher);
Console.WriteLine("Plain: " + plain);
Console.ReadKey();
}
You can also call the scytale.exe program like this:
d:\> scytale.exe "HELPMEIAMUNDERATTACK" 5
The output should be the following:
Message: HELPMEIAMUNDERATTACK
Cipher: HENTEIDTLAEAPMRCMUAK
Plain: HELPMEIAMUNDERATTACK