Feistel Cipher

Last Updated : 3 Oct, 2025

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

Python
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.

Comment