Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

MY University

ACC: Fall 2023


Project 4

Submitted by: Ghosia Razaq

Registration #: MCY231003

Submitted to: Dr. Muhammad Shamim Baig

Date: 12 December, 2023


1.Give C++ / Python code to Implement the following Functions:-Encryptor: inputs
plaintext (P) & roundkeys (K1, K2) from user & returns Ciphertext(C). Decryptor:
inputs plaintext (C) & roundkeys (K1, K2) from user & returns Ciphertext(C).
Code:
def initial_permutation(plaintext, permutation_table):
return ''.join(plaintext[i - 1] for i in permutation_table)

def final_permutation(ciphertext, permutation_table):


return ''.join(ciphertext[i - 1] for i in permutation_table)

def feistel_permutation(right_half, permutation_table):


return ''.join(right_half[i - 1] for i in permutation_table)

def substitution_box(input_binary, s_box):

# Convert binary input to decimal for row and column lookup


row = int(input_binary[0] + input_binary[-1], 2)
col = int(input_binary[1:-1], 2)

# Look up the output in the S-box


output_binary = format(s_box[row][col], '02b')
return output_binary

def straight_p_box_permutation(input_bits, permutation_table):


return ''.join(input_bits[i - 1] for i in permutation_table)

def binary_xor(bin_str1, bin_str2):


return ''.join(str(int(bit1) ^ int(bit2)) for bit1, bit2 in zip(bin_str1, bin_str2))

def feistel(plaintext, round_key, expansion_table, s_box1, s_box2, p_box):


left, right = plaintext[:len(plaintext)//2], plaintext[len(plaintext)//2:]
feistal_right = feistel_permutation(right, expansion_table)

xor_result = binary_xor(feistal_right, round_key)

s_box_output1 = substitution_box(xor_result[:4], s_box1)


s_box_output2 = substitution_box(xor_result[4:], s_box2)

s_box_output = s_box_output1 + s_box_output2

p_box_output = straight_p_box_permutation(s_box_output, p_box)

new_left = binary_xor(left, p_box_output)

xor_left_f = new_left + right


return xor_left_f

def apply_swapper(xor_left_f):
new_left, right = xor_left_f[:len(xor_left_f)//2], xor_left_f[len(xor_left_f)//2:]
return right + new_left

def encrypt(plaintext, round_keys, initial_permutation_table, final_permutation_table,


expansion_table, s_box1, s_box2, p_box):
permuted_text = initial_permutation(plaintext, initial_permutation_table)

permuted_text = feistel_permutation(permuted_text[len(permuted_text)//2:],
expansion_table)

# first round
permuted_text = feistel(permuted_text, round_keys[0], expansion_table, s_box1, s_box2,
p_box)
#swapper
permuted_text = apply_swapper(permuted_text)

#second round
permuted_text = feistel(permuted_text, round_keys[1], expansion_table, s_box1, s_box2,
p_box)

#final permtation
ciphertext = final_permutation(permuted_text, final_permutation_table)

return ciphertext
#print(ciphertext)
# Define permutation tables
initial_permutation_table = [2, 6, 3, 1, 4, 8, 5, 7]
final_permutation_table = [4, 1, 3, 5, 7, 2, 8, 6]
expansion_table = [4, 1, 2, 3, 2, 3, 4, 1]

# S-box tables
s_box1 = [
[1, 0, 3, 2],
[3, 2, 1, 0],
[0, 2, 1, 3],
[3, 1, 3, 2]
]

s_box2 = [
[0, 1, 2, 3],
[2, 0, 1, 3],
[3, 0, 1, 0],
[2, 1, 0, 3]
]
# P-Box
p_box = [2, 4, 3, 1]

# Example usage:
plaintext = input("Enter plaintext in binary: ")
round_key1 = input("Enter Round Key 1 in binary: ")
round_key2 = input("Enter Round Key 2 in binary: ")

# Convert the plaintext and round keys to the same length


plaintext = plaintext.ljust(len(round_key1) * 2, '0')

# Encrypt the plaintext using the round keys


ciphertext = encrypt(plaintext, [round_key1, round_key2], initial_permutation_table,
final_permutation_table, expansion_table, s_box1, s_box2, p_box)

print("Ciphertext:", ciphertext)

**************************************************************************

2. KeyGenerator: inputs Cipherkey (K) from user and generates & returns roundkeys
(K1, K2).
Encryption:
Code:
# P10 permutation table for key generation

P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]

# P8 permutation table for key generation

P8 = [6, 3, 7, 4, 8, 5, 10, 9]

# Function to perform permutation as permutation table

def permute(input_bits, permutation_table):

return ''.join(input_bits[i - 1] for i in permutation_table)


# Function to left shift the bits of a string

def left_shift(bits, shift):

return bits[shift:] + bits[:shift]

# Function to generate round keys K1 and K2 from the original 10-bit key

def generate_round_keys(cipher_key):

# Initial permutation P10

key_p10 = permute(cipher_key, P10)

# Split the result into two halves

left_half = key_p10[:5]

right_half = key_p10[5:]

# Perform left shifts for 1 bit

left_half_shifted = left_shift(left_half, 1)

right_half_shifted = left_shift(right_half, 1)

# Combine the halves

key_compression_box = left_half_shifted + right_half_shifted

# Permutation P8 to obtain K1

round_key1 = permute(key_compression_box, P8)

# Perform left shifts for 2 bits

left_half_shifted = left_shift(left_half_shifted, 2)

right_half_shifted = left_shift(right_half_shifted, 2)

# Combine the halves for K2

key_combined = left_half_shifted + right_half_shifted


# Permutation P8 to obtain K2

round_key2 = permute(key_combined, P8)

return round_key1, round_key2

# Get the 10-bit cipher key from the user

cipher_key = input("Enter the 10-bit Cipher Key: ")

# Generate round keys

round_key1, round_key2 = generate_round_keys(cipher_key)

print(f"Round Key 1 (K1): {round_key1}")

print(f"Round Key 2 (K2): {round_key2}")

********************************************************************************

You might also like