from Crypto.Util.number import getPrime, long_to_bytesfrom math import gcd # for greatest common divisorclassRSA:def__init__(self):# p, q (large prime numbers) self.p =getPrime(512) self.q =getPrime(512)# calculate n (n is used for both the public key (n, e) and the private key (n, d)) self.n = p * q# calculate t (totient, or called as 'phi') self.t = (p -1) * (q -1)# calculate e (e is one of the puclic key (n, e))for i inrange(2, self.t):ifgcd(i, self.t)==1: self.e = ibreak# calculate d (d is one of the private key(e, d)) self.d =pow(self.e, -1, self.t)defencrypt(self,plaintext:str):# ciphertext = plaintext ** e % n ct =pow(int(plaintext.encode().hex(), 16), self.e, self.n)returnlong_to_bytes(ct)defdecrypt(self,ciphertext:str):# plaintext = ciphertext ** d % n pt =pow(int(ciphertext.hex()), self.d, self.n)returnlong_to_bytes(pt)defsign(self,plaintext:str): h = SHA256.new() h.update(plaintext.encode())# signed_plaintext = hash(plaintext) ** d % n signed_pt =pow(bytes_to_long(h.digest()), self.d, self.n)return signed_ptmsg ="Hello"rsa =RSA()enc_msg = rsa.encrypt(msg)dec_msg = rsa.decrypt(enc_msg)
Basic Rules
n
p and q should be prime numbers.
n = p * q
Totient (Phi)
t = (p -1) * (q -1)
e (Exponentiation)
65536 is often used for the value of exponentiation (e).
e =65537
Decryption Key
d = e **-1% t
Encrypt/Decrypt
# Encryptciphertext = plaintext ** e % n# Decryptplaintext = ciphertext ** d % n
We can calculate prime numbers (p and q) by factoring n (n = p * q).
To do that, we can use online tools such as factordb, or create a Python script as below.