Information Security – Rotation Cipher Project

The rotation cipher is often described using a mathematical formula. First, we start by matching each letter in the alphabet to a number as follows:

A = 0, B = 1, C = 2…Z = 25

The plaintext can then be written as a series of numbers:

Plaintext:                                        P     Y     T     H     O     N

Plaintext as numbers:                   15   24   19    7     14   13

If the key is “R” (or 17), we can encrypt the message by adding the corresponding number to each number in the plaintext.

(15 + 17)        (24 + 17)        (19 + 17)        (7 + 17)          (14 + 17)        (13 + 17)

The problem is that many of these numbers will be greater than 25, which means they will not have a letter to correspond to. Consider, for example, the first letter, which is encrypted as (15 + 17) = 32, which does not correspond to a letter in the alphabet. What we want in this case is for it to go up to Z (25), then loop back around to A (0) and go from there. To do this we use the modulus operator (%). This takes the remainder that you get when you divide two numbers.

(15 + 17) % 26 = 32 % 26 = 6 because 32/26 = 1 remainder 6

So our now our ciphertext becomes:

6          15       10        24       5          4

which corresponds to:

G         P         K         Y         F         E

To decrypt, all we have to do is take the ciphertext values and subtract the key value, remembering include % 26. This leads to the following encryption and decryption formulas where m represents one letter of plaintext, c represents one letter of ciphertext, and k represents the key.

c := (m + k) % 26

m:= (c – k) % 26

So far, the formula is good for encrypting and decrypting messages for which the alphabet goes from 0 to 25. But in programming, the ASCII values for capital letters start at 65. To account for this, we will add and subtract 65 from the values as follows:

c:= (m – 65 + k) % 26 + 65

m:= (c – 65 – k) % 26 + 65

This essentially brings the values down to the 1-25 range, adds or subtracts the key, calculates the new value, then adds 65 again to put it back into ASCII range.

Programming Activity

Part A

  • The goal of this project is to write a Python program that will allow them to set up a Rotation Cipher with any key and use it to encrypt and decrypt any messages.
  • Two useful functions they will need are ord() and chr(), which change ASCII values to characters and vice versa. For example, ord(‘A’) will yield 65, and chr(65) will yield ‘A’.
  • This project can be good practice for classes and objects. Create a class called RotationCipher that has one instance variable (key) and several methods, including the __init__, setKey for changing the key, encrypt, and decrypt. Discuss with the students what each method should do.
  • Note: The formula given for encryption and decryption restricts the possible characters to capital letters. This means that any spaces in the plaintext should be removed before encryption.
  • Example Code:
#!/usr/bin/python

class RotationCipher:

    def __init__(self, key):
        self.key = ord(key) - 65

    def setKey(self, key):
        self.key = ord(key) - 65

    def encrypt(self, message):
        encrypted = ""
        message = message.replace(" ", "")
        for letter in message:
            encrypted += chr((ord(letter) - 65 + self.key) % 26 + 65)
        return encrypted

    def decrypt(self, message):
        decrypted = ""
        message = message.replace(" ", "")
        for letter in message:
            decrypted += chr((ord(letter) - 65 - self.key) % 26 + 65)
        return decrypted

#This portion is a user interface to interact with the class and methods

RC = RotationCipher("A")
cmd = ""

while cmd != "quit":
    cmd = raw_input(">>")
    if cmd == "setKey":
        key = raw_input("\nKey: ")
        RC.setKey(key)
    elif cmd == "encrypt":
        message = raw_input("\nPlaintext: ")
        CT = RC.encrypt(message)
        print CT
    elif cmd == "decrypt":
        ciphertext = raw_input("\nCiphertext: ")
        PT = RC.decrypt(ciphertext)
        print PT

Part B

  • As was mentioned above, the key space for this encryption system is very small (only 26 possibilities in the English alphabet). Even a human, given enough time, would be able to break it by brute-force (for example, using a decoder ring), and a computer could try all 26 possibilities in a very short amount of time.
  • The goal of this part is to write a short program to break the cipher. The program should be separate from Part A since someone breaking the cipher should not have access to any of the Rotation Cipher information.
  • Discuss with the students how they might go about breaking the cipher, pointing them back to what they did with the decoder rings.
  • Give the students a lengthy portion of ciphertext, and ask them to write a program to break it. If they come up with the correct plaintext (and the key), then their code is probably right.
  • Example Code:
#!/usr/bin/python

ciphertext = raw_input("Enter the ciphertext: ")
key = 0

ciphertext = ciphertext.replace(" ", "")

while key < 26:
    message = ""
    for letter in ciphertext:
        message += chr((ord(letter) - 65 - key) % 26 + 65)
    print message + "\n"
    key += 1