import random from sympy import isprime import time import matplotlib.pyplot as plt def generate_keys(bit_length=32): while True: q = random.getrandbits(bit_length) if isprime(q): break g = random.randint(2, q - 1) x = random.randint(1, q - 2) h = pow(g, x, q) public_key = (q, g, h) private_key = (q, x) return public_key, private_key def encrypt(public_key, message): q, g, h = public_key # Determine the maximum block size based on the size of q max_block_size = (q.bit_length() - 1) // 8 encrypted_blocks = [] for i in range(0, len(message), max_block_size): block = message[i:i+max_block_size] y = random.randint(1, q - 2) c1 = pow(g, y, q) m = int.from_bytes(block.encode(), 'big') s = pow(h, y, q) c2 = (m * s) % q encrypted_blocks.append((c1, c2)) return encrypted_blocks def decrypt(private_key, ciphertext): q, x = private_key decrypted_blocks = [] for c1, c2 in ciphertext: s = pow(c1, x, q) m = (c2 * pow(s, q - 2, q)) % q block = m.to_bytes((m.bit_length() + 7) // 8, 'big').decode(errors='ignore') decrypted_blocks.append(block) return ''.join(decrypted_blocks) # Example Usage public_key, private_key = generate_keys() print("Public Key:", public_key) print("Private Key:", private_key) encrypted_message = encrypt(public_key, "Hello, World!") print("Encrypted Message:", encrypted_message) decrypted_message = decrypt(private_key, encrypted_message) print("Decrypted Message:", decrypted_message) def main(): public_key, private_key = generate_keys() print("Public Key:", public_key) print("Private Key:", private_key) encrypted_message = encrypt(public_key, "Hello, World!") print("Encrypted Message:", encrypted_message) decrypted_message = decrypt(private_key, encrypted_message) print("Decrypted Message:", decrypted_message) return encrypted_message, decrypted_message # Measure execution times execution_times = [] for _ in range(10): start_time = time.time() main() end_time = time.time() execution_times.append(end_time - start_time) print(execution_times) # Plot the execution times plt.plot(execution_times, marker='o') plt.xlabel('Run Number') plt.ylabel('Execution Time (seconds)') plt.title('Execution Times for Encrypting and Decrypting') plt.show()