Beaufort Cipher

The cipher is named after British admiral Francis Beaufort, who lived at the turn of the 18th and 19th centuries.

Usage

The Beaufort cipher is a simple polyalphabetic cipher. It uses a table called tabula recta, which was first introduced in the Trithemius cipher. It shouldn't be confused with a special variant of the Vigenère cipher, named Variant Beaufort.

The Beaufort cipher was used in rotor-based cipher machines Hagelin M-209 in the middle of the 20th century.

Algorithm

The Beaufort cipher's algorithm is based on the table called tabula recta:

tabula recta
Tabula Recta

During encryption, all plaintext letters are replaced by other letters, based on the tabula recta table. Both sides share one secret key, which consists of one or more words. Each plaintext letter is encrypted by using one key letter. After the last key character has been used, the algorithm goes back to the first key letter and starts taking key characters again from the beginning.

The encryption process is presented below. For every plaintext letter, one should perform the following operations, by using one key character.

  1. Find the plaintext letter in the topmost horizontal row.
  2. Travel down the column, until you find the current key letter.
  3. The leftmost letter in the current row is the new ciphertext letter.

Decryption of the ciphertext uses exactly the same algorithm. This means that after the second encryption of ciphertext, one receives the original plaintext. Ciphers that have this property are referred to as reciprocal ciphers.

Security of the Beaufort Cipher

Ciphertexts created by the Beaufort cipher can be very easily changed into ciphertexts of the Vigenère cipher. This can be done by replacing every letter of the ciphertext by its opposite letter (a becomes z, b becomes y and so on). After this modification, the ciphertext can be analyzed by using all the existing attacks against the Vigenère cipher.

Implementation

A simple encryption/decryption function implemented in Python:

def encrypt_or_decrypt(key, input_txt):
  output_txt = []
  for pos in range(0, len(input_txt)):
    letter_row = 'A'
    letter_txt = input_txt[pos]
    while letter_txt != key[pos%len(key)]:
      letter_txt = chr((ord(letter_txt)-ord('A')+1)%26
                + ord('A'))
      letter_row = chr((ord(letter_row)-ord('A')+1)%26
                + ord('A'))
    output_txt.append(letter_row)
  return ''.join(output_txt)