Commit 82b582dc authored by hasan.bahjat's avatar hasan.bahjat 💬

Merge branch 'dev/Core' into 'master'

Dev/core

See merge request !1
parents a935f6d6 5d1cdb9a
Pipeline #201 failed with stages
# Byte-compiled / optimized / compiled Python files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Virtual environment
env/
venv/
# Packages
*.egg
*.egg-info/
dist/
build/
*.whl
# Distribution / packaging
.Python
*.tar.gz
*.zip
# Unit test / coverage reports
htmlcov/
*.cover
*.coverage
*.coverage.*
.cache
nosetests.xml
coverage.xml
*.lcov
# Logs and temporary files
*.log
*.tmp
*.swp
*.swo
# IDE settings and project files
.vscode/
.idea/
*.sublime-workspace
*.sublime-project
# MacOS files
.DS_Store
# Jupyter Notebook checkpoints
.ipynb_checkpoints/
# System files
Thumbs.db
desktop.ini
# Config files
.env
*.ini
*.cfg
# Makefile artifacts
*.d
*.o
*.out
# Compiler and Flags
PYTHON = python
# Targets
.PHONY: all run demo clean
# Run the main program
run:
$(PYTHON) main.py
# Run the demo script
demo:
$(PYTHON) demo.py
# Clean temporary files or logs
clean:
rm -f *.pyc __pycache__/*
rmdir __pycache__ 2>/dev/null || true
from key_generator import KeyGenerator
from pem_converter import PEMConverter
from rsa_encryptor import RSAEncryptor
def demo():
print("=== RSA DEMO ===")
# [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("Decrypted 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)
# [5] Verify decryption with restored keys
print("\nVerifying decryption with restored keys...")
decrypted_with_restored = rsa_encryptor.decrypt(encrypted_message, restored_private_key)
print("Decrypted Message with Restored Key:", decrypted_with_restored)
if __name__ == "__main__":
demo()
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