Commit 5cad10b9 authored by hasan  khaddour's avatar hasan khaddour

Add Core Progras, Encryptor, key generator, and formater

parent c13ba846
import random
from sympy import isprime, mod_inverse
class KeyGenerator:
def __init__(self, bits=512):
self.bits = bits # Number of bits for p and q
def generate_private_key(self):
"""
Generate a private key using two large prime numbers p and q.
The private key consists of (d, n), where:
- d is the private exponent
- n is the system modulus
Returns:
tuple: (d, n), represent the private key
"""
# [1] Generate two large distinct prime numbers
# p and q
p = self._generate_large_prime()
q = self._generate_large_prime()
while p == q: # Ensure p and q are distinct
q = self._generate_large_prime()
# ][2] Calculate n (the system modulus) and phi(n)
n = p * q
phi_n = (p - 1) * (q - 1)
# [3] Choose e (public exponent)
# such that 1 < e < ph(n) and gcd(e, phi(n)) = 1
e = 65537 # Common choice for e
while self._gcd(e, phi_n) != 1:
e += 2
# [4] Calculate d (the private exponent)
# such that d * e ≡ 1 (mod phi(n))
d = mod_inverse(e, phi_n)
# Return the private key as (d, n)
return d, n
def extract_public_key(self, private_key):
"""
Extract the public key from the private key.
Public key consists of (e, n), where:
- e is the public exponent
- n is the modulus (same as in the private key)
Args:
private_key (tuple): (d, n)
Returns:
tuple: (e, n)
"""
d, n = private_key
# [1] Recalculate [hi(n)
# from n and d
e = 65537
# [2]] Return the public key as (e, n)
return e, n
def _generate_large_prime(self):
"""Generate a large prime number with the specified number of bits."""
while True:
candidate = random.getrandbits(self.bits)
if isprime(candidate):
return candidate
def _gcd(self, a, b):
"""Compute the greatest common divisor (GCD) of two integers."""
while b:
a, b = b, a % b
return a
from key_generator import KeyGenerator
from pem_converter import PEMConverter
from rsa_encryptor import RSAEncryptor
def main():
print("\n\n\n\n")
# [1] Key generation
key_generator = KeyGenerator(bits=512)
## Generate a private key
private_key = key_generator.generate_private_key()
## Generate a public key
public_key = key_generator.extract_public_key(private_key)
print("Private Key:", private_key)
print("Public Key:", public_key)
# [2] Convert to PEM format
pem_converter = PEMConverter() # defin pem formater
private_pem = pem_converter.to_pem(private_key, "PRIVATE") # format the priavte key
public_pem = pem_converter.to_pem(public_key, "PUBLIC") # format the publiie key
print("\nPrivate Key (PEM):\n", private_pem)
print("\nPublic Key (PEM):\n", public_pem)
# [3] Encrypt and decrypt a message
## Creata an Encrpytor
rsa_encryptor= RSAEncryptor()
message = "\n\nHello, RSA!"
print("\nOriginal Message:", message)
encrypted_message = rsa_encryptor.encrypt(message, public_key)
print("Encrypted Message:", encrypted_message)
decrypted_message = rsa_encryptor.decrypt(encrypted_message, private_key)
print("\n\nDecrypted Message:", decrypted_message)
# [4] Convert PEM back to keys
restored_private_key = pem_converter.from_pem(private_pem)
restored_public_key = pem_converter.from_pem(public_pem)
print("\nRestored Private Key:", restored_private_key)
print("Restored Public Key:", restored_public_key)
if __name__ == "__main__":
main()
import base64
class PEMConverter:
@staticmethod
def to_pem(key, key_type):
"""
Convert a key to PEM format.
- key: Tuple containing key components.
- key_type: Either 'PUBLIC' or 'PRIVATE'.
"""
key_bytes = f"{key[0]},{key[1]}".encode()
key_base64 = base64.b64encode(key_bytes).decode()
pem_key = f"-----BEGIN {key_type} KEY-----\n{key_base64}\n-----END {key_type} KEY-----"
return pem_key
@staticmethod
def from_pem(pem_key):
"""
Convert PEM-formatted key back to tuple.
- pem_key: The PEM-formatted key string.
"""
key_base64 = "".join(pem_key.split("\n")[1:-1])
key_bytes = base64.b64decode(key_base64).decode()
n, val = map(int, key_bytes.split(","))
return n, val
from sympy import mod_inverse
class RSAEncryptor:
def encrypt(self,message, public_key):
"""
Encrypts a message using the public key (e, n).
"""
e, n = public_key
# Convert plaintext to an integer
message_int = int.from_bytes(message.encode(), 'big')
# Perform encryption
# ciphertext = ( (message as int) ^ e) mod n
ciphertext = pow(message_int, e, n)
return ciphertext
def decrypt(self,ciphertext, private_key):
"""
Decrypts a ciphertext using the private key (d, n).
"""
d, n = private_key
# Perform decryption
# plaintext_int = (ciphertext ^ d) mod n
plaintext_int = pow(ciphertext, d, n)
# Convert integer back to bytes
try:
plaintext_bytes = plaintext_int.to_bytes((plaintext_int.bit_length() + 7) // 8, 'big')
plaintext = plaintext_bytes.decode('utf-8', errors='replace') # Replace invalid bytes
return plaintext
except Exception as e:
raise ValueError(f"Decryption failed: {e}")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment