Search
Trithemius Cipher

Trithemius Cipher

The Trithemius Cipher attempts to formalize the polyalphabetic cipher process by using very predictable keys. The first letter in your plaintext will be enciphered by key letter/value of A and each subsequent letter in the plaintext is enciphered using the subsequent letters that follow A. For example, to encipher the plaintext message do not press this button you would start by writing:

keystream: ABCDEFGHIJKLMNOPQRST
plaintext: donotpressthisbutton

Then you would use the tabula rectra or mathematical approach to encipher the message as seen in the previous section.

Variations of the Trithemius Cipher

Since the Trithemius cipher as described above would be used the same way every time, it's not a secure cipher. Once you know a message was enciphered with the Trithemius method, you know exactly how to decipher it. This goes against one of the components that makes an encryption scheme valid, The method need not be secret to guarantee security. To make this cipher valid, there needs to be some variation possible.

Offset Values

Instead of starting at A, the keystream could start at any of the 26 characters of the alphabet

keystream: HIJKLMNOPQRSTUVWXYZA
plaintext: donotpressthisbutton

Direction

Instead of moving to the next letter in the alphabet to determine the next letter in the keystream, you could move to the previous letter in the alphabet.

keystream: EDCBAZYXWVUTSRQPONML
plaintext: donotpressthisbutton

Step Value

Instead of stepping by one letter in the alphabet when creating the keystream, you could step by 2, 3, 4, etc.

keystream: ADGJMPSVYBEHKMQTWZCF
plaintext: donotpressthisbutton

Programming the Trithemius Cipher

Let's look at how to program the Trithemius cipher. We'll start by importing the textClean() function from the toolkit and defining our plaintext message

from toolkit import textClean
plaintext = 'donotpressthisbutton'

Now we'll write the function trithemiusEncipher(). It should take in a string (the message), an integer (the starting key value), an integer (+1 for increasing, -1 for decreasing), and another integer (step size).

def trithemiusEncipher( text, start, direction, step):
    plaintext = textClean( text )
    LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    ciphertext = ''
    keystream = ''
    
    # Create the keystream
    counter = start
    while len(keystream) != len(plaintext):
        keystream += LETTERS[counter]
        counter = ( counter + (direction * step) ) % 26
    
    for i in range(0, len(plaintext)):
        keyValue = LETTERS.find(keystream[i]) 
        plaintextValue = LETTERS.find(plaintext[i])
        ciphertext += LETTERS[ (plaintextValue + keyValue) % 26 ]
    
    return ciphertext
print( trithemiusEncipher('donotpressthisbutton', 2, 1, 4) )
FUXCLLRIAEJBGUHEHLKN
print( trithemiusEncipher('donotpressthisbutton', 10, -1, 2) )
NWTSVPPAMKJVUCJAXVOL
print( trithemiusEncipher('donotpressthisbutton', 0, 1, 0) )
DONOTPRESSTHISBUTTON

Let's go through the two different loops and discuss why they work the way they do.

counter = start
while len(keystream) != len(plaintext):
    keystream += LETTERS[counter]
    counter = ( counter + (direction * step) ) % 26

The goal of this section is to create the keystream that would be written over the top of the plaintext. Since we'll know that the keystream is long enough when it is the same length as the plaintext, that is a good condition to check in the while loop. Inside the loop, we'll use the value of counter to determine which letter to add to the keystream. We'll use the argument stored to start to initialize the variable. After adding the letter from LETTERS to the keystream, we increment the counter by direction * step since the product indicates how many letters to move from the current letter. We'll need to $\text{MOD}$ by 26 to make sure the new counter value is valid. This process repeats until the code has generated the entire keystream.

for i in range(0, len(plaintext)):
    keyValue = LETTERS.find(keystream[i]) 
    plaintextValue = LETTERS.find(plaintext[i])
    ciphertext += LETTERS[ (plaintextValue + keyValue) % 26 ]

This for loop is iterating by index values starting at 0 and ending at len(plaintext). This choice was made to make it easy to operate on characters found at the same index in two different strings. The first two lines of code in the loop takes the letters found at index i in the strings keystream and plaintext and converts them to their numerical representations. The third line of code performs the Caesar shift by adding these two values and performing a $\text{MOD}$ 26 to ensure the new position number is valid. It then converts the new value to a letter using the LETTERS string and adds it to the string ciphertext. This repeats until all the letters have been enciphered.

This second loop can be reused for most types of polyalphabetic ciphers that use a keystream. How the keystream gets generated is specific to each cipher, but the use of the keystream is similar across all the ciphers covered in this section.