0% found this document useful (0 votes)
21 views62 pages

Cryptography Lab

Uploaded by

J. Prince
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views62 pages

Cryptography Lab

Uploaded by

J. Prince
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 62

PRESIDENCY COLLEGE (AUTONOMOUS)

CHENNAI – 600 005

DEPARTMENT OF COMPUTER SCIENCE


MASTER OF COMPUTER APPLICATIONS (M.C.A)
SUBJECT CODE: 23PYCP52
SEMESTER – II
2023 – 2024

CRYPTOGRAPHY AND NETWORK SECURITY LAB

NAME :
REGISTER NO. :
PRESIDENCY COLLEGE (AUTONOMOUS)
CHENNAI – 600 005
DEPARTMENT OF COMPUTER SCIENCE

CERTIFICATE
Certified this is a Bonafide record of practical work done by
______________________ Register No. ________________ in
“CRYPTOGRAPHY AND NETWORK SECURITY LAB (23PYCP52)”
during the year 2023 – 2024.

Lecturer in-charge Head of the Department

Submitted for the I semester M.C.A Degree Practical Examination held on


______ at Presidency College (Autonomous), Chennai – 600 005.

Internal Examiner External Examiner


INDEX

S.NO DATE TITLE SIGNATURE

1
Implementation of XOR

2
Cesar Cipher
3
Hill Cipher
4
Mono-Alphabetic Substitution Cipher

5
Data Encryption Standards (DES) Algorithm

6
Transposition Cipher

7
Playfair Cipher

8 RSA Algorithm

9 Diffe-Hellman Key Exchange

10
Implementation of XOR

Aim:
To write a python program to implement XOR operation.

Algorithm:
STEP 1: The xor function takes two parameters: input_string and ch (either 1 or 0).

STEP 2: It initializes an empty string result.

STEP 3: If ch is 1, it iterates through each character of input_string, performs the XOR operation with 1,
and appends the result to the result string.

STEP 4: If ch is 0, it iterates through each character of input_string, performs the XOR operation with 0,
and appends the result to the result string.

STEP 5: The main block of code initializes an example string "Hello world" and then runs a loop for 100
iterations, allowing the user to choose between XORing with 1 or 0.

STEP 6: The result is printed for each iteration.


Exclusive OR Truth Table

Input A Input B Output

0 0 0

0 1 1

1 0 1

1 1 0

Sample Plaintext: Hello World

Equivalent Binary form (ASCII)

H e l l o W o r l d

72 101 108 108 111 87 111 114 108 100

‘H’ XOR with 0

Result ‘H’

‘e’ XOR with 0

Result ‘e’

‘H’ XOR with 1

Result ‘I’

‘e’ XOR with 1

Result ‘d’
Program:
def xor(input_string, ch):

result = ""

if ch == 1:

for char in input_string:

# Convert the character to ASCII, XOR with 1, and convert back to character

result += chr(ord(char) ^ 1)

return result

else:

for char in input_string:

# Convert the character to ASCII, XOR with 0, and convert back to character

result += chr(ord(char) ^ 0)

return result

if __name__ == "__main__":

# Initialize the string

input_string = "Hello world"

for i in range(100):

print("\t\t\tXOR OF HELLO WORLD")

print("\t\t\t------------------")

print("1. XOR with 1")

print("2. XOR with 0")

ch = int(input("Enter 1 for XOR with 1 and 0 for XOR with 0: ")

result_string = xor(input_string, ch)

if ch == 1:

print("Original String:", input_string)

print("XORed with 1:", result_string)

else:

print("Original String:", input_string)

print("XORed with 0:", result_string)


Output:
XOR OF HELLO WORLD
---------------------------------
1. XOR with 1
2. XOR with 0
Enter 1 for XOR with 1 and 0 for XOR with 0: 0
Original String: Hello world
XORed with 0: Hello world

XOR OF HELLO WORLD


---------------------------------
1. XOR with 1
2. XOR with 0
Enter 1 for XOR with 1 and 0 for XOR with 0: 1
Original String: Hello world
XORed with 1: Idmmn!vnsme
Cesar Cipher
Aim:
To write a python program to find the encryption and decryption of a plaintext using Caesar
cipher algorithm.

Algorithm:
STEP 1: Start
STEP 2: Define a function named Caesar with parameter text
STEP 3: Iterate the text and check whether the character is uppercase or lowercase
STEP 4: Based on ASCII shift the alphabets +3 positions
STEP 5: Print the text after shift positions
STEP 6: Stop
Numerical equivalent to each letter:

For Encryption

For Decryption

For Caesar cipher key K=3


Program:
def encrypt(text, shift):
result = ""
for char in text:
if char.isalpha():
if char.islower():
result += chr((ord(char) + shift - ord('a')) % 26 + ord('a'))
else:
result += chr((ord(char) + shift - ord('A')) % 26 + ord('A'))
else:
result += char
return result
def encrypt(text, shift_s):
result = ""
for char in text:
if char.isalpha():
if char.islower():
result += chr((ord(char) + shift_s - ord('a')) % 26 + ord('a'))
else:
result += chr((ord(char) + shift_s - ord('A')) % 26 + ord('A'))
else:
result += char
return result
def decrypt(text, shift):
return encrypt(text, -shift)
def decrypt(text, shift_s):
return encrypt(text, -shift_s)
def main():
for i in range(100):
print("\t\t\t\tCesar Cipher & Substitution Cipher")
print("\t\t\t\t**********************************")
print("Menu:")
print("1.Cesar Cipher")
print("2.Substitution Cipher")
ch = int(input("Enter your choice:"))
if ch == 1:
print("\t\t\tCesar Cipher")
print("\t\t\t************")
choice = input("\nEnter 'E' to encrypt or 'D' to decrypt: ").upper()
if choice not in ('E', 'D'):
print("Invalid choice. Please enter 'E' or 'D'.")
return
print("\nInput")
print("*****")
text = input("Enter the text: ")
shift = 3
if choice == 'E':
print("\nOutput")
print("******")
result = encrypt(text, shift)
print("Encrypted text:", result)
else:
print("\nOutput")
print("******")
result = decrypt(text, shift)
print("Decrypted text:", result)
else:
print("\t\t\tSubstitution Cipher")
print("\t\t\t*******************")
choice = input("\nEnter 'E' to encrypt or 'D' to decrypt: ").upper()
if choice not in ('E', 'D'):
print("Invalid choice. Please enter 'E' or 'D'.")
return
print("\nInput")
print("*****")
text = input("Enter the text: ")
shift_s = int(input("Enter the shift value:"))

if choice == 'E':
print("\nOutput")
print("******")
result = encrypt(text, shift_s)
print("Encrypted text:", result)
else:
print("\nOutput")
print("******")
result = decrypt(text, shift_s)
print("Decrypted text:", result)
if __name__ == "__main__":
main()
Output:
Cesar Cipher & Substitution Cipher
*******************************
Menu:
1.Cesar Cipher
2.Substitution Cipher
Enter your choice:1
Cesar Cipher
************
Enter 'E' to encrypt or 'D' to decrypt: e
Input
*****
Enter the text: meetmeaftertogaparty

Output
******
Encrypted text: phhwphdiwhuwrjdsduwb

Cesar Cipher & Substitution Cipher


**********************************
Menu:
1.Cesar Cipher
2.Substitution Cipher
Enter your choice:1
Cesar Cipher
************
Enter 'E' to encrypt or 'D' to decrypt: d
Input
*****
Enter the text: phhwphdiwhuwrjdsduwb
Output
******
Decrypted text: meetmeaftertogaparty
Cesar Cipher & Substitution Cipher
**********************************
Menu:
1.Cesar Cipher
2.Substitution Cipher
Enter your choice:2
Substitution Cipher
*******************
Enter 'E' to encrypt or 'D' to decrypt: e
Input
*****
Enter the text: meetmeaftertogaparty
Enter the shift value:10

Output
******
Encrypted text: woodwokpdobdyqkzkbdi
Cesar Cipher & Substitution Cipher
**********************************
Menu:
1.Cesar Cipher
2.Substitution Cipher
Enter your choice:2
Substitution Cipher
*******************
Enter 'E' to encrypt or 'D' to decrypt: d
Input
*****
Enter the text: woodwokpdobdyqkzkbdi
Enter the shift value:10
Output
******
Decrypted text: meetmeaftertogaparty
Hill Cipher
AIM:
To write a python program to implement Hill cipher.
ALGORITHM:
STEP 1: Input: The user is prompted to choose an option from the menu (Encrypt, Decrypt, or Exit).
STEP 2: Text Input: If the user chooses to Encrypt or Decrypt, they are prompted to input the
corresponding plaintext or ciphertext.
STEP 3: Preprocessing: The input text is preprocessed by removing any spaces and converting all
characters to lowercase.
STEP 4: Padding: If the length of the plaintext is odd, it is padded with the character 'x' to make it even.
This is because Hill Cipher requires plaintext to be arranged in pairs of two letters.
STEP 5: Matrix Formation: The plaintext or ciphertext is represented as a matrix of size (n x 2), where n
is the number of pairs of characters in the text. Each character in the text is replaced with its index in the
alphabet (a=0, b=1, ..., z=25).
STEP 6: Matrix Multiplication: For encryption, the key matrix is multiplied with the plaintext matrix.
For decryption, the inverse of the key matrix is multiplied with the ciphertext matrix. The resulting matrix
is of size (n x 2).
STEP 7: Index to Character Conversion: Each element in the resulting matrix is converted back to its
corresponding character in the alphabet using modular arithmetic (mod 26). The resulting ciphertext or
plaintext is a string of characters.
STEP 8: Output: The resulting ciphertext or plaintext is printed to the user.
Note :
The algorithm assumes that the input key is a 2x2 matrix and that its determinant is nonzero.
Hill system can be expressed as

Encryption:

The plaintext “paymoremoney” and use the encryption key K

The first three letters of the plaintext (PAY) are represented by the vector (15 0 24).
Then (15 0 24) K = (303 303 531) mod 26 = (17 17 11) = RRL.
Continuing the process
the ciphertext for the entire plaintext is RRLMWBKASPDH.
Decryption:

Decryption requires using the inverse of the matrix K.


The ciphertext “rrlmwbkaspdh” and use the decryption key K-1

the plaintext for the entire ciphertext is PAYMOREMONEY


Program:
import numpy as np
def hill_cipher_encrypt(plaintext, key):
plaintext = plaintext.replace(" ", "").lower()
while len(plaintext) % 2 != 0:
plaintext += "x"
plaintext_matrix = np.array([alphabet.index(char) for char in plaintext]).reshape(-1, 2)
ciphertext_matrix = np.dot(key, plaintext_matrix.T).T
ciphertext = "".join([alphabet[idx % 26] for idx in ciphertext_matrix.flatten()])
return ciphertext
def hill_cipher_decrypt(ciphertext, key):
ciphertext_matrix = np.array([alphabet.index(char) for char in ciphertext]).reshape(-1, 2)
det = key[0][0] * key[1][1] - key[0][1] * key[1][0]
key_inv = np.array([[key[1][1], -key[0][1]], [-key[1][0], key[0][0]]]) * det
key_inv = key_inv % 26
plaintext_matrix = np.dot(key_inv, ciphertext_matrix.T).T
plaintext = "".join([alphabet[idx % 26] for idx in plaintext_matrix.flatten()])
return plaintext
key = np.array([[1, 2], [3, 5]])
alphabet = "abcdefghijklmnopqrstuvwxyz"
for i in range(100):
print("\n\t\tHill Cipher")
print("\n1. Encrypt\n2. Decrypt\n3. Exit")
n = int(input("\nEnter your Option : "))
if n == 1:
plaintext = input("Plain Text : ")
ciphertext = hill_cipher_encrypt(plaintext, key)
print("Output (Cipher Text) : ", ciphertext)
elif n == 2:
ciphertext = input("\nCipher Text : ")
plaintext = hill_cipher_decrypt(ciphertext, key)
print("Decrypted plaintext:", plaintext)
elif n == 3:
print("EXIT")
exit()
else:
print("---Choose correct option---")
Output:
Hill Cipher

1. Encrypt
2. Decrypt
3. Exit

Enter your Option : 1


Plain Text : hello
Output (Cipher Text) : pphkib

Hill Cipher

1. Encrypt
2. Decrypt
3. Exit

Enter your Option : 2

Cipher Text : pphkib


Decrypted plaintext: hellox
Mono-Alphabetic Substitution Cipher
Aim:
To implement Mono-Alphabetic Substitution Cipher using Python.

Algorithm:
Step 1: Import the ‘random’ package, which is used to generate random values. In this case, it is used to
shuffle the alphabet.
Step 2: The generate_substitution_key() function creates a random substitution key by shuffling the
alphabet.
Step 3: The encrypt(plaintext, substitution_key) function uses the substitution key to encrypt a given
plaintext message.
Step 4: The decrypt(ciphertext, substitution_key) function decrypts a ciphertext using the inverse of the
substitution key.
Step 5: Takes user input for a message to be encrypted.
Step 6: Generates a substitution key.
Step 7: Prints the substitution key and the original message.
Step 8: Encrypts the message and prints the result.
Step 9: Decrypts the encrypted message and prints the decrypted result.
Using the random package, we are shuffling the alphabets:
'A': 'D', 'B': 'Y', 'C': 'E', 'D': 'O', 'E': 'B', 'F': 'C', 'G': 'S', 'H': 'P', 'I': 'V', 'J': 'L', 'K': 'X', 'L': 'N', 'M': 'M', 'N':
'W', 'O': 'T', 'P': 'U', 'Q': 'Z', 'R': 'H', 'S': 'F', 'T': 'R', 'U': 'K', 'V': 'A', 'W': 'Q', 'X': 'I', 'Y': 'J', 'Z': 'G'
The shuffled alphabets were used to replace the respected values to cipher the text.
The above is a randomly generated pair used for ciphering the text.
Plaintext H E L L O
Ciphertext P B N N T
Program:
import random
def generate_substitution_key():
"""Generates a random substitution key."""
alphabet = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
shuffled_alphabet = list(alphabet)
random.shuffle(shuffled_alphabet)
substitution_key = dict(zip(alphabet, shuffled_alphabet))
return substitution_key
def encrypt(plaintext, substitution_key):
"""Encrypts the plaintext using the substitution key."""
ciphertext = ''.join(substitution_key.get(char, char) for char in plaintext.upper())
return ciphertext
def decrypt(ciphertext, substitution_key):
"""Decrypts the ciphertext using the inverse of the substitution key."""
inverse_key = {v: k for k, v in substitution_key.items()}
plaintext = ''.join(inverse_key.get(char, char) for char in ciphertext.upper())
return plaintext
def main():
print("\t\t\tMono-Alphabetic Substitution Cipher")
print("\t\t\t***********************************")
print("Input")
print("-----")
message = input("Enter the message to be encrypted: ")
print("\n\n\nGenerating the substitution key ...")
print("------------------------------------")
substitution_key = generate_substitution_key()
print("Substitution Key:", substitution_key)
print("Given Message:", message)
print("\nEncryption")
print("---------")
encrypted_message = encrypt(message, substitution_key)
print("Encrypted Message:", encrypted_message)
print("\nDecryption")
print("---------")
decrypted_message = decrypt(encrypted_message, substitution_key)
print("Decrypted Message:", decrypted_message)
if __name__ == "__main__":
main()
Output:
Mono-Alphabetic Substitution Cipher
*******************************
Input
-------
Enter the message to be encrypted: meetmeaftertogaparty

Generating the substitution key ...


-------------------------------------
Substitution Key: {'A': 'Q', 'B': 'Y', 'C': 'X', 'D': 'K', 'E': 'M', 'F': 'U', 'G': 'J', 'H': 'A', 'I': 'H', 'J': 'I', 'K': 'P',
'L': 'V', 'M': 'L', 'N': 'F', 'O': 'W', 'P': 'D', 'Q': 'B', 'R': 'E', 'S': 'R', 'T': 'O', 'U': 'Z', 'V': 'C', 'W': 'S', 'X': 'T',
'Y': 'G', 'Z': 'N'}
Given Message: meetmeaftertogaparty

Encryption
---------
Encrypted Message: LMMOLMQUOMEOWJQDQEOG

Decryption
---------
Decrypted Message: MEETMEAFTERTOGAPARTY
Data Encryption Standards (DES) Algorithm
AIM:
To write a python program to implement DES.
ALGORITHM:
STEP 1: Key Generation: The key_generation method generates two subkeys (key1 and key2) using the
initial key (key) and permutation tables (P10 and P8).
STEP 2: Circular Shift Function (shift): The shift method performs circular shifts on the left and right
halves of the key.
STEP 3: Encryption Function (encryption): The encryption method takes an 8-bit plaintext as input,
performs the initial permutation (IP), two rounds of encryption using the Feistel function (function_), and
the final permutation (IP_inv).It prints the intermediate results during encryption.
STEP 4: Binary Conversion Function (binary_): The binary_ method calls the binary function to convert
a decimal value to a 2-bit binary representation.
STEP 5: Feistel Function (function_): The function_ method implements the Feistel function using the
expansion permutation (EP), permutation (P4), and S-boxes (S0 and S1).
STEP 6: Swap Function (swap): The swap method swaps the left and right halves of the given array.
STEP 7: Decryption Function (decryption): The decryption method performs the reverse of the
encryption process using the subkeys in reverse order.
STEP 8: Menu and Main Execution: The script starts by creating an instance of the DES class and prints
a menu for the user to choose between encryption, decryption, or exit. It reads user input and performs
the corresponding operation.
General Description of DES Algorithm
Program:
def binary(val):
if val == 0:
return "00"
elif val == 1:
return "01"
elif val == 2:
return "10"
else:
return "11"
class DES:
def __init__(self):
self.key = [1, 1, 0, 0, 0, 1, 1, 1, 1, 0] # extra example for checking purpose
self.P10 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
self.P8 = [6, 3, 7, 4, 8, 5, 10, 9]
self.key1 = [0] * 8
self.key2 = [0] * 8
self.IP = [2, 6, 3, 1, 4, 8, 5, 7]
self.EP = [4, 1, 2, 3, 2, 3, 4, 1]
self.P4 = [2, 4, 3, 1]
self.IP_inv = [4, 1, 3, 5, 7, 2, 8, 6]
self.S0 = [[1, 0, 3, 2], [3, 2, 1, 0], [0, 2, 1, 3], [3, 1, 3, 2]]
self.S1 = [[0, 1, 2, 3], [2, 0, 1, 3], [3, 0, 1, 0], [2, 1, 0, 3]]
self.key_generation() # Key generation is executed once at the beginning
def key_generation(self):
key_ = [self.key[i - 1] for i in self.P10]
Ls = key_[:5]
Rs = key_[5:]
Ls_1 = self.shift(Ls, 1)
Rs_1 = self.shift(Rs, 1)
key1_ = Ls_1 + Rs_1
self.key1 = [key1_[i - 1] for i in self.P8]
Ls_2 = self.shift(Ls, 3)
Rs_2 = self.shift(Rs, 3)
key2_ = Ls_2 + Rs_2
self.key2 = [key2_[i - 1] for i in self.P8]
def shift(self, ar, n):
ar = ar[n:] + ar[:n]
return ar
def encryption(self, plaintext):
arr = [plaintext[i - 1] for i in self.IP]
print("\nInitial Permutation (IP):")
print(" ".join(map(str, arr)))
arr1 = self.function_(arr, self.key1)
print("\nAfter First Round:")
print(" ".join(map(str, arr1)))
after_swap = self.swap(arr1, len(arr1) // 2)
arr2 = self.function_(after_swap, self.key2)
print("\nAfter Second Round:")
print(" ".join(map(str, arr2)))
ciphertext = [arr2[i - 1] for i in self.IP_inv]
print("\nFinal Cipher Text:")
print(" ".join(map(str, ciphertext)))
return ciphertext
def binary_(self, val):
return binary(val)
def function_(self, ar, key_):
l = ar[:4]
r = ar[4:]
ep = [r[i - 1] for i in self.EP]
ar = [key_[i] ^ ep[i] for i in range(8)]
l_1 = ar[:4]
r_1 = ar[4:]
row = int(str(l_1[0]) + str(l_1[3]), 2)
col = int(str(l_1[1]) + str(l_1[2]), 2)
val = self.S0[row][col]
str_l = self.binary_(val)
row = int(str(r_1[0]) + str(r_1[3]), 2)
col = int(str(r_1[1]) + str(r_1[2]), 2)
val = self.S1[row][col]
str_r = self.binary_(val)
r_ = [int(str_l[i]) for i in range(2)] + [int(str_r[i]) for i in range(2)]
r_p4 = [r_[i - 1] for i in self.P4]
l = [l[i] ^ r_p4[i] for i in range(4)]
output = l + r
return output
def swap(self, array, n):
l = array[:n]
r = array[n:]
output = r + l
return output
def decryption(self, ar):
arr = [ar[i - 1] for i in self.IP]
arr1 = self.function_(arr, self.key2)
after_swap = self.swap(arr1, len(arr1) // 2)
arr2 = self.function_(after_swap, self.key1)
decrypted = [arr2[i - 1] for i in self.IP_inv]
return decrypted
if __name__ == "__main__":
obj = DES()
print("\t\tSimple DES Algorithm")
print("\t\t-------------------")
obj.key_generation() # Print Key-1 and Key-2 after initialization
while True:
print("\nMenu:")
print("1. Encryption")
print("2. Decryption")
print("3. Exit")
choice = input("Enter your choice (1-3): ")
if choice == "1":
print("Encryption of 8-bit binary data")
plaintext = [0, 0, 1, 0, 1, 0, 0, 0]
print("\nYour plain Text is:")
print(" ".join(map(str, plaintext)))
ciphertext = obj.encryption(plaintext)
elif choice == "2":
print("Decryption of 8-bit binary data.")
decrypted = obj.decryption(ciphertext)
print("\nYour decrypted Text is:")
print(" ".join(map(str, decrypted)))
elif choice == "3":
print("Exiting the program. Goodbye!")
break
else:
print("Invalid choice. Please enter a number between 1 and 3.")
Output:
Simple DES Algorithm
-----------------------------

Menu:
1. Encryption
2. Decryption
3. Exit
Enter your choice (1-3): 1
Encryption of 8-bit binary data

Your plain Text is:


00101000

Initial Permutation (IP):


00100010

After First Round:


00110010

After Second Round:


00010011

Final Cipher Text:


10001010

Menu:
1. Encryption
2. Decryption
3. Exit
Enter your choice (1-3): 2
Decryption of 8-bit binary data.
Your decrypted Text is:
00101000

Menu:
1. Encryption
2. Decryption
3. Exit
Enter your choice (1-3): 3
Exiting the program. Goodbye!
Rail Fence Cipher
Aim:
To write a python program to implement the rail fence cipher.

ALGORITHM:
STEP 1: Define a function "encryptRailFence(text, key)" that takes a plain text and a key as inputs.
STEP 2: Initialize a 2D list called "rail" with "len(text)" rows and "key" columns with the value "\n".
STEP 3: Initialize a boolean variable "dir_down" to False, and integer variables "row" and "col" to 0.
STEP 4: Loop through the characters in the plain text, and for each character:
• Check if the current row is either the top row or the bottom row. If so, change the direction of
traversal by flipping the "dir_down" variable.
• Add the character to the current position in the "rail" list.
• Update the "col" variable to move to the next column.
• Update the "row" variable based on the direction of traversal.
STEP 5: Flatten the "rail" list by iterating through each row and column and adding each non-"\n"
character to a list called "result".
STEP 6: Return the joined version of the "result" list as the ciphertext.
STEP 7: Define a function "decryptRailFence(cipher, key)" that takes a ciphertext and a key as inputs.
STEP 8: Implement the decryption process by following steps 2-5 above to initialize the "rail" list and
populate it with asterisks at the appropriate positions, then use the asterisks as markers to insert the
ciphertext characters into the "rail" list. Finally, traverse the "rail" list in the same way as in step 4 above,
but this time add each non-asterisk character to a list called "result".
Return the joined version of the "result" list as the plaintext.
encipher the message “meet me after the toga party” with a rail fence of depth 2
Program:
def encryptRailFence(text,key):
rail=[['\n' for i in range(len(text))]
for j in range(key)]
dir_down=False
row,col=0,0
for i in range(len(text)):
if(row==0)or(row==key-1):
dir_down=not dir_down
rail[row][col]=text[i]
col+=1
if dir_down:
row+=1
else:
row-=1
result=[]
for i in range(key):
for j in range(len(text)):
if rail[i][j]!='\n':
result.append(rail[i][j])
return("".join(result))
def decryptRailFence(cipher,key):
rail=[['\n' for i in range(len(cipher))]
for j in range(key)]
dir_down=None
row,col=0,0
for i in range(len(cipher)):
if row==0:
dir_down=True
if row==key-1:
dir_down=False
rail[row][col]='*'
col+=1
if dir_down:
row+=1
else:
row-=1
index=0
for i in range(key):
for j in range(len(cipher)):
if((rail[i][j]=='*')and(index<len(cipher))):
rail[i][j]=cipher[index]
index+=1
result=[]
row,col=0,0
for i in range(len(cipher)):
if row == 0:
dir_down = True
if row == key - 1:
dir_down = False
if (rail[row][col] != '*'):
result.append(rail[row][col])
col += 1
if dir_down:
row += 1
else:
row -= 1
return ("".join(result))
for i in range(100):
print("\n\n\t\tTranposition Technique with a RailFence of depth2")
print("\n1. Encrypt\n2. Decrypt\n3. Exit")
n = int(input("\nEnter the Option : "))
if n == 1:
print("\n\t\tTranposition Cipher\n\t\tRailFence of depth 2\n")
str1 = input("Plain Text : ")
print("Output (Cipher Text) : ", encryptRailFence(str1, 2))
elif n == 2:
print("\n\t\tTranposition Cipher\n\t\tRailFence of depth 2\n")
str2 = input("Cipher Text : ")
print("Output (Plain Text) : ", decryptRailFence(str2, 2))
elif n == 3:
print("EXIT")
break
else:
print("---Enter the correct option---")
Output:
Tranposition Technique with a RailFence of depth2
1. Encrypt
2. Decrypt
3. Exit
Enter the Option : 1
Tranposition Cipher
RailFence of depth 2
Plain Text : meet me after toga party
Output (Cipher Text) : me eatrtg atetm fe oapry

Tranposition Technique with a RailFence of depth2


1. Encrypt
2. Decrypt
3. Exit
Enter the Option : 2
Tranposition Cipher
RailFence of depth 2
Cipher Text : me eatrtg atetm fe oapry
Output (Plain Text) : meet me after toga party

Tranposition Technique with a RailFence of depth2


1. Encrypt
2. Decrypt
3. Exit
Enter the Option : 3
EXIT
Row / Column Transposition Cipher
Aim:
To write a python program to implement Row/ Column Transposition Cipher.

Algorithm:
Encryption:
STEP 1: Remove any spaces from the plain text.
STEP 2: Determine the number of rows needed based on the length of the plain text and key.
STEP 3: Add padding "x" to the plain text if necessary to fill the grid.
STEP 4: Create an empty grid with the number of rows and columns needed.
STEP 5: Fill in the first row of the grid with the key.
STEP 6: Fill in the remaining rows with the padded plain text.
STEP 7: Read off the ciphertext row by row from the grid.
STEP 8: Add spaces between each character in the ciphertext and return.
Decryption:
STEP 1: Determine the number of columns needed based on the length of the key.
STEP 2: Determine the number of rows needed based on the length of the ciphertext and number of
columns.
STEP 3: Create an empty grid with the number of rows and columns needed.
STEP 4: Fill in the grid with the ciphertext by column, starting from the first column.
STEP 5: Read off the plaintext row by row from the grid.
STEP 6: Remove any padding "x" from the plaintext.
STEP 7: Remove the key from the plaintext.
STEP 8: Remove any spaces between characters in the plaintext and return.
Enciphering:

Deciphering:
Program:
import math
def encrypt(plaintext, key):
rows = (len(plaintext) + len(key) - 1) // len(key)
plaintext += "x" * (rows * len(key) - len(plaintext))
grid = [["" for _ in range(len(key))] for _ in range(rows + 1)]
for i, letter in enumerate(key):
grid[0][i] = letter
for i in range(rows):
for j in range(len(key)):
index = i * len(key) + j
if index < len(plaintext):
grid[i + 1][j] = plaintext[index]
else:
grid[i + 1][j] = "x"
print("\nGrid:")
for row in grid:
print(" ".join(row))
ciphertext = "".join([grid[j][i] for i in range(len(key)) for j in range(rows + 1)])
ciphertext = " ".join([ciphertext[i:i + 1] for i in range(0, len(ciphertext), 1)])
return ciphertext
def decrypt(ciphertext, key):
num_columns = len(key)
num_rows = math.ceil(len(ciphertext) / num_columns)
num_pad = (num_columns * num_rows) - len(ciphertext)
plaintext = [''] * num_rows
col = 0
row = 0
for symbol in ciphertext:
plaintext[row] += symbol
row += 1
if (row == num_rows) or (row == num_rows - 1 and col >= num_columns - num_pad):
row = 0
col += 1
return ''.join(plaintext)
print()
print("TRANSPOSITION CIPHER".center(60, " "))
print()
plaintext = input("Enter the plain text: ")
key = input("Enter the key: ")
print("\n\n The Given Plain Text is: ", plaintext)
print("\n The Given Key is: ", key)
ciphertext = encrypt(plaintext, key)
decrypttext = decrypt(ciphertext,key)
remove_cipher_space = ciphertext.replace(" ", "")
print("\n Cipher Text(Encrypted Text): ", remove_cipher_space)
remove_x = decrypttext.replace("x", "")
remove_key = remove_x.replace(key, "")
remove_space = remove_key.replace(" ", "")
print("\n Plain Text(Decrypted Text): ", remove_space)
Output:
TRANSPOSITION CIPHER
Enter the plain text: meetmeaftertogaparty
Enter the key: secret
The Given Plain Text is: meetmeaftertogaparty
The Given Key is: secret

Grid:
secret
meetme
aftert
ogapar
tyxxxx

Cipher Text(Encrypted Text): smaoteefgycetaxrtepxemraxtetrx


Plain Text(Decrypted Text): meetmeaftertogaparty
Playfair Cipher
AIM:
To write a python program to implement Playfair cipher
ALGORITHM:
STEP 1: Import the string module to use the ascii_uppercase constant.
STEP 2: Prompt the user to input the key and convert it to uppercase.
STEP 3: Create the Playfair matrix by appending unique characters from the key andthe remaining
alphabet to a list. The matrix is a list of lists, where each sub-list represents a row in the matrix.
STEP 4: Define two helper functions: find_position(matrix, char) to find the row and column of a
character in the Playfair matrix, and encrypt_pair(matrix, pair) to encrypt a single pair of characters.
STEP 5: Define the encrypt(plaintext, matrix) function to encrypt the plaintext using the Playfair Cipher.
First, convert the plaintext to uppercase and replace any occurrences of 'J' with 'I'. Next, split the plaintext
into pairs of characters, handling special cases where a pair contains duplicate characters or there is an
odd number of characters. Finally, iterate through the pairs and encrypt each one using the
encrypt_pair(matrix, pair) function.
STEP 6: Define the decrypt_pair(matrix, pair) function to decrypt a single pair of characters. The
implementation is similar to encrypt_pair(matrix, pair), but uses subtraction instead of addition to find
the new index of the character in the matrix.
STEP 7: Define the decrypt(ciphertext, matrix) function to decrypt the ciphertext using the Playfair
Cipher. First, iterate through the ciphertext in pairs and decrypt each one using the decrypt_pair(matrix,
pair) function. Then, replace any occurrences of 'X' with an empty string.
STEP 8: Prompt the user to input the plaintext and encrypt it using the encrypt(plaintext, matrix) function.
Print the plaintext, ciphertext, and decrypted plaintext.
PLAYFAIR CIPHER
The Playfair algorithm is based on the use of a 5 * 5 matrix of letters constructed using a
keyword
Keyword = MONARCHY

The matrix is constructed by filling in the letters of the keyword (minus duplicates) from left
to right and from top to bottom, and then filling in the remainder of the matrix with the
remaining letters in alphabetic order. The letters I and J count as one letter.
Program:
import string
print()
print("THE PLAYFAIR CIPHER".center(30, " "))
print()
key = input("Enter the secret key: ")
matrix = []
def fill_matrix(val):
for k in val.upper():
if k not in ['I', 'J']:
if k not in matrix:
matrix.append(k)
else:
if k == 'I':
if k not in matrix:
matrix.append(k)
elif k == 'J':
if 'I' not in matrix:
matrix.append('I')
fill_matrix(key)
fill_matrix(string.ascii_uppercase)
k_matrix = []
start, end = 0, 5
for i in range(5):
m = matrix[start: end]
k_matrix.append(m)
start += 5
end += 5
print()
print("key generated matrix:")
print()
for lst in k_matrix:
print(lst, "\n")
print()
def find_position(matrix, char):
row = 0
col = 0
for i in range(5):
for j in range(5):
if matrix[i * 5 + j] == char:
row = i
col = j
return row, col
def encrypt_pair(matrix, pair):
a, b = pair
row1, col1 = find_position(matrix, a)
row2, col2 = find_position(matrix, b)
if row1 == row2:
return matrix[row1 * 5 + (col1 + 1) % 5] + matrix[row2 * 5 + (col2 + 1) % 5]
elif col1 == col2:
return matrix[((row1 + 1) % 5) * 5 + col1] + matrix[((row2 + 1) % 5) * 5 + col2]
else:
return matrix[row1 * 5 + col2] + matrix[row2 * 5 + col1]
def decrypt_pair(matrix, pair):
a, b = pair
row1, col1 = find_position(matrix, a)
row2, col2 = find_position(matrix, b)
if row1 == row2:
return matrix[row1 * 5 + (col1 - 1) % 5] + matrix[row2 * 5 + (col2 - 1) % 5]
elif col1 == col2:
return matrix[((row1 - 1) % 5) * 5 + col1] + matrix[((row2 - 1) % 5) * 5 + col2]
else:
return matrix[row1 * 5 + col2] + matrix[row2 * 5 + col1]
def encrypt(plaintext, matrix):
plaintext = plaintext.upper().replace('J', 'I')
plaintext_pairs = []
for i in range(0, len(plaintext), 2):
if i == len(plaintext) - 1:
plaintext_pairs.append(plaintext[i] + 'X')
elif plaintext[i] == plaintext[i + 1]:
plaintext_pairs.append(plaintext[i] + 'X')
plaintext = plaintext[:i + 1] + 'X' + plaintext[i + 1:]
else:
plaintext_pairs.append(plaintext[i:i + 2])
ciphertext = ''
for pair in plaintext_pairs:
ciphertext += encrypt_pair(matrix, pair)
return ciphertext
def decrypt(ciphertext, matrix):
plaintext = ''
for i in range(0, len(ciphertext), 2):
plaintext += decrypt_pair(matrix, ciphertext[i:i + 2])
return plaintext.replace('X', '')
plaintext = input("Enter the plain text: ")
ciphertext = encrypt(plaintext, matrix)
decrypted_plaintext = decrypt(ciphertext, matrix)
print(f"Plaintext: {plaintext}")
print()
print("ENCRYPTION:")
print(f"Ciphertext: {ciphertext}")
print()
print("DECRYPTION:")
print(f"Decrypted plaintext: {decrypted_plaintext}")
Output:
THE PLAYFAIR CIPHER

Enter the secret key: meeting

key generated matrix:

['M', 'E', 'T', 'I', 'N']

['G', 'A', 'B', 'C', 'D']

['F', 'H', 'K', 'L', 'O']

['P', 'Q', 'R', 'S', 'U']

['V', 'W', 'X', 'Y', 'Z']

Enter the plain text: meetmeaftertogaparty


Plaintext: meetmeaftertogaparty

ENCRYPTION:
Ciphertext: ETTIETGHITXBFDGQBQIX

DECRYPTION:
Decrypted plaintext: MEETMEAFTERTOGAPARTY
RSA Algorithm
AIM:
To write a python program to implement RSA algorithm.

ALGORITHM:
STEP 1: Key generation: Choose two large prime numbers p and q, and compute their product
n = pq. Compute the totient of n, which is phi(n) = lcm(p-1, q-1). Choose a public exponent e
that is coprime to phi(n), and compute the private exponent d such that de is congruent to 1
modulo phi(n). The public key is the pair (e, n), and the private key is the pair (d, n).
STEP 2: Message encryption: Convert the message to be encrypted into an integer m, and
apply the public key (e, n) to compute the ciphertext c = m^e mod n.
STEP 3: Message transmission: Send the ciphertext to the recipient.
STEP 4: Message decryption: Apply the private key (d, n) to the ciphertext c to obtain the
original message m = c^d mod n.
STEP 5: Message verification: Check that the decrypted message is the same as the original
message.
For example:
1. Select two prime numbers, p = 17 and q = 11.
2. Calculate n = pq = 17 * 11 = 187.
3. Calculate f(n) = (p - 1)(q - 1) = 16 * 10 = 160.
4. Select e such that e is relatively prime to f(n) = 160 and less than f(n); we choose e= 7.
5. Determine d such that de K 1 (mod 160) and d 6 160. The correct value is d = 23, because
23 * 7 = 161 = (1 * 160) + 1; d can be calculated using the extended Euclid’s algorithm
For encryption
1. PU = {7, 187} and private key PR = {23, 187}
2. plaintext input M = 88.
3. To calculate C = 88^7 mod 187
For decryption,
To calculate M = 1123 mod 187
Program:
import math
def gcd(a, b):
while b:
a, b = (b, a % b)
return a
def extended_gcd(a, b):
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = b, a
while r != 0:
quotient = old_r // r
old_r, r = r, old_r - quotient * r
old_s, s = s, old_s - quotient * s
old_t, t = t, old_t - quotient * t
return old_r, old_s, old_t
print()
print(" RSA Algorithm ".center(50, "*"))
p = int(input("\t\nEnter a prime number p: "))
q = int(input("\t\nEnter a prime number q: "))
e = int(input("\t\nEnter a public exponent e: "))
msg = int(input("\t\nEnter the message to be encrypted: "))
n=p*q
phi = (p - 1) * (q - 1)
while (e < phi):
if (gcd(e, phi) == 1):
break
else:
e=e+1
g, x, y = extended_gcd(e, phi)
if g != 1:
raise ValueError("e is not invertible")
d = x % phi
print()
c = pow(msg, e, n)
print("Encrypted data: ", c)
print()
m = pow(c, d, n)
m = float(m)
print("Decrypted message: ", m)
Output:
***************** RSA Algorithm ******************

Enter a prime number p: 3

Enter a prime number q: 11

Enter a public exponent e: 7

Enter the message to be encrypted: 8

Encrypted data: 2

Decrypted message: 8.0


Diffie-Hellman Key Exchange
AIM:
To write a python program to find the PUBLIC KEY, PRIVATE KEY,SHARED
SECURED KEY.

ALGORITHM:
The code begins by asking the user to enter a prime number.
STEP 1: The prime is then used to calculate the base, which will be used in generating a private
key for each party.
STEP 2: The next line asks the user to input their private key options: 1) manual method and
2) random key generation.
STEP 3: The code will generate a random number between 1 and the prime number, which is
then used to encrypt the private key.
STEP 4: The code will generate a random number between 1 and the prime number, which is
then used to encrypt the private key.
STEP 5: The code starts by asking the user to enter an option.
STEP 6: The user enters 1 or 2, and then the code prints a message saying "Enter alice's private
key" or "Enter bob's private key."
STEP 7: The next line asks for input from the user.
STEP 8: It is asking for either Alice's public key (alice_public) or Bob's public key
(bob_public).
STEP 9: If they enter one of these keys, it will be used in place of their own private keys.
STEP 10: The code is a simple example of how to use the pow() function.
STEP 11: The code asks the user for an integer, and then prompts them for two integers that
are in between 1 and 2.
STEP 12: The first integer is entered as alice's private key, and the second integer is entered
as bob's private key.
STEP 13: If the user enters 1, they will enter alice's private key into the variable called
alice_private .
STEP 14: If they enter 2, they will enter bob's private key into the variable called bob_private.
STEP 15: The code starts by printing the following: print("\t\tVALID OPTIONS: 1 OR 2")
The code then asks for input from the user.
STEP 16: The user can enter either "1" or "2".
STEP 17: If they enter "1", it will calculate the public values for each party, and if they enter
"2", it will calculate a Diffie-Hellman key exchange.
STEP 18: If case in [1, 2]: This line is an if statement that checks to see if the value entered by
the user is equal to one of two possible values (in this case, either 1 or 2).
STEP 19: If so, then it calculates a Diffie-Hellman key exchange.

Working Principle:
The prime number q = 353 and a primitive root of 353,
α = 3.
A and B select private keys XA = 97
XB = 233
Compute public key:
A computes YA = 397 mod 353 = 40.
B computes YB = 3233 mod 353 = 248.
After they exchange public keys, each can compute the common secret key: A computes K =
(YB)XA mod 353 = 24897 mod 353 = 160.
B computes K = (YA)XB mod 353 = 40233 mod 353 = 160.
Program:
import random
print("PUBLIC KEY CRYPTOGRAPHY".center(60, " "))
print("DIFFIE-HELLMAN KEY EXCHANGE".center(60, " "))
print()
prime = int(input("\t\tEnter the prime: "))
base = int(input("\t\tEnter base: "))
print()
print("\t\tPrivate key input options:")
print("\t\t1. Manual method")
print("\t\t2. Random key generation")
case = int(input("\t\tEnter an option (1/2): "))
print()
if case == 1:
alice_private = int(input("\t\tEnter alice's private key: "))
bob_private = int(input("\t\tEnter bob's private key: "))
elif case == 2:
alice_private = random.randint(1,prime)
bob_private = random.randint(1,prime)
else:
print("\t\tINVALID OPTION")
print("\t\tVALID OPTIONS: 1 OR 2")

if case in [1, 2]:


alice_public = (base ** alice_private) % prime
bob_public = (base ** bob_private) % prime

# Exchange public values


shared_secret_alice = (bob_public ** alice_private) % prime
shared_secret_bob = (alice_public ** bob_private) % prime
print()
print("PUBLIC KEY CRYPTOGRAPHY".center(60, " "))
print("DIFFIE-HELLMAN KEY EXCHANGE".center(60, " "))
print()
print("\t\tUSER A PRIVATE KEY AND PUBLIC KEY")
print(f"\t\tAlice's private: {alice_private}")
print(f"\t\tAlice's public key: {alice_public}")
print()
print("\t\tUSER B PRIVATE KEY AND PUBLIC KEY")
print(f"\t\tBob's private: {bob_private}")
print(f"\t\tBob's public key: {bob_public}")
print()
print("\t\tUSER A AND USER B SHARED KEY")
print(f"\t\tAlice's shared key: {shared_secret_alice}")
print(f"\t\tBob's shared key: {shared_secret_bob}")
Output:
Manual Method
PUBLIC KEY CRYPTOGRAPHY
DIFFIE-HELLMAN KEY EXCHANGE

Enter the prime: 19


Enter base: 10

Private key input options:


1. Manual method
2. Random key generation
Enter an option (1/2): 1

Enter alice's private key: 5


Enter bob's private key: 6

PUBLIC KEY CRYPTOGRAPHY


DIFFIE-HELLMAN KEY EXCHANGE

USER A PRIVATE KEY AND PUBLIC KEY


Alice's private: 5
Alice's public key: 3

USER B PRIVATE KEY AND PUBLIC KEY


Bob's private: 6
Bob's public key: 11

USER A AND USER B SHARED KEY


Alice's shared key: 7
Bob's shared key: 7
Random Method
PUBLIC KEY CRYPTOGRAPHY
DIFFIE-HELLMAN KEY EXCHANGE

Enter the prime: 17


Enter base: 10

Private key input options:


1. Manual method
2. Random key generation
Enter an option (1/2): 2

PUBLIC KEY CRYPTOGRAPHY


DIFFIE-HELLMAN KEY EXCHANGE

USER A PRIVATE KEY AND PUBLIC KEY


Alice's private: 14
Alice's public key: 8

USER B PRIVATE KEY AND PUBLIC KEY


Bob's private: 6
Bob's public key: 9

USER A AND USER B SHARED KEY


Alice's shared key: 4
Bob's shared key: 4

You might also like