About Vigenère Cipher
The Vigenère cipher is a classic encryption technique that dates back to the 16th century. It was invented by a French diplomat and cryptographer named Blaise de Vigenère, hence the name. It was known as “le chiffre indéchiffrable,” which means “the indecipherable cipher,” and remained unbroken until British polymath Charles Babbage broke it in the 19th century.
How it works
The Vigenère cipher is a polyalphabetic substitution cipher that uses a keyword to encrypt and decrypt messages. The key idea behind the Vigenère cipher is to use multiple Caesar ciphers
based on the letters of the keyword.
Let’s say we have a plaintext message
PPP
consisting of
nnn
letters:
P=p1,p2,…,pnP = p_1, p_2, ldots, p_nP=p1,p2,…,pn
. We also have a keyword
KKK
consisting of
mmm
letters:
K=k1,k2,…,kmK = k_1, k_2, ldots, k_mK=k1,k2,…,km
, where
m≤nm leq nm≤n
.
To encrypt the message, we repeat the keyword until it matches the length of the plaintext. Let
K′=k1,k2,…,km,k1,k2,…,km,…K’ = k_1, k_2, ldots, k_m, k_1, k_2, ldots, k_m, ldotsK′=k1,k2,…,km,k1,k2,…,km,…
repeated until it matches the length of
PPP
.
To encrypt each letter
pip_ipi
in the plaintext, we find the corresponding letter
kjk_jkj
in the keyword
K′K’K′
where
jjj
is the index of
pip_ipi
modulo
mmm
. Then, we shift the letter
pip_ipi
by the index of
kjk_jkj
in the alphabet. Let
EEE
represent the encrypted message.
The mathematical representation of the encryption process is given by:
where
EiE_iEi
is the
iii
-th letter of the encrypted message and
j=(i−1)mod mj = (i−1) mod mj=(i−1)modm
.
To decrypt the message, we use a similar process. We repeat the keyword until it matches the length of the ciphertext. Let
K′′=k1,k2,…,km,k1,k2,…,km,…K” = k_1, k_2, ldots, k_m, k_1, k_2, ldots, k_m, ldotsK′′=k1,k2,…,km,k1,k2,…,km,…
(repeated until it matches the length of
EEE
).
To decrypt each letter
EiE_iEi
in the ciphertext, we find the corresponding letter
kjk_jkj
in the keyword
K′K’K′
(where
jjj
is the index of
EiE_iEi
modulo
mmm
). Then, we shift the letter
EiE_iEi
back by the index of
kjk_jkj
in the alphabet. Let
DDD
represent the decrypted message.
The mathematical representation of the decryption process is given by:
where
DiD_iDi
is the
iii
-th letter of the decrypted message and
j=(i−1)mod mj = (i−1) mod mj=(i−1)mod m
.
Note that in these equations, we use modular arithmetic with
262626
since there are
262626
letters in the English alphabet. Additionally, we assume a simple mapping where
AAA
is represented by
000
,
BBB
by
111
, and so on.
Example
Let’s use the word “KEY” as the keyword and encrypt the plaintext message “HELLO” using the Vigenère cipher.
First, we repeat the keyword “KEY” to match the length of the plaintext “HELLO”. Thus, the repeated keyword becomes “KEYKE”.
The corresponding numerical representation of the plaintext message “HELLO” is:
E rightarrow 4\
L rightarrow 11\
L rightarrow 11\
O rightarrow 14H→7E→4L→11L→11O→14
Using the mathematical encryption formula
Ei=(pi+kj)mod 26E_i = (p_i+k_j) mod 26Ei=(pi+kj)mod 26
, we can calculate the encrypted values as follows:
E_2 = (4 + 4) mod 26 = 8 rightarrow I\
E_3 = (11 + 24) mod 26 = 9 rightarrow J\
E_4 = (11 + 10) mod 26 = 21 rightarrow V\
E_5 = (14 + 4) mod 26 = 18 rightarrow SE1=(7+10)mod26=17→RE2=(4+4)mod26=8→IE3=(11+24)mod26=9→JE4=(11+10)mod26=21→VE5=(14+4)mod26=18→S
Thus, the encrypted message is “RIJVS”.
To decrypt the ciphertext “RIJVS” back to the original plaintext, we repeat the keyword “KEY” to match the length of the ciphertext. Thus, the repeated keyword becomes “KEYKE”.
Using the mathematical decryption formula
Di=(Ei−kj)mod 26D_i=(E_i−k_j) mod 26Di=(Ei−kj)mod 26
, we can calculate the decrypted values as follows:
D_2 = (8 – 4) mod 26 = 4 rightarrow E\
D_3 = (9 – 24) mod 26 = 11 rightarrow L\
D_4 = (21 – 10) mod 26 = 11 rightarrow L\
D_5 = (18 – 4) mod 26 = 14 rightarrow OD1=(17−10)mod26=7→HD2=(8−4)mod26=4→ED3=(9−24)mod26=11→LD4=(21−10)mod26=11→LD5=(18−4)mod26=14→O
Thus, the decrypted message is “HELLO”.
Vigenère Table
Encryption/decryption in case of Vigenere Cipher is a tedious task. The Vigenère table, also known as the Vigenère square or the Tabula Recta, is used to simplify the process of encryption and decryption.
It consists of a grid or matrix that provides a systematic way of encrypting and decrypting messages using the Vigenère cipher. The table is formed by aligning multiple Caesar ciphers together, each with a different shift value determined by a keyword. The rows and columns of the table represent the letters of the alphabet, and each cell contains the letter resulting from combining the row and column letters using the Caesar cipher.
The Code
The encryption-decryption script as well as the hacking script can be downloaded from here:
About Vigenère Cipher
The Vigenère cipher is a classic encryption technique that dates back to the 16th century. It was invented by a French diplomat and cryptographer named Blaise de Vigenère, hence the name. It was known as “le chiffre indéchiffrable,” which means “the indecipherable cipher,” and remained unbroken until British polymath Charles Babbage broke it in the 19th century.
How it works
The Vigenère cipher is a polyalphabetic substitution cipher that uses a keyword to encrypt and decrypt messages. The key idea behind the Vigenère cipher is to use multiple Caesar ciphers based on the letters of the keyword.
Let’s say we have a plaintext message $P$ consisting of $n$ letters: $P = p_1, p_2, ldots, p_n$. We also have a keyword $K$ consisting of $m$ letters: $K = k_1, k_2, ldots, k_m$, where $m leq n$.
To encrypt the message, we repeat the keyword until…
.
Here is the source code of encryption_decryption.py:
def vigenere_cipher(text, keyword, mode):
result = ""
keyword_length = len(keyword)
keyword = keyword.upper()
key_index = 0
for i, char in enumerate(text):
if char.isalpha():
ascii_offset = ord('A') if char.isupper() else ord('a')
keyword_shift = ord(keyword[key_index % keyword_length]) - ord('A')
if mode == "decrypt":
keyword_shift = -keyword_shift # Reverse the shift for decryption
char = chr((ord(char) - ascii_offset + keyword_shift) % 26 + ascii_offset)
key_index+=1
result += char
return result
# Get mode
while True:
print('Do you want to (e)ncrypt or (d)ecrypt?')
response = input('> ').lower()
if response.startswith('e'):
action = 'encrypt'
break
elif response.startswith('d'):
action = 'decrypt'
break
print('Please enter the letter e or d.')
print("Enter the message.")
message = input('> ')
print("Enter the keyword.")
keyword = input('> ').upper()
# Perform encryption/decryption
result = vigenere_cipher(message, keyword, action)
# Display the result
print(f"Result: {result}")
The vigenere_cipher function performs the encryption or decryption operation based on the provided parameters. It initializes an empty string called result to store the final result. It calculates the length of the keyword and converts it to uppercase.
Next, it iterates through each character in the text input. If the character is a letter, it determines whether it is uppercase or lowercase and assigns an ASCII offset accordingly. It calculates the shift value for the current character based on the corresponding letter in the keyword. If the mode is set to “decrypt,” it reverses the shift value.
Then, it applies the shift to the current character by subtracting the ASCII offset, adding the keyword shift, and taking the modulo 26 to wrap around the alphabet. Finally, it converts the shifted value back to a character using the ASCII offset and appends it to the result string. The key_index is incremented to ensure the keyword characters are used cyclically.
After processing all characters in the text, the result string contains the encrypted or decrypted message, depending on the mode.
The code prompts the user to enter the encryption or decryption mode (encrypt or decrypt) and stores the response in the action variable. It keeps asking for input until a valid mode is provided.
Then, it asks the user to enter the message and keyword, storing them in the message and keyword variables, respectively.
The vigenere_cipher function is called with the provided inputs (message, keyword, and action), and the result is stored in the result variable.
The Program in Action
Here is a sample output that we get upon executing the program:
Do you want to (e)ncrypt or (d)ecrypt?
> e
Enter the message.
> Enemy is approaching! Send troops immediately!
Enter the keyword.
> Moonlight
Result: Qbszj qy hibfcnnpouz! Esbq ezuvie wazplohmqzm!
Do you want to (e)ncrypt or (d)ecrypt?
> d
Enter the message.
> Qbszj qy hibfcnnpouz! Esbq ezuvie wazplohmqzm!
Enter the keyword.
> Moonlight
Result: Enemy is approaching! Send troops immediately!
Here the key used is Moonlight.
Conclusion
There are several ways to hack the Vigenère Cipher, such as Kasiski examination, Friedman test, frequency analysis, dictionary attack, etc. However, these are advanced methods and require complex application of combinatorics and statistics. Discussing even one of those would require a separate post. For now we will focus on encryption and decryption. I will surely post a Vigenère hack tutorial in future.
Note: Vigenère Cipher, although complex, is still too easy to break using modern methods and should not be used for serious encryption purposes.