1) PLAY FAIR CIPHER:
def prepare_text(text):
text = text.upper().replace("J", "I").replace(" ", "")
prepared = ""
i = 0
while i < len(text):
a = text[i]
b = text[i + 1] if i + 1 < len(text) else "X"
if a == b:
prepared += a + "X"
i += 1
else:
prepared += a + b
i += 2
if len(prepared) % 2 != 0:
prepared += "X"
return prepared
def generate_matrix(key):
key = key.upper().replace("J", "I")
seen = set()
matrix = []
for char in key + "ABCDEFGHIKLMNOPQRSTUVWXYZ":
if char not in seen:
seen.add(char)
matrix.append(char)
return [matrix[i:i+5] for i in range(0, 25, 5)]
def find_position(matrix, char):
for i in range(5):
for j in range(5):
if matrix[i][j] == char:
return i, j
return None
def encrypt_pair(a, b, matrix):
row1, col1 = find_position(matrix, a)
row2, col2 = find_position(matrix, b)
if row1 == row2:
return matrix[row1][(col1 + 1) % 5] + matrix[row2][(col2 + 1) % 5]
elif col1 == col2:
return matrix[(row1 + 1) % 5][col1] + matrix[(row2 + 1) % 5][col2]
else:
return matrix[row1][col2] + matrix[row2][col1]
def decrypt_pair(a, b, matrix):
row1, col1 = find_position(matrix, a)
row2, col2 = find_position(matrix, b)
if row1 == row2:
return matrix[row1][(col1 - 1) % 5] + matrix[row2][(col2 - 1) % 5]
elif col1 == col2:
return matrix[(row1 - 1) % 5][col1] + matrix[(row2 - 1) % 5][col2]
else:
return matrix[row1][col2] + matrix[row2][col1]
def encrypt(text, key):
prepared = prepare_text(text)
matrix = generate_matrix(key)
cipher = ""
for i in range(0, len(prepared), 2):
cipher += encrypt_pair(prepared[i], prepared[i+1], matrix)
return cipher
def decrypt(cipher, key):
matrix = generate_matrix(key)
decrypted = ""
for i in range(0, len(cipher), 2):
decrypted += decrypt_pair(cipher[i], cipher[i+1], matrix)
return decrypted
# Example usage
key = "monarchy"
text = "instruments"
cipher = encrypt(text, key)
print("Encrypted:", cipher)
print("Decrypted:", decrypt(cipher, key))
OUTPUT:
Encrypted: GATLMZCLRQXA
Decrypted: INSTRUMENTSX
2) CAESAR CIPHER:
def caesar_cipher(text, shift, mode='encrypt'):
result = ""
if mode == 'decrypt':
shift = -shift
for char in text:
if char.isalpha():
base = ord('A') if char.isupper() else ord('a')
result += chr((ord(char) - base + shift) % 26 + base)
else:
result += char
return result
# Example usage
text = "Hello World"
shift = 3
encrypted = caesar_cipher(text, shift)
decrypted = caesar_cipher(encrypted, shift, mode='decrypt')
print("Encrypted:", encrypted)
print("Decrypted:", decrypted)
OUTPUT:
Encrypted: Khoor Zruog
Decrypted: Hello World
3)MONO ALPHABETIC CIPHER:
import string
def monoalphabetic_encrypt(text, key):
alphabet = string.ascii_lowercase
key_map = dict(zip(alphabet, key.lower()))
result = ''
for char in text.lower():
result += key_map[char] if char in key_map else char
return result
def monoalphabetic_decrypt(cipher, key):
alphabet = string.ascii_lowercase
key_map = dict(zip(key.lower(), alphabet))
result = ''
for char in cipher.lower():
result += key_map[char] if char in key_map else char
return result
# Example usage
key = "QWERTYUIOPASDFGHJKLZXCVBNM" # A shuffled alphabet (key must have 26 unique
letters)
text = "hello world"
cipher = monoalphabetic_encrypt(text, key)
plain = monoalphabetic_decrypt(cipher, key)
print("Encrypted:", cipher)
print("Decrypted:", plain)
OUTPUT:
Encrypted: itssg vgksr
Decrypted: hello world
4) HILL CIPHER:
def mod_inverse(a, m):
for i in range(1, m):
if (a * i) % m == 1:
return i
return None # No inverse exists
def matrix_mod_inv(key, mod):
a, b = key[0]
c, d = key[1]
det = (a * d - b * c) % mod
inv_det = mod_inverse(det, mod)
if inv_det is None:
raise ValueError("Key matrix is not invertible.")
# Adjugate matrix
return [
[(d * inv_det) % mod, (-b * inv_det) % mod],
[(-c * inv_det) % mod, (a * inv_det) % mod]
]
def hill_encrypt(text, key):
text = text.upper().replace(" ", "")
if len(text) % 2 != 0:
text += 'X'
result = ''
for i in range(0, len(text), 2):
a = ord(text[i]) - 65
b = ord(text[i+1]) - 65
x = (key[0][0]*a + key[0][1]*b) % 26
y = (key[1][0]*a + key[1][1]*b) % 26
result += chr(x + 65) + chr(y + 65)
return result
def hill_decrypt(cipher, key):
inv_key = matrix_mod_inv(key, 26)
return hill_encrypt(cipher, inv_key)
# Example usage
key = [[3, 3], [2, 5]] # Must be invertible mod 26
plain = "HELP"
cipher = hill_encrypt(plain, key)
print("Encrypted:", cipher)
print("Decrypted:", hill_decrypt(cipher, key))
OUTPUT:
Encrypted: HIAT
Decrypted: HELP
5) DES ALGORITHM:
def xor(a, b):
return ''.join(['0' if i == j else '1' for i, j in zip(a, b)])
def encrypt_block(plain_bin, key_bin):
left = plain_bin[:len(plain_bin)//2]
right = plain_bin[len(plain_bin)//2:]
for _ in range(4): # 4 rounds (just for demo)
temp = right
right = xor(left, right) # fake function
left = temp
return left + right
def decrypt_block(cipher_bin, key_bin):
left = cipher_bin[:len(cipher_bin)//2]
right = cipher_bin[len(cipher_bin)//2:]
for _ in range(4):
temp = left
left = xor(right, left)
right = temp
return left + right
def text_to_bin(text):
return ''.join(format(ord(c), '08b') for c in text)
def bin_to_text(b):
return ''.join(chr(int(b[i:i+8], 2)) for i in range(0, len(b), 8))
# Example
plaintext = "HiDEMO12" # 8 chars = 64 bits
key = "MyDESKey" # dummy key, not used here
pt_bin = text_to_bin(plaintext)
ct_bin = encrypt_block(pt_bin, key)
dec_bin = decrypt_block(ct_bin, key)
print("Encrypted (bin):", ct_bin)
print("Encrypted (hex):", hex(int(ct_bin, 2))[2:])
print("Decrypted text:", bin_to_text(dec_bin))
OUTPUT:
Encrypted (bin): 0100110101001111001100010011001000000101001001100111010101110111
Encrypted (hex): 4d4f313205267577
Decrypted text: HiDEMO12
6) NIST:
import hashlib
message = "Hello from NIST!"
hash_object = hashlib.sha256(message.encode())
hex_dig = hash_object.hexdigest()
print("SHA-256 Hash:", hex_dig)
OUTPUT:
SHA-256 Hash: 7af852f351ce5a5a7d6d325d02f76fae2f98f94ad379da3d617604d4ef080b06
7) AES algorithm
def xor_block(a, b): return bytes([x ^ y for x, y in zip(a, b)])
def shift_left(block): return block[1:] + block[:1]
def substitute(block): return bytes([b ^ 0x1F for b in block])
key = b'1234567890abcdef'
plaintext = b'hello world!!'
block = plaintext[:16]
ciphertext = xor_block(block, key)
ciphertext = shift_left(ciphertext)
ciphertext = substitute(ciphertext)
print(f'Ciphertext: {ciphertext}')
decrypted = substitute(ciphertext)
decrypted = shift_left(decrypted)
decrypted = xor_block(decrypted, key)
print(f'Decrypted: {decrypted.decode()}')
OUTPUT:
Ciphertext: b'H@GE\t_HTC\x1a\\]F'
Decrypted: nji"ua|d<s#;4
8) Diffie-Hellman Key Exchange Algorithm
P = 23
G = 5
print(f"Publicly Shared:\nP (prime) = {P}, G (primitive root) = {G}")
a = 6
b = 15
A = (G ** a) % P
print(f"\nAlice sends to Bob: A = {A}")
B = (G ** b) % P
print(f"Bob sends to Alice: B = {B}")
secret_key_alice = (B ** a) % P
secret_key_bob = (A ** b) % P
print(f"\nAlice's computed secret key: {secret_key_alice}")
print(f"Bob's computed secret key: {secret_key_bob}")
if secret_key_alice == secret_key_bob:
print("\n Key exchange successful! Shared secret key is established.")
else:
print("\n Key exchange failed.")
OUTPUT:
Publicly Shared:
P (prime) = 23, G (primitive root) = 5
Alice sends to Bob: A = 8
Bob sends to Alice: B = 19
Alice's computed secret key: 2
Bob's computed secret key: 2
Key exchange successful! Shared secret key is established.
9) RSA algorithm
import math
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
def mod_inverse(e, phi):
for d in range(1, phi):
if (e * d) % phi == 1:
return d
return None
p = 3
q = 11
print(f"Selected primes:\np = {p}, q = {q}")
n = p * q
phi = (p - 1) * (q - 1)
print(f"\nn = p * q = {n}")
print(f"phi(n) = (p-1)*(q-1) = {phi}")
e = 7
if gcd(e, phi) != 1:
raise ValueError("e and phi(n) must be coprime.")
print(f"\nChosen public exponent:\ne = {e}")
d = mod_inverse(e, phi)
if d is None:
raise ValueError("Modular inverse of e does not exist.")
print(f"Calculated private exponent:\nd = {d}")
message = 9
cipher = (message ** e) % n
print(f"\nOriginal message = {message}")
print(f"Encrypted message (ciphertext) = {cipher}")
decrypted = (cipher ** d) % n
print(f"Decrypted message = {decrypted}")
OUTPUT
Selected primes:
p = 3, q = 11
n = p * q = 33
phi(n) = (p-1)*(q-1) = 20
Chosen public exponent:
e = 7
Calculated private exponent:
d = 3
Original message = 9
Encrypted message (ciphertext) = 15
Decrypted message = 9
10) Secure Hashing Algorithm
def lrot(n, b): return ((n << b) | (n >> (32 - b))) & 0xffffffff
def sha1(msg):
ml = len(msg) * 8
msg += b'\x80' + b'\x00' * ((56 - (len(msg) + 1) % 64) % 64) + ml.to_bytes(8,
'big')
h0, h1, h2, h3, h4 = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
for i in range(0, len(msg), 64):
w = [int.from_bytes(msg[i+j:i+j+4], 'big') for j in range(0, 64, 4)] +
[0]*64
for j in range(16, 80): w[j] = lrot(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1)
a, b, c, d, e = h0, h1, h2, h3, h4
for j in range(80):
if j < 20: f, k = (b & c) | (~b & d), 0x5A827999
elif j < 40: f, k = b ^ c ^ d, 0x6ED9EBA1
elif j < 60: f, k = (b & c) | (b & d) | (c & d), 0x8F1BBCDC
else: f, k = b ^ c ^ d, 0xCA62C1D6
a, b, c, d, e = (lrot(a,5) + f + e + k + w[j]) & 0xffffffff, a,
lrot(b,30), c, d
h0, h1, h2, h3, h4 = (h0+a)&0xffffffff, (h1+b)&0xffffffff,
(h2+c)&0xffffffff, (h3+d)&0xffffffff, (h4+e)&0xffffffff
return '%08x%08x%08x%08x%08x' % (h0,h1,h2,h3,h4)
msg = "Hello, world!"
digest = sha1(msg.encode())
print(f"Original message: {msg}")
print(f"SHA-1 Hash: {digest}")
OUTPUT
Original message: Hello, world!
SHA-1 Hash: 943a702d06f34599aee1f8da8ef9f7296031d699
11) Elective Curve Digital Signature Algorithm
P = 17
A = 2
B = 2
G = (5, 1)
n = 19
d = 7
def inverse_mod(k, p):
if k == 0: return None
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = p, k
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_s % p
def point_add(P1, P2):
if P1 is None: return P2
if P2 is None: return P1
x1, y1 = P1
x2, y2 = P2
if x1 == x2 and y1 != y2: return None
if P1 == P2:
m = (3 * x1 * x1 + A) * inverse_mod(2 * y1, P) % P
else:
m = (y2 - y1) * inverse_mod(x2 - x1, P) % P
x3 = (m * m - x1 - x2) % P
y3 = (m * (x1 - x3) - y1) % P
return (x3, y3)
def scalar_mult(k, point):
result = None
append = point
while k:
if k & 1: result = point_add(result, append)
append = point_add(append, append)
k >>= 1
return result
Q = scalar_mult(d, G)
def sign(m, k):
R = scalar_mult(k, G)
r = R[0] % n
s = (inverse_mod(k, n) * (m + r * d)) % n
return (r, s)
def verify(m, sig, Q):
r, s = sig
w = inverse_mod(s, n)
u1 = (m * w) % n
u2 = (r * w) % n
X = point_add(scalar_mult(u1, G), scalar_mult(u2, Q))
return X is not None and X[0] % n == r
m = 5
k = 3
signature = sign(m, k)
valid = verify(m, signature, Q)
print(f"Message: {m}")
print(f"Private Key (d): {d}")
print(f"Public Key (Q): {Q}")
print(f"Signature: {signature}")
print(f"Signature valid: {valid}")
OUTPUT
Message: 5
Private Key (d): 7
Public Key (Q): (0, 6)
Signature: (10, 6)
Signature valid: True
12) Elgamal Digital Signature Algorithm
def modinv(a, m):
m0, x0, x1 = m, 0, 1
while a > 1:
q = a // m
a, m = m, a % m
x0, x1 = x1 - q * x0, x0
return x1 % m0
def power(a, b, m):
result = 1
a = a % m
while b > 0:
if b % 2 == 1:
result = (result * a) % m
a = (a * a) % m
b = b // 2
return result
p = 467
g = 2
x = 127
y = power(g, x, p)
k = 61
m = 123
r = power(g, k, p)
k_inv = modinv(k, p - 1)
s = (k_inv * (m - x * r)) % (p - 1)
def verify(p, g, y, m, r, s):
if not (0 < r < p):
return False
v1 = (power(y, r, p) * power(r, s, p)) % p
v2 = power(g, m, p)
return v1 == v2
print("Public Key (p, g, y):", p, g, y)
print("Private Key (x):", x)
print("Message (m):", m)
print("Signature (r, s):", r, s)
print("Verification:", verify(p, g, y, m, r, s))
OUTPUT:
Public Key (p, g, y): 467 2 132
Private Key (x): 127
Message (m): 123
Signature (r, s): 338 131
Verification: True