(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

Popular posts from this blog

vaa arunachalam...nee inga varuva nu therium