Cryptography Lab
Cryptography 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.
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
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 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.
0 0 0
0 1 1
1 0 1
1 1 0
H e l l o W o r l d
Result ‘H’
Result ‘e’
Result ‘I’
Result ‘d’
Program:
def xor(input_string, ch):
result = ""
if ch == 1:
# Convert the character to ASCII, XOR with 1, and convert back to character
result += chr(ord(char) ^ 1)
return result
else:
# Convert the character to ASCII, XOR with 0, and convert back to character
result += chr(ord(char) ^ 0)
return result
if __name__ == "__main__":
for i in range(100):
print("\t\t\t------------------")
if ch == 1:
else:
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
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
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 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:
1. Encrypt
2. Decrypt
3. Exit
Hill Cipher
1. Encrypt
2. Decrypt
3. Exit
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
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
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
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
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
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 ******************
Encrypted data: 2
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")