(Cyber Security)
(using pycrypt libraries)
HILL CIPHER
import numpy as np
from Crypto.Util.number
import inverse
import math
def text_to_numbers(text):
return [ord(char) - ord('A') for char in
text.upper() if char.isalpha()]
def numbers_to_text(numbers):
return ''.join(chr(num + ord('A')) for num
in numbers)
def
create_key_matrix_from_integers(int_list, size):
if len(int_list) != size * size:
raise ValueError(f"Need exactly
{size*size} integers for the key matrix.")
return np.array(int_list).reshape(size,
size) % 26
def
is_invertible_mod26(matrix):
det = int(round(np.linalg.det(matrix))) %
26
return math.gcd(det, 26) == 1, det
def hill_encrypt(plaintext,
key_matrix):
size = key_matrix.shape[0]
plaintext_numbers =
text_to_numbers(plaintext)
while len(plaintext_numbers) % size != 0:
plaintext_numbers.append(ord('X') -
ord('A')) # Padding with 'X'
ciphertext_numbers = []
for i in range(0, len(plaintext_numbers),
size):
block =
np.array(plaintext_numbers[i:i+size])
encrypted_block = key_matrix.dot(block)
% 26
ciphertext_numbers.extend(encrypted_block)
return numbers_to_text(ciphertext_numbers)
def hill_decrypt(ciphertext,
key_matrix):
size = key_matrix.shape[0]
det = int(round(np.linalg.det(key_matrix)))
% 26
det_inv = inverse(det, 26)
cofactors = np.zeros(key_matrix.shape)
for r in range(size):
for c in range(size):
minor =
np.delete(np.delete(key_matrix, r, axis=0), c, axis=1)
cofactor = ((-1) ** (r + c)) *
int(round(np.linalg.det(minor)))
cofactors[r][c] = cofactor % 26
adjugate = cofactors.T % 26
inv_key_matrix = (det_inv * adjugate) % 26
ciphertext_numbers =
text_to_numbers(ciphertext)
plaintext_numbers = []
for i in range(0, len(ciphertext_numbers),
size):
block =
np.array(ciphertext_numbers[i:i+size])
decrypted_block =
inv_key_matrix.dot(block) % 26
plaintext_numbers.extend(decrypted_block.astype(int))
return numbers_to_text(plaintext_numbers)
def main():
size = int(input("Enter size of square
key matrix (e.g., 2 for 2x2): "))
while True:
print(f"Enter {size*size} integers
for the {size}x{size} key matrix (row-wise):")
key_elements = []
while len(key_elements) < size*size:
line = input().strip()
if not line:
continue
parts = line.split()
for p in parts:
if p.isdigit():
key_elements.append(int(p)
% 26)
else:
print("Please enter
integers only.")
return
key_matrix =
create_key_matrix_from_integers(key_elements, size)
invertible, det =
is_invertible_mod26(key_matrix)
if invertible:
print(f"Key matrix accepted.
Determinant mod 26 = {det}")
break
else:
print(f"Key matrix NOT
invertible mod 26 (det={det}). Please enter a valid key matrix.")
choice = input("Do you want to Encrypt
or Decrypt? (E/D): ").strip().upper()
if choice == 'E':
plaintext = input("Enter the
plaintext (letters only): ").strip()
ciphertext = hill_encrypt(plaintext,
key_matrix)
print(f"Encrypted ciphertext:
{ciphertext}")
elif choice == 'D':
ciphertext = input("Enter the
ciphertext (letters only): ").strip()
decrypted_text =
hill_decrypt(ciphertext, key_matrix)
print(f"Decrypted plaintext:
{decrypted_text}")
else:
print("Invalid choice. Please
enter E or D.")
if __name__ ==
"__main__":
main()
CEASER
CIPHER
from Crypto.Random import get_random_bytes
class CaesarCipher:
def
__init__(self, shift=None):
if shift is
None:
#
Generate a secure random shift key between 1 and 25
self.shift = int.from_bytes(get_random_bytes(1), 'big') % 25 + 1
print(f"Generated secure shift key: {self.shift}")
else:
self.shift = shift % 26
def encrypt(self,
plaintext):
return
''.join(self._shift_char(c, self.shift) for c in plaintext)
def decrypt(self,
ciphertext):
return
''.join(self._shift_char(c, -self.shift) for c in ciphertext)
def
_shift_char(self, char, shift):
if
char.isupper():
return
chr((ord(char) - ord('A') + shift) % 26 + ord('A'))
elif
char.islower():
return
chr((ord(char) - ord('a') + shift) % 26 + ord('a'))
else:
return
char
if __name__ == "__main__":
choice =
input("Do you want to (E)ncrypt or (D)ecrypt? ").strip().upper()
text =
input("Enter the text: ")
shift_input =
input("Enter the shift key (integer) or leave blank for random key:
").strip()
if shift_input ==
'':
cipher =
CaesarCipher()
else:
try:
shift =
int(shift_input)
cipher =
CaesarCipher(shift)
except
ValueError:
print("Invalid shift key. Must be an integer.")
exit()
if choice == 'E':
result =
cipher.encrypt(text)
print("Encrypted Text:", result)
elif choice ==
'D':
result =
cipher.decrypt(text)
print("Decrypted Text:", result)
else:
print("Invalid choice. Please enter 'E' or 'D'.")
PLAYFAIR CIPHER
from Crypto.Util.Padding import pad, unpad
def generate_matrix(key):
key =
key.upper().replace('J', 'I')
matrix = []
used = set()
for char in key:
if char not
in used and char.isalpha():
used.add(char)
matrix.append(char)
for char in
"ABCDEFGHIKLMNOPQRSTUVWXYZ":
if char not
in used:
used.add(char)
matrix.append(char)
return
[matrix[i*5:(i+1)*5] for i in range(5)]
def find_position(matrix, char):
for i, row in
enumerate(matrix):
for j, c in
enumerate(row):
if c ==
char:
return i, j
return None
def process_text(text):
text =
text.upper().replace('J', 'I')
text = ''.join([c
for c in text if c.isalpha()])
processed = ''
i = 0
while i <
len(text):
char1 =
text[i]
if i + 1 <
len(text):
char2 =
text[i+1]
if char1
== char2:
processed += char1 + 'X'
i +=
1
else:
processed += char1 + char2
i +=
2
else:
processed
+= char1 + 'X'
i += 1
# Pad processed
text to even length using PKCS7 padding (block size 2)
# Convert to
bytes for padding
padded_bytes =
pad(processed.encode(), 2)
# Convert back to
string for Playfair processing
padded_text =
padded_bytes.decode('utf-8', errors='ignore')
# Note: PKCS7
padding may add non-alpha chars (e.g. \x01, \x02)
# Playfair works
only with letters, so we just trust process_text's own padding (X)
# Alternatively,
you can skip this pad step if you rely on 'X' padding only.
# Here, we'll
skip pad step actually:
# Just return
processed text, because PKCS7 adds non-alpha which breaks Playfair.
return processed
def encrypt_pair(matrix, a, b):
r1, c1 =
find_position(matrix, a)
r2, c2 =
find_position(matrix, b)
if r1 == r2:
return
matrix[r1][(c1 + 1) % 5] + matrix[r2][(c2 + 1) % 5]
elif c1 == c2:
return
matrix[(r1 + 1) % 5][c1] + matrix[(r2 + 1) % 5][c2]
else:
return
matrix[r1][c2] + matrix[r2][c1]
def decrypt_pair(matrix, a, b):
r1, c1 =
find_position(matrix, a)
r2, c2 =
find_position(matrix, b)
if r1 == r2:
return
matrix[r1][(c1 - 1) % 5] + matrix[r2][(c2 - 1) % 5]
elif c1 == c2:
return
matrix[(r1 - 1) % 5][c1] + matrix[(r2 - 1) % 5][c2]
else:
return
matrix[r1][c2] + matrix[r2][c1]
def playfair_encrypt(message, key):
matrix =
generate_matrix(key)
message =
process_text(message)
cipher = ''
for i in range(0,
len(message), 2):
cipher +=
encrypt_pair(matrix, message[i], message[i+1])
return cipher
def playfair_decrypt(cipher, key):
matrix =
generate_matrix(key)
plain = ''
for i in range(0,
len(cipher), 2):
plain +=
decrypt_pair(matrix, cipher[i], cipher[i+1])
return plain
# ---- User Input ----
key = input("Enter the key: ")
message = input("Enter the message: ")
# Encryption
cipher_text = playfair_encrypt(message, key)
print("\nEncrypted message:", cipher_text)
# Decryption
decrypted_message = playfair_decrypt(cipher_text, key)
print("Decrypted message:", decrypted_message)
AES
from Crypto.Cipher import AES
from Crypto.Util.Padding
import pad, unpad
def get_key():
while True:
key = input("Enter secret key (16,
24 or 32 characters): ").encode()
if len(key) in [16, 24, 32]:
return key
else:
print("Invalid key length. Try
again.")
def encrypt(plaintext, key):
iv = b'0123456789abcdef' # 16 bytes fixed IV for simplicity (unsafe in
real use)
cipher = AES.new(key, AES.MODE_CBC, iv)
ct_bytes =
cipher.encrypt(pad(plaintext.encode(), AES.block_size))
return ct_bytes
def decrypt(ciphertext, key):
iv = b'0123456789abcdef'
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = unpad(cipher.decrypt(ciphertext),
AES.block_size)
return pt.decode('utf-8')
def main():
print("AES
Encryption/Decryption")
key = get_key()
choice = input("Choose (E)ncrypt or
(D)ecrypt: ").strip().upper()
if choice == 'E':
plaintext = input("Enter plaintext
to encrypt: ")
ciphertext = encrypt(plaintext, key)
print("Ciphertext (hex):",
ciphertext.hex())
elif choice == 'D':
hex_ct = input("Enter ciphertext
(hex): ")
ciphertext = bytes.fromhex(hex_ct)
try:
plaintext = decrypt(ciphertext,
key)
print("Decrypted
plaintext:", plaintext)
except Exception as e:
print("Decryption
failed:", e)
else:
print("Invalid option
selected.")
if __name__ ==
"__main__":
main()
DES
from Crypto.Cipher import DES
from Crypto.Util.Padding
import pad, unpad
def get_key():
while True:
key = input("Enter secret key (8
characters): ").encode()
if len(key) == 8:
return key
else:
print("Invalid key length. DES
requires 8 bytes. Try again.")
def encrypt(plaintext, key):
iv = b'12345678' # 8 bytes fixed IV for simplicity (unsafe in
real use)
cipher = DES.new(key, DES.MODE_CBC, iv)
ct_bytes =
cipher.encrypt(pad(plaintext.encode(), DES.block_size))
return ct_bytes
def decrypt(ciphertext, key):
iv = b'12345678'
cipher = DES.new(key, DES.MODE_CBC, iv)
pt = unpad(cipher.decrypt(ciphertext),
DES.block_size)
return pt.decode('utf-8')
def main():
print("DES
Encryption/Decryption")
key = get_key()
choice = input("Choose (E)ncrypt or
(D)ecrypt: ").strip().upper()
if choice == 'E':
plaintext = input("Enter plaintext
to encrypt: ")
ciphertext = encrypt(plaintext, key)
print("Ciphertext (hex):",
ciphertext.hex())
elif choice == 'D':
hex_ct = input("Enter ciphertext
(hex): ")
ciphertext = bytes.fromhex(hex_ct)
try:
plaintext = decrypt(ciphertext,
key)
print("Decrypted
plaintext:", plaintext)
except Exception as e:
print("Decryption
failed:", e)
else:
print("Invalid option
selected.")
if __name__ ==
"__main__":
main()
DFIEEHELLMAN
from Crypto.Util.number import getPrime
import hashlib
# Get user input for bit length
bit_length = int(input("Enter bit length for prime
number (e.g., 512, 1024, 2048): "))
p = getPrime(bit_length)
g = 2 # Using 2 as a
common generator
print("\nShared Prime (p):", p)
print("Generator (g):", g)
# User input for Alice's and Bob's private keys
a_private = int(input("\nEnter Alice's private key (a
number < p): "))
b_private = int(input("Enter Bob's private key (a
number < p): "))
# Generate public keys
a_public = pow(g, a_private, p)
b_public = pow(g, b_private, p)
print("\nAlice's Public Key:", a_public)
print("Bob's Public Key:", b_public)
# Calculate shared secrets
alice_shared_secret = pow(b_public, a_private, p)
bob_shared_secret = pow(a_public, b_private, p)
# Ensure both computed the same secret
if alice_shared_secret == bob_shared_secret:
print("\n✅ Key exchange
successful!")
else:
print("\n❌ Key exchange
failed.")
# Derive symmetric key using SHA-256
shared_secret = alice_shared_secret
symmetric_key =
hashlib.sha256(str(shared_secret).encode()).digest()
print("\nShared Secret (integer):",
shared_secret)
print("Derived Symmetric Key (SHA-256):",
symmetric_key.hex())
---------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------
(Without
libraries)
Caesar Cipher:
class CaesarCipher:
def __init__(self, shift):
self.shift = shift % 26
def encrypt(self, plaintext):
return ''.join(self._shift_char(c,
self.shift) for c in plaintext)
def decrypt(self, ciphertext):
return ''.join(self._shift_char(c,
-self.shift) for c in ciphertext)
def _shift_char(self, char, shift):
if char.isupper():
return chr((ord(char) - ord('A') +
shift) % 26 + ord('A'))
elif char.islower():
return chr((ord(char) - ord('a') +
shift) % 26 + ord('a'))
else:
return char
if __name__ ==
"__main__":
choice = input("Do you want to
(E)ncrypt or (D)ecrypt? ").strip().upper()
text = input("Enter the text: ")
try:
shift = int(input("Enter the shift
key (integer): "))
except ValueError:
print("Invalid shift key. Must be
an integer.")
exit()
cipher = CaesarCipher(shift)
if choice == 'E':
result = cipher.encrypt(text)
print("Encrypted Text:",
result)
elif choice == 'D':
result = cipher.decrypt(text)
print("Decrypted Text:",
result)
else:
print("Invalid choice. Please
enter 'E' or 'D'.")
HILL CIPHER
import
numpy as np
from
math import gcd
#
Convert text to numerical values (A=0, B=1, ..., Z=25)
def
text_to_numbers(text):
return [ord(c.upper()) - ord('A') for c in
text if c.isalpha()]
#
Convert numerical values back to uppercase letters
def
numbers_to_text(numbers):
return ''.join([chr(num % 26 + ord('A'))
for num in numbers])
# Pad
the text to make it a multiple of block size
def
pad_text(text, block_size):
while len(text) % block_size != 0:
text += 'X'
return text
#
Extended Euclidean Algorithm for modular inverse
def
modinv(a, m):
a = a % m
for x in range(1, m):
if (a * x) % m == 1:
return x
raise ValueError(f"No modular inverse
for {a} under modulus {m}")
#
Compute modular inverse of matrix
def
matrix_mod_inv(matrix, modulus):
n = matrix.shape[0]
det = int(round(np.linalg.det(matrix))) %
modulus
if gcd(det, modulus) != 1:
raise ValueError("Matrix is not
invertible under mod 26.")
det_inv = modinv(det, modulus)
# Compute matrix of cofactors
cofactors = np.zeros((n, n))
for r in range(n):
for c in range(n):
minor = np.delete(np.delete(matrix,
r, axis=0), c, axis=1)
cofactors[r, c] = ((-1) ** (r + c))
* int(round(np.linalg.det(minor)))
# Adjugate = transpose of cofactor matrix
adjugate = cofactors.T
inv_matrix = (det_inv * adjugate) % modulus
return inv_matrix.astype(int)
# Hill
Cipher Encryption
def
hill_encrypt(plaintext, key_matrix):
n = key_matrix.shape[0]
plaintext = pad_text(plaintext, n)
plaintext_nums = text_to_numbers(plaintext)
ciphertext_nums = []
for i in range(0, len(plaintext_nums), n):
block = np.array(plaintext_nums[i:i +
n])
encrypted_block = key_matrix.dot(block)
% 26
ciphertext_nums.extend(encrypted_block)
return numbers_to_text(ciphertext_nums)
# Hill
Cipher Decryption
def
hill_decrypt(ciphertext, key_matrix):
n = key_matrix.shape[0]
ciphertext_nums =
text_to_numbers(ciphertext)
inv_key_matrix = matrix_mod_inv(key_matrix,
26)
plaintext_nums = []
for i in range(0, len(ciphertext_nums), n):
block = np.array(ciphertext_nums[i:i +
n])
decrypted_block =
inv_key_matrix.dot(block) % 26
plaintext_nums.extend(decrypted_block)
return numbers_to_text(plaintext_nums)
# ===
Main Program ===
n =
int(input("Enter size of square key matrix (e.g., 2 for 2x2): "))
print(f"Enter
{n * n} integers for the {n}x{n} key matrix (row-wise):")
key_values
= list(map(int, input().split()))
if
len(key_values) != n * n:
raise ValueError("Invalid number of
elements for the matrix.")
key_matrix
= np.array(key_values).reshape(n, n)
choice
= input("Do you want to Encrypt or Decrypt? (E/D): ").strip().upper()
if
choice == 'E':
plaintext = input("Enter the plaintext
(only letters): ").strip()
ciphertext = hill_encrypt(plaintext,
key_matrix)
print("Encrypted ciphertext:",
ciphertext)
elif
choice == 'D':
ciphertext = input("Enter the
ciphertext (only letters): ").strip()
try:
plaintext = hill_decrypt(ciphertext,
key_matrix)
print("Decrypted plaintext:",
plaintext)
except ValueError as e:
print("Decryption failed:",
e)
else:
print("Invalid choice. Please enter
'E' to encrypt or 'D' to decrypt.")
PLAYFAIR CIPHER:
def generate_matrix(key):
key =
key.upper().replace('J', 'I')
matrix = []
used = set()
for char in key:
if char not
in used and char.isalpha():
used.add(char)
matrix.append(char)
for char in
"ABCDEFGHIKLMNOPQRSTUVWXYZ":
if char not
in used:
used.add(char)
matrix.append(char)
return
[matrix[i*5:(i+1)*5] for i in range(5)]
def find_position(matrix, char):
for i, row in
enumerate(matrix):
for j, c in
enumerate(row):
if c ==
char:
return i, j
return None
def process_text(text, for_encryption=True):
text =
text.upper().replace('J', 'I')
processed = ''
i = 0
while i <
len(text):
char1 =
text[i]
if not
char1.isalpha():
i += 1
continue
if i + 1 <
len(text):
char2 =
text[i+1]
if not
char2.isalpha():
processed += char1 + 'X'
i +=
1
continue
if char1
== char2:
processed += char1 + 'X'
i +=
1
else:
processed += char1 + char2
i +=
2
else:
processed
+= char1 + 'X'
i += 1
return processed
def encrypt_pair(matrix, a, b):
r1, c1 =
find_position(matrix, a)
r2, c2 =
find_position(matrix, b)
if r1 == r2:
return
matrix[r1][(c1 + 1) % 5] + matrix[r2][(c2 + 1) % 5]
elif c1 == c2:
return
matrix[(r1 + 1) % 5][c1] + matrix[(r2 + 1) % 5][c2]
else:
return
matrix[r1][c2] + matrix[r2][c1]
def decrypt_pair(matrix, a, b):
r1, c1 =
find_position(matrix, a)
r2, c2 =
find_position(matrix, b)
if r1 == r2:
return
matrix[r1][(c1 - 1) % 5] + matrix[r2][(c2 - 1) % 5]
elif c1 == c2:
return
matrix[(r1 - 1) % 5][c1] + matrix[(r2 - 1) % 5][c2]
else:
return
matrix[r1][c2] + matrix[r2][c1]
def playfair_encrypt(message, key):
matrix =
generate_matrix(key)
message =
process_text(message)
cipher = ''
for i in range(0,
len(message), 2):
cipher +=
encrypt_pair(matrix, message[i], message[i+1])
return cipher
def playfair_decrypt(cipher, key):
matrix =
generate_matrix(key)
plain = ''
for i in range(0,
len(cipher), 2):
plain +=
decrypt_pair(matrix, cipher[i], cipher[i+1])
return plain
# ---- User Input ----
key = input("Enter the key: ")
message = input("Enter the message: ")
# Encryption
cipher_text = playfair_encrypt(message, key)
print("\nEncrypted message:", cipher_text)
# Decryption
decrypted_message = playfair_decrypt(cipher_text, key)
print("Decrypted message:", decrypted_message)
RAIL FENCE :
def encryptRailFence(text, key):
text =
text.replace(" ", "")
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)
plain_text = input("Enter the message to encrypt:
")
key = int(input("Enter the key (number of rails):
"))
cipher_text = encryptRailFence(plain_text, key)
print("\nEncrypted message:", cipher_text)
COLUMUNAR TRANSPOSITION:
def
encrypt_columnar_transposition(plaintext, key):
plaintext = plaintext.replace("
", "").lower()
num_cols = len(key)
num_rows = (len(plaintext) + num_cols - 1)
// num_cols
padded_length = num_rows * num_cols
plaintext += 'x' * (padded_length -
len(plaintext))
matrix =
[list(plaintext[i*num_cols:(i+1)*num_cols]) for i in range(num_rows)]
label_to_col_index = {label: idx for idx,
label in enumerate(key)}
ciphertext = ''
for label in range(1, num_cols + 1):
col = label_to_col_index[label]
for row in range(num_rows):
ciphertext += matrix[row][col]
return ciphertext.upper()
def main():
plaintext = input("Enter the
plaintext: ")
key_input = input("Enter the key as
space-separated numbers (e.g., 4 3 1 2 5 6 7): ")
key = list(map(int,
key_input.strip().split()))
if sorted(key) != list(range(1, len(key) +
1)):
print("Invalid key. It must be a
permutation of 1 to", len(key))
return
ciphertext =
encrypt_columnar_transposition(plaintext, key)
print("Ciphertext:", ciphertext)
if __name__ ==
"__main__":
main()
Comments
Post a Comment