The Feistel Cipher is not a complete cipher itself, but a design model used to build many block ciphers, such as DES. It provides a simple way to build secure encryption and decryption algorithms. The only difference: during decryption, the round keys are applied in reverse order.
Key Features of Feistel Cipher
- Works on blocks of data (not on individual characters like substitution ciphers).
- The plaintext block is split into two halves: left (L) and right (R).
- In each round, one half is modified using a function of the other half and a round key.
- Multiple rounds make the cipher stronger.
- Same process is used for both encryption and decryption.
Step-by-Step Algorithm
Here’s how a simple 2-round Feistel Cipher works:
1. Convert Plaintext to Binary
- Take the plaintext characters.
- Convert each character to its ASCII value and then into an 8-bit binary string.
2. Divide into Two Halves
- Split the binary string into two equal halves:
- Left half = L1
- Right half = R1
3. Generate Round Keys
- Create random binary keys K1 and K2.
- Each key has a length equal to half the block size.
Round 1 (Encryption)
- Compute function f1:
f1 = R1 XOR K1
- Update halves:
R2 = L1 XOR f1
L2 = R1
Round 2 (Encryption)
- Compute function f2:
f2 = R2 XOR K2 - Update halves:
R3 = L2 XOR f2
L3 = R2
Final Ciphertext
Concatenate L3 and R3 to get the ciphertext.
Decryption Process
The Feistel Cipher uses the same algorithm for both encryption and decryption, with the round keys simply applied in reverse order.
Example:
Plaintext: Hello
- After encryption → Ciphertext: E1!w(
- After decryption → Retrieved Plaintext: Hello
Plaintext: Geeks
- After encryption → Ciphertext: O;Q
- After decryption → Retrieved Plaintext: Geeks
Why is Feistel Cipher Important?
- It provides a flexible framework to build strong ciphers.
- Many real-world ciphers (like DES) are based on this model.
- Ensures reversibility (you can always get back plaintext from ciphertext).
- Makes encryption/decryption more efficient and practical.
Program to demonstrate Feistel Cipher
import random
# Function to generate a random binary key of given length
def rand_key(length):
return "".join(str(random.randint(0, 1)) for _ in range(length))
# Function to perform XOR between two binary strings
def xor(a, b):
return "".join("0" if a[i] == b[i] else "1" for i in range(len(a)))
# Feistel round function
def feistel_round(left, right, key):
# Round function: f = XOR(right, key)
f = xor(right, key)
new_left = right
new_right = xor(left, f)
return new_left, new_right
# Encryption function
def feistel_encrypt(plain_text, rounds=2):
# Convert plaintext to binary (8 bits for each character)
pt_bin = "".join(format(ord(c), "08b") for c in plain_text)
# Split into two halves
n = len(pt_bin) // 2
left, right = pt_bin[:n], pt_bin[n:]
# Generate random round keys
keys = [rand_key(len(right)) for _ in range(rounds)]
# Apply Feistel rounds
for i in range(rounds):
left, right = feistel_round(left, right, keys[i])
# Final ciphertext in binary
cipher_bin = left + right
# Convert binary to string
cipher_text = ""
for i in range(0, len(cipher_bin), 8):
byte = cipher_bin[i:i+8]
cipher_text += chr(int(byte, 2))
return cipher_text, keys
# Decryption function
def feistel_decrypt(cipher_text, keys):
# Convert ciphertext to binary
ct_bin = "".join(format(ord(c), "08b") for c in cipher_text)
# Split into two halves
n = len(ct_bin) // 2
left, right = ct_bin[:n], ct_bin[n:]
# Apply Feistel rounds in reverse
for i in reversed(range(len(keys))):
right, left = feistel_round(right, left, keys[i])
# Final plaintext in binary
plain_bin = left + right
# Convert binary back to string
plain_text = ""
for i in range(0, len(plain_bin), 8):
byte = plain_bin[i:i+8]
plain_text += chr(int(byte, 2))
return plain_text
# Driver Code
if __name__ == "__main__":
plaintext = "Hello"
print("Plain Text:", plaintext)
# Encryption
cipher, round_keys = feistel_encrypt(plaintext)
print("Cipher Text:", cipher)
# Decryption
recovered = feistel_decrypt(cipher, round_keys)
print("Decrypted Text:", recovered)
Output
Plain Text: Hello Cipher Text: åÓ'mÝ Decrypted Text: Hello
Explanation:
1. Plaintext Conversion
- "Hello" is converted into binary (8 bits for each character).
- Example: 01001000 01100101 …
2. Splitting into Halves: The binary string is divided into Left (L) and Right (R) halves.
3. Key Generation: Random binary keys (K1, K2, …) are generated for each round.
4. Feistel Rounds:
- Each round takes (L, R, Key) and updates them using:
- f = R XOR Key
- New Right = L XOR f
- New Left = R
This is repeated for the chosen number of rounds (here 2).
5. Ciphertext: After rounds, the two halves are combined and converted back into characters → Ciphertext.
6. Decryption: Uses the same process as encryption but applies keys in reverse order. This restores the original plaintext.