CRYPTO
MAT
(using crypto packages) -- pip install cryptography , pip install pycryptodome
Ceasar Cipher
# Basic Caesar Cipher implementation
def caesar_cipher(text, shift):
result = ""
for char in text:
if char.isalpha():
shift_amount = shift % 26
new_char = chr(((ord(char.upper()) - 65 + shift_amount) % 26) + 65)
result += new_char if char.isupper() else new_char.lower()
else:
result += char
return result
def caesar_decipher(text, shift):
return caesar_cipher(text, -shift)
# Example usage of basic Caesar Cipher
message = input("Enter message for Caesar Cipher: ")
shift = int(input("Enter shift value: "))
encrypted_text = caesar_cipher(message, shift)
decrypted_text = caesar_decipher(encrypted_text, shift)
print("Basic Caesar Encrypted:", encrypted_text)
print("Basic Caesar Decrypted:", decrypted_text)
///////////////////////////////////////////////////////////////////////////////
Playfair Cipher
def playfair_cipher_encrypt(text, key):
"""Encrypts the given text using the Playfair cipher with the provided key."""
matrix = generate_playfair_matrix(key)
text = preprocess_text(text)
encrypted_text = ""
for i in range(0, len(text), 2):
a, b = text[i], text[i + 1]
row1, col1, row2, col2 = get_positions(matrix, a, b)
# Rule 1: If both letters are in the same row, shift right
if row1 == row2:
encrypted_text += matrix[row1][(col1 + 1) % 5] + matrix[row2][(col2 + 1) % 5]
# Rule 2: If both letters are in the same column, shift down
elif col1 == col2:
encrypted_text += matrix[(row1 + 1) % 5][col1] + matrix[(row2 + 1) % 5][col2]
# Rule 3: Form a rectangle and swap columns
else:
encrypted_text += matrix[row1][col2] + matrix[row2][col1]
return encrypted_text
def playfair_cipher_decrypt(text, key):
"""Decrypts the given text using the Playfair cipher with the provided key."""
matrix = generate_playfair_matrix(key)
decrypted_text = ""
for i in range(0, len(text), 2):
a, b = text[i], text[i + 1]
row1, col1, row2, col2 = get_positions(matrix, a, b)
# Reverse of encryption rules
if row1 == row2:
decrypted_text += matrix[row1][(col1 - 1) % 5] + matrix[row2][(col2 - 1) % 5]
elif col1 == col2:
decrypted_text += matrix[(row1 - 1) % 5][col1] + matrix[(row2 - 1) % 5][col2]
else:
decrypted_text += matrix[row1][col2] + matrix[row2][col1]
return decrypted_text
def generate_playfair_matrix(key):
"""Generates a 5x5 Playfair cipher matrix using the given key."""
key = "".join(dict.fromkeys(key.upper().replace("J", "I"))) # Remove duplicates and replace 'J' with 'I'
alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
matrix = []
for char in key + alphabet:
if char not in matrix:
matrix.append(char)
return [matrix[i * 5:(i + 1) * 5] for i in range(5)] # Convert list into 5x5 matrix
def preprocess_text(text):
"""Prepares the text for encryption by handling duplicate letters and spaces."""
text = text.upper().replace("J", "I").replace(" ", "")
processed_text = ""
i = 0
while i < len(text):
if i == len(text) - 1: # If odd length, add 'X' at the end
processed_text += text[i] + "X"
break
if text[i] == text[i + 1]: # If duplicate letters, insert 'X' between them
processed_text += text[i] + "X"
i += 1
else:
processed_text += text[i] + text[i + 1]
i += 2
return processed_text
def get_positions(matrix, a, b):
"""Finds the positions of two letters in the Playfair cipher matrix."""
for row in range(5):
for col in range(5):
if matrix[row][col] == a:
row1, col1 = row, col
if matrix[row][col] == b:
row2, col2 = row, col
return row1, col1, row2, col2
# Example usage
key = input("Enter Playfair Cipher key: ")
message = input("Enter message for Playfair Cipher: ")
encrypted_text = playfair_cipher_encrypt(message, key)
decrypted_text = playfair_cipher_decrypt(encrypted_text, key)
print("Playfair Encrypted:", encrypted_text)
print("Playfair Decrypted:", decrypted_text)
///////////////////////////////////////////////////////////////////////////////////
HILL CIPHER
import numpy as np
import math
def mod_inverse(matrix, mod):
"""Finds the modular inverse of a matrix under a given modulo."""
det = int(np.round(np.linalg.det(matrix)))
det = det % mod
if math.gcd(det, mod) != 1:
raise ValueError("Key matrix is not invertible under modulo 26. Choose a different matrix.")
det_inv = pow(det, -1, mod)
adjugate = np.round(det * np.linalg.inv(matrix)).astype(int) % mod
return (det_inv * adjugate) % mod
def text_to_numbers(text):
"""Converts text to numerical representation (A=0, B=1, ..., Z=25)."""
return [ord(char) - ord('A') for char in text.upper() if char.isalpha()]
def numbers_to_text(numbers):
"""Converts numerical representation back to text."""
return ''.join(chr(num + ord('A')) for num in numbers)
def hill_cipher_encrypt(plaintext, key_matrix):
"""Encrypts plaintext using Hill Cipher and the given key matrix."""
plaintext_numbers = text_to_numbers(plaintext)
while len(plaintext_numbers) % key_matrix.shape[0] != 0:
plaintext_numbers.append(23) # Padding with 'X' (23 in A-Z mapping)
plaintext_matrix = np.array(plaintext_numbers).reshape(-1, key_matrix.shape[0]).T
ciphertext_matrix = np.dot(key_matrix, plaintext_matrix) % 26
return numbers_to_text(ciphertext_matrix.T.flatten())
def hill_cipher_decrypt(ciphertext, key_matrix):
"""Decrypts ciphertext using Hill Cipher and the given key matrix."""
try:
key_matrix_inv = mod_inverse(key_matrix, 26)
except ValueError as e:
print(e)
return "Decryption failed. Invalid key matrix."
ciphertext_numbers = text_to_numbers(ciphertext)
ciphertext_matrix = np.array(ciphertext_numbers).reshape(-1, key_matrix.shape[0]).T
decrypted_matrix = np.dot(key_matrix_inv, ciphertext_matrix) % 26
return numbers_to_text(decrypted_matrix.T.flatten())
# Example usage
key_size = int(input("Enter key matrix size (e.g., 2 for 2x2, 3 for 3x3): "))
key_input = input(f"Enter {key_size * key_size} key matrix values separated by space: ").split()
key_matrix = np.array(list(map(int, key_input))).reshape(key_size, key_size)
plaintext = input("Enter message for Hill Cipher: ")
encrypted_text = hill_cipher_encrypt(plaintext, key_matrix)
decrypted_text = hill_cipher_decrypt(encrypted_text, key_matrix)
print("Hill Cipher Encrypted:", encrypted_text)
print("Hill Cipher Decrypted:", decrypted_text)
///////////////////////////////////////////////////////////////////////////
VIGNERE CIPHER
def vigenere_encrypt(plaintext, key):
"""Encrypts plaintext using Vigenère Cipher."""
plaintext = plaintext.upper()
key = key.upper()
encrypted_text = ""
key_index = 0
for char in plaintext:
if char.isalpha():
shift = ord(key[key_index % len(key)]) - ord('A')
encrypted_text += chr((ord(char) - ord('A') + shift) % 26 + ord('A'))
key_index += 1
else:
encrypted_text += char # Keep non-alphabet characters unchanged
return encrypted_text
def vigenere_decrypt(ciphertext, key):
"""Decrypts ciphertext using Vigenère Cipher."""
ciphertext = ciphertext.upper()
key = key.upper()
decrypted_text = ""
key_index = 0
for char in ciphertext:
if char.isalpha():
shift = ord(key[key_index % len(key)]) - ord('A')
decrypted_text += chr((ord(char) - ord('A') - shift) % 26 + ord('A'))
key_index += 1
else:
decrypted_text += char # Keep non-alphabet characters unchanged
return decrypted_text
# Example usage
plaintext = input("Enter message for Vigenère Cipher: ")
key = input("Enter key for Vigenère Cipher: ")
encrypted_text = vigenere_encrypt(plaintext, key)
decrypted_text = vigenere_decrypt(encrypted_text, key)
print("Vigenère Cipher Encrypted:", encrypted_text)
print("Vigenère Cipher Decrypted:", decrypted_text)
/////////////////////////////////////////////////////////////
RAIL FENCE CIPHER
def rail_fence_encrypt(plaintext, rails):
"""Encrypts plaintext using Rail Fence Cipher."""
fence = [['\n' for _ in range(len(plaintext))] for _ in range(rails)]
row, direction = 0, 1
for i, char in enumerate(plaintext):
fence[row][i] = char
if row == 0:
direction = 1
elif row == rails - 1:
direction = -1
row += direction
return ''.join(char for row in fence for char in row if char != '\n')
def rail_fence_decrypt(ciphertext, rails):
"""Decrypts ciphertext using Rail Fence Cipher."""
fence = [['\n' for _ in range(len(ciphertext))] for _ in range(rails)]
row, direction = 0, 1
for i in range(len(ciphertext)):
fence[row][i] = '*'
if row == 0:
direction = 1
elif row == rails - 1:
direction = -1
row += direction
index = 0
for r in range(rails):
for c in range(len(ciphertext)):
if fence[r][c] == '*' and index < len(ciphertext):
fence[r][c] = ciphertext[index]
index += 1
result = []
row, direction = 0, 1
for i in range(len(ciphertext)):
result.append(fence[row][i])
if row == 0:
direction = 1
elif row == rails - 1:
direction = -1
row += direction
return ''.join(result)
# Example usage
plaintext = input("Enter message for Rail Fence Cipher: ")
rails = int(input("Enter number of rails: "))
encrypted_text = rail_fence_encrypt(plaintext, rails)
decrypted_text = rail_fence_decrypt(encrypted_text, rails)
print("Rail Fence Cipher Encrypted:", encrypted_text)
print("Rail Fence Cipher Decrypted:", decrypted_text)
///////////////////////////////////////////////////////////////////////
ROW TRANSPOSITION CIPHER
import numpy as np
def row_transposition_encrypt(plaintext, key):
"""Encrypts plaintext using Row Transposition Cipher."""
plaintext = plaintext.replace(" ", "") # Remove spaces
num_cols = len(key)
num_rows = -(-len(plaintext) // num_cols) # Ceiling division
grid = [['X' for _ in range(num_cols)] for _ in range(num_rows)]
index = 0
for i in range(num_rows):
for j in range(num_cols):
if index < len(plaintext):
grid[i][j] = plaintext[index]
index += 1
key_order = sorted(range(len(key)), key=lambda k: key[k])
ciphertext = ''.join(''.join(row[i] for row in grid) for i in key_order)
return ciphertext
def row_transposition_decrypt(ciphertext, key):
"""Decrypts ciphertext using Row Transposition Cipher."""
num_cols = len(key)
num_rows = -(-len(ciphertext) // num_cols) # Ceiling division
key_order = sorted(range(len(key)), key=lambda k: key[k])
grid = [['X' for _ in range(num_cols)] for _ in range(num_rows)]
index = 0
for col in key_order:
for row in range(num_rows):
if index < len(ciphertext):
grid[row][col] = ciphertext[index]
index += 1
plaintext = ''.join(''.join(row) for row in grid).rstrip('X') # Remove padding
return plaintext
# Example usage
plaintext = input("Enter message for Row Transposition Cipher: ")
key = list(map(int, input("Enter key as space-separated numbers (e.g., 3 1 4 2): ").split()))
encrypted_text = row_transposition_encrypt(plaintext, key)
decrypted_text = row_transposition_decrypt(encrypted_text, key)
print("Row Transposition Cipher Encrypted:", encrypted_text)
print("Row Transposition Cipher Decrypted:", decrypted_text)
//////////////////////////////////////////////////////////////////////////////////
DES
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
import base64
def des_encrypt(plaintext, key):
"""Encrypts plaintext using DES Cipher."""
cipher = DES.new(key, DES.MODE_ECB)
padded_text = pad(plaintext.encode(), DES.block_size)
encrypted_text = cipher.encrypt(padded_text)
return base64.b64encode(encrypted_text).decode()
def des_decrypt(ciphertext, key):
"""Decrypts ciphertext using DES Cipher."""
cipher = DES.new(key, DES.MODE_ECB)
encrypted_text = base64.b64decode(ciphertext)
decrypted_text = unpad(cipher.decrypt(encrypted_text), DES.block_size)
return decrypted_text.decode()
# Example usage
plaintext = input("Enter message for DES encryption: ")
key = input("Enter 8-character key: ").encode()
if len(key) != 8:
raise ValueError("Key must be exactly 8 bytes long.")
encrypted_text = des_encrypt(plaintext, key)
decrypted_text = des_decrypt(encrypted_text, key)
print("DES Encrypted:", encrypted_text)
print("DES Decrypted:", decrypted_text)
///////////////////////////////////////////////////////////////////////////////////////
AES
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
def aes_encrypt(plaintext, key):
"""Encrypts plaintext using AES Cipher."""
cipher = AES.new(key, AES.MODE_ECB)
padded_text = pad(plaintext.encode(), AES.block_size)
encrypted_text = cipher.encrypt(padded_text)
return base64.b64encode(encrypted_text).decode()
def aes_decrypt(ciphertext, key):
"""Decrypts ciphertext using AES Cipher."""
cipher = AES.new(key, AES.MODE_ECB)
encrypted_text = base64.b64decode(ciphertext)
decrypted_text = unpad(cipher.decrypt(encrypted_text), AES.block_size)
return decrypted_text.decode()
# Example usage
plaintext = input("Enter message for AES encryption: ")
key = input("Enter 16, 24, or 32-character key: ").encode()
if len(key) not in [16, 24, 32]:
raise ValueError("Key must be 16, 24, or 32 bytes long.")
encrypted_text = aes_encrypt(plaintext, key)
decrypted_text = aes_decrypt(encrypted_text, key)
print("AES Encrypted:", encrypted_text)
print("AES Decrypted:", decrypted_text)
/////////////////////////////////////////////////////////////////////
RSA
import random
def gcd(a, b):
"""Compute the greatest common divisor using the Euclidean algorithm."""
while b:
a, b = b, a % b
return a
def mod_inverse(e, phi):
"""Compute modular inverse using the extended Euclidean algorithm."""
phi0, x0, x1 = phi, 0, 1
while e > 1:
q = e // phi
e, phi = phi, e % phi
x0, x1 = x1 - q * x0, x0
return x1 + phi0 if x1 < 0 else x1
def is_prime(n):
"""Check if a number is prime (simple primality test)."""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def generate_prime(bits=8):
"""Generate a prime number of specified bit length."""
while True:
num = random.randint(2 ** (bits - 1), 2 ** bits - 1)
if is_prime(num):
return num
def generate_keys():
"""Generates an RSA key pair (public and private keys)."""
p = generate_prime(8) # Small prime for demonstration
q = generate_prime(8)
n = p * q
phi = (p - 1) * (q - 1)
e = 65537 # Common choice for e
while gcd(e, phi) != 1:
e = random.randint(2, phi - 1)
d = mod_inverse(e, phi)
public_key = (e, n)
private_key = (d, n)
return public_key, private_key
def rsa_encrypt(plaintext, public_key):
"""Encrypt a plaintext message using RSA."""
e, n = public_key
ciphertext = [pow(ord(char), e, n) for char in plaintext]
return ciphertext
def rsa_decrypt(ciphertext, private_key):
"""Decrypt a ciphertext message using RSA."""
d, n = private_key
plaintext = ''.join(chr(pow(char, d, n)) for char in ciphertext)
return plaintext
# Generate RSA keys
public_key, private_key = generate_keys()
# Example usage
plaintext = input("Enter message for RSA encryption: ")
encrypted_text = rsa_encrypt(plaintext, public_key)
decrypted_text = rsa_decrypt(encrypted_text, private_key)
print("\nRSA Public Key:", public_key)
print("RSA Private Key:", private_key)
print("RSA Encrypted:", encrypted_text)
print("RSA Decrypted:", decrypted_text)
///////////////////////////////////////////////////////////////
EL-GAMAL
import random
def gcd(a, b):
"""Compute the greatest common divisor."""
while b:
a, b = b, a % b
return a
def mod_inverse(a, p):
"""Compute modular inverse of a under modulo p using Extended Euclidean Algorithm."""
p0, x0, x1 = p, 0, 1
while a > 1:
q = a // p
a, p = p, a % p
x0, x1 = x1 - q * x0, x0
return x1 + p0 if x1 < 0 else x1
def is_prime(n):
"""Check if a number is prime (simple trial division)."""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def generate_prime(bits=16):
"""Generate a prime number of given bit length."""
while True:
num = random.randint(2 ** (bits - 1), 2 ** bits - 1)
if is_prime(num):
return num
def generate_keys(bits=16):
"""Generates an ElGamal key pair."""
p = generate_prime(bits) # Large prime number
g = random.randint(2, p - 1) # Generator
x = random.randint(2, p - 2) # Private key
y = pow(g, x, p) # Public key component
return (p, g, y), x # Public key and private key
def elgamal_encrypt(plaintext, public_key):
"""Encrypts plaintext using ElGamal public key."""
p, g, y = public_key
k = random.randint(2, p - 2) # Random integer k
a = pow(g, k, p)
b = (pow(y, k, p) * plaintext) % p
return a, b
def elgamal_decrypt(ciphertext, private_key, p):
"""Decrypts ciphertext using ElGamal private key."""
a, b = ciphertext
s = pow(a, private_key, p) # Compute shared secret
s_inv = mod_inverse(s, p) # Modular inverse of shared secret
return (b * s_inv) % p
# Generate keys
public_key, private_key = generate_keys()
p, g, y = public_key
# Example usage
plaintext = int(input("Enter integer message for ElGamal encryption: "))
ciphertext = elgamal_encrypt(plaintext, public_key)
decrypted_text = elgamal_decrypt(ciphertext, private_key, p)
print("\nElGamal Public Key:", public_key)
print("ElGamal Private Key:", private_key)
print("ElGamal Encrypted:", ciphertext)
print("ElGamal Decrypted:", decrypted_text)
////////////////////////////////////////////////////////////////////////////////
Diffie-Hellman and Man-in-Middle AttacK
import random
def is_prime(n):
"""Check if a number is prime (simple trial division)."""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def generate_prime(bits=16):
"""Generate a prime number of given bit length."""
while True:
num = random.randint(2 ** (bits - 1), 2 ** bits - 1)
if is_prime(num):
return num
def diffie_hellman_key_exchange():
"""Performs Diffie-Hellman Key Exchange."""
p = generate_prime(16) # Small prime for demo (use 256+ bits in real-world)
g = random.randint(2, p - 1) # Generator
# Alice's private and public key
a_private = random.randint(2, p - 2)
a_public = pow(g, a_private, p)
# Bob's private and public key
b_private = random.randint(2, p - 2)
b_public = pow(g, b_private, p)
# Shared secret computation
shared_secret_alice = pow(b_public, a_private, p)
shared_secret_bob = pow(a_public, b_private, p)
return (p, g, a_public, b_public, shared_secret_alice, shared_secret_bob)
def man_in_the_middle_attack():
"""Simulates a Man-in-the-Middle (MITM) attack on Diffie-Hellman."""
p, g, a_public, b_public, _, _ = diffie_hellman_key_exchange()
# Attacker intercepts Alice and Bob's public keys
attacker_private = random.randint(2, p - 2)
# Attacker generates fake keys
fake_a_public = pow(g, attacker_private, p)
fake_b_public = pow(g, attacker_private, p)
# Attacker computes shared secrets with both parties
shared_secret_alice = pow(fake_a_public, attacker_private, p)
shared_secret_bob = pow(fake_b_public, attacker_private, p)
return (p, g, a_public, b_public, fake_a_public, fake_b_public, shared_secret_alice, shared_secret_bob)
# Example usage
print("Diffie-Hellman Key Exchange")
p, g, a_pub, b_pub, secret_alice, secret_bob = diffie_hellman_key_exchange()
print("Prime (p):", p)
print("Generator (g):", g)
print("Alice's Public Key:", a_pub)
print("Bob's Public Key:", b_pub)
print("Shared Secret (Alice):", secret_alice)
print("Shared Secret (Bob):", secret_bob)
print("\nMan-in-the-Middle Attack")
p, g, a_pub, b_pub, fake_a_pub, fake_b_pub, mitm_secret_alice, mitm_secret_bob = man_in_the_middle_attack()
print("Attacker's Fake Alice Public Key:", fake_a_pub)
print("Attacker's Fake Bob Public Key:", fake_b_pub)
print("Attacker's Shared Secret with Alice:", mitm_secret_alice)
print("Attacker's Shared Secret with Bob:", mitm_secret_bob)
///////////////////////////////////////