Vernam Cipher in Swift

Unbreakable encryption is possible. Welcome to One-time Pad or what also referred to as “the perfect cipher”. To be honest, it is comforting to know that it is possible to encrypt text conversations to the point where it is practically impossible to decrypt without having the correct key. While the previous two ciphers mentioned earlier (Caesar Cipher and Vigenere Cipher) provide a way to scramble text into “gibberish”, both can be easily decrypted using pattern matching without needing the original key.

Unlike previous crypto algorithms, Vernam uses random key composed of random numbers to encrypt text. It is a very simple, yet powerful algorithm as you will see shortly.

Let’s begin by assuming we have plain text that needs encryption. For the sake of simplicity, we are going to pick one of L. Messi’s quotes. Encrypt it and then decrypt it (I am a huge Barcelona fan):

Unlike Caesar or Vigenre ciphers, Vernam cipher does not require a key from the user. The implementation can allow for it especially since it is possible to determine if the sequence of numbers was computer generated or not. However, the way I am going to implement this algorithm is by not only encrypting the actual text, but also providing the user with automatically generated key he/she can use later to decrypt text.

I am going to begin by generating a set of random numbers based on the length of the plain text. This function will take in the count of characters as its only parameter and return an array of random integers. In plain terms, it will essentially generate the key that will be used to offset characters.

In the next step I’m going to create the encryption / decryption map using an array of characters composed off of english letters. This step is very important and is absolutely required.

Function “map” enumerates through the array of letters and creates a forward map where the key is the letter and the value is the location of the letter; reversed map uses the location as the key and the letter as the value. I also keep track of the location of the last letter in the alphabet. Forward, reversed and last index data is returned as a tuple. This is great since to generate this data I only need to enumerate through the array once.

This finally leads me to the actual encryption and decryption functions. First, I am converting text to lowercase string for consistency. Next, I am generating an array of random numbers for each character in plain text using the “key” function. After I get the key, I am creating a map and an empty string called “output”.

The implementation of the actual encryption is happening in the for-in loop. Here I am checking to see if the character I am currently enumerating is a space. If so, I add it to the output string and if not, I am getting letterIndex for current character. Then I get a random number from the array of random numbers (key) to derive at the outputCharacter. Lastly, the outputCharacter is appended to the “output” string.

Note the return type of the above function… it returns a tuple. It returns both encrypted text and the key used to encrypt it.

Finally, here is a decryption function that takes in encrypted text, the key and returns decrypted, plain text:

While the actual cipher is great, the biggest challenge with Vernam is key distribution. Believe you me, I’ve spent more time trying to solve the key distribution dilemma than writing implementation… Unfortunately everything and everyone has a weakness.

Anyway, this will be my last article on encryption (probably). Huge thank you to my good friend Branton Boehm who inspired me to look into encryption in detail.

You can find sample code on my Github page.

Vernam Cipher in Swift