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

3 thoughts on “Vernam Cipher in Swift

  1. Branton Boehm says:

    Thanks for writing all this up, Michael! I noticed that in the key method, you have “arc4random() % 25”. If you want a range from 0 to 25, then you actually need to use “% 26”. Modulus creates a range from 0 to n-1.

  2. Dan G says:

    Hi Michael, and thank you for the tutorial!
    I’m trying to display the decrypted text in UITextView, but it looks like I’m having trouble. I’ll paste the code bellow, if you could assist me with it.

    @IBAction func decrypt(sender: AnyObject?) {

    func decrypt(text: String, key:[Int]) -> String {

    let text = text.lowercased()

    let map = self.map()

    var output = String()

    for (index, character) in text.characters.enumerated() {

    if character == ” ” {

    output.append(character)

    } else {

    if let letterIndex = map.forward[String(character)] {

    let keyIndex = key[index]

    let outputIndex = (letterIndex – keyIndex + map.lastCharacterIndex) % map.lastCharacterIndex

    if let outputCharacter = map.reversed[outputIndex] {

    output.append(outputCharacter)

    }

    }

    }

    }

    return output

    }

    let text = decryptText.text

    let key = pskey.text

    // call the decrypt function

    let (resultText, resultKey) = decrypt(text: text!, key: key)

    print(outputText)

    // put the result in the text view

    outputText.text = resultText

    }

Leave a Reply

Your email address will not be published. Required fields are marked *