This post is about the slowest and worst-ish implementation of RSA, RSA is an important public key encryption algorithm. From wiki:
RSA (Rivest–Shamir–Adleman) is a public-key cryptosystem that is widely used for secure data transmission. It is also one of the oldest. The acronym “RSA” comes from the surnames of Ron Rivest, Adi Shamir and Leonard Adleman, who publicly described the algorithm in 1977
The math behind RSA requires more mental calories than i can afford on Saturday morning. Anyway, The algorithm is simple (simple-ish). These are steps to calculate integer public and private keys
For public key, I am using naive shot in the dark to generate random e
and check if gcd(e,phi) == 1
.
17 self.e = random.randrange(1, self.phi)
18 res = math.gcd(self.e, self.phi)
19 while res != 1:
20 self.e = random.randrange(1, self.phi)
21 res = math.gcd(self.e , self.phi)
For private key, We need to calculate d where e.d = 1 mod n
. apparently d can be calculated with Extended Euclidean algorithm but i am too lazy to write it. So, After little googling I found that it’s the same as “Modular multiplicative inverse”
"y = invmod(x, p) such that x*y == 1 ( mod p)"
And that can be done with pow()
8 return pow(e, -1, phi)
4 import math
5 import random
6
7 def calc_private(e, phi):
8 return pow(e, -1, phi)
9
10 class RSA():
11 def __init__(self, a ,b):
12 self.a, self.b = (a,b)
13 self.n = self.a * self.b
14 self.phi = (self.a - 1) * (self.b - 1)
15
16 # public key
17 self.e = random.randrange(1, self.phi)
18 res = math.gcd(self.e, self.phi)
19 while res != 1:
20 self.e = random.randrange(1, self.phi)
21 res = math.gcd(self.e, self.phi)
22
23 # private key
24 self.d = calc_private(self.e, self.phi)
25
26 print(f"n:{self.n} phi:{self.phi} public key:{self.e} private key:{self.d}")
27
28 def encrypt(self, text):
29 cipher = (text ** self.e) % self.n
30 return cipher
31
32 def decrypt(self, text):
33 cipher = (text ** self.d) % self.n
34 return cipher
35
36
37 rsa = RSA(11,17)
38
39 i = 5
40 y = rsa.encrypt(i)
41 z = rsa.decrypt(y)
42 print(f"text:{i} encrypted:{y} decrepted:{z}")
43