You need to sign in or sign up before continuing.
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