Vigenère Cipher#

The Vigenère cipher is a method of encrypting alphabetic text using a form of polyalphabetic substitution, which applies multiple Caesar ciphers based on a keyword. Each letter in the plaintext is shifted by an amount determined by the corresponding letter in the keyword, creating a more secure encryption than a single-shift cipher. This method is more resistant to brute force attacks because the pattern of shifts varies based on the keyword.

Algorithm 17 (Vigenère Cipher Input)

Input:

  • Plaintext message \(M\).

  • Key \(K\).

Preparation for Encryption:

  1. Assign Numbers to Letters:

    • Each letter in the alphabet is assigned a number:

    \[\begin{split} \begin{aligned} A & = 0, \\ B & = 1, \\ \vdots \\ Z & = 25. \end{aligned} \end{split}\]
  2. Repeat Key to Match Message Length:

    • If the plaintext message \(M\) has a length \(n\) and the key \(K\) has a length \(m\), repeat the key until it matches the length of the message.

    Example: If \(M = "HELLO"\) and \(K = "KEY"\), then \(K\) is repeated to form “KEYKE”.

Algorithm 18 (Vigenère Cipher Encryption)

Encryption Process:

  • For each letter in the plaintext message \(M\), let \(x\) be its numeric representation.

  • For the corresponding letter in the key \(K\), let \(k\) be its numeric representation.

  • The encryption function \(E(x, k)\) shifts the letter \(x\) by \(k\) positions down the alphabet:

\[ E(x, k) = (x + k) \mod 26 \]
  • Example: Encrypting \(M = "HELLO"\) with \(K = "KEYKE"\):

    • \(H = 7\), \(K = 10\): \(E(7, 10) = (7 + 10) \mod 26 = 17\) (R)

    • \(E = 4\), \(E = 4\): \(E(4, 4) = (4 + 4) \mod 26 = 8\) (I)

    • \(L = 11\), \(Y = 24\): \(E(11, 24) = (11 + 24) \mod 26 = 9\) (J)

    • \(L = 11\), \(K = 10\): \(E(11, 10) = (11 + 10) \mod 26 = 21\) (V)

    • \(O = 14\), \(E = 4\): \(E(14, 4) = (14 + 4) \mod 26 = 18\) (S)

    • Result: \(M = "HELLO"\) is encrypted to \(C = "RIJVS"\).

Algorithm 19 (Vigenère Cipher Decryption)

Decryption Process:

  • For each letter in the ciphertext \(C\), let \(y\) be its numeric representation.

  • For the corresponding letter in the key \(K\), let \(k\) be its numeric representation.

  • The decryption function \(D(y, k)\) shifts the letter \(y\) back by \(k\) positions up the alphabet:

\[ D(y, k) = (y - k) \mod 26 \]
  • Example: Decrypting \(C = "RIJVS"\) with \(K = "KEYKE"\):

    • \(R = 17\), \(K = 10\): \(D(17, 10) = (17 - 10) \mod 26 = 7\) (H)

    • \(I = 8\), \(E = 4\): \(D(8, 4) = (8 - 4) \mod 26 = 4\) (E)

    • \(J = 9\), \(Y = 24\): \(D(9, 24) = (9 - 24) \mod 26 = 11\) (L)

    • \(V = 21\), \(K = 10\): \(D(21, 10) = (21 - 10) \mod 26 = 11\) (L)

    • \(S = 18\), \(E = 4\): \(D(18, 4) = (18 - 4) \mod 26 = 14\) (O)

    • Result: \(C = "RIJVS"\) is decrypted to \(M = "HELLO"\).

The Vigenère Cipher is more secure than the Caesar Cipher due to its use of a repeating key, introducing polyalphabetic substitution. However, it is still vulnerable to cryptanalysis, especially if the key length is known or the ciphertext is long.

Encoding with the Vigenère Cipher#

Encoding a message with the Vigenère cipher involves applying different shifts to each letter in the plaintext, determined by the corresponding letter in the repeated keyword. This ensures that each character is encrypted with a different substitution, making the resulting ciphertext more complex and secure. The process involves converting characters to numeric values, applying modular arithmetic for the shifts, and converting the results back to alphabetic text.

def vigenere_cipher_encode(input_string, keyword):
    encoded_string = ""
    for i, character in enumerate(input_string):
        key = keyword[i % len(keyword)]
        if character.isalpha():
            base = ord('a') if character.islower() else ord('A')
            encoded_string += chr((ord(character) - base + ord(key) - ord('A')) % 26 + base)
        else:
            encoded_string += character  # Non-alphabet characters remain unchanged
    return encoded_string
message = "Hello, World!"
keyword = "KEY"
encoded_message = vigenere_cipher_encode(message, keyword)
print(f"Original: {message}")
print(f"Encoded: {encoded_message}")
Original: Hello, World!
Encoded: Rijvs, Ambpb!

Decoding with the Vigenère Cipher#

Decoding a message encrypted with the Vigenère cipher involves reversing the shifts applied during encryption using the same keyword. By applying the modular arithmetic in reverse, each character is shifted back to its original position, reconstructing the plaintext. This process relies on the keyword to match the shifts used during encryption, ensuring that the message can only be decrypted by someone with the correct key.

def vigenere_cipher_decode(input_string, keyword):
    decoded_string = ""
    for i, character in enumerate(input_string):
        key = keyword[i % len(keyword)]
        if character.isalpha():
            base = ord('a') if character.islower() else ord('A')
            decoded_string += chr((ord(character) - base - ord(key) + ord('A') + 26) % 26 + base)
        else:
            decoded_string += character  # Non-alphabet characters remain unchanged
    return decoded_string
encoded_message = "Rijvs, Ambpb!"
keyword = "KEY"
decoded_message = vigenere_cipher_decode(encoded_message, keyword)
print(f"Encoded: {encoded_message}")
print(f"Decoded: {decoded_message}")
Encoded: Rijvs, Ambpb!
Decoded: Hello, World!