Skip to content

Instantly share code, notes, and snippets.

@JohnnyJayJay
Last active September 23, 2019 20:22
Show Gist options
  • Save JohnnyJayJay/99c2242b63b4172581d5d696179c99de to your computer and use it in GitHub Desktop.
Save JohnnyJayJay/99c2242b63b4172581d5d696179c99de to your computer and use it in GitHub Desktop.
RSA key generation and en-/decryption implementation
import random
import string
def crypt(key, str):
x, n = key
return string.join([chr(c) for c in map(lambda element: (element ** x) % n, [ord(c) for c in str])])
def get_primes(r):
primes = []
for possible_prime in r:
is_prime = True
for possible_divider in range(2, int(possible_prime ** 0.5) + 1):
if possible_prime % possible_divider == 0:
is_prime = False
break
if is_prime:
primes.append(possible_prime)
return primes
def get_possible_e(phi):
possible = []
for i in range(1, phi):
if gcd(phi, i) == 1:
possible.append(i)
return possible
def gcd(a, b):
while b > 0:
rest = a % b
a = b
b = rest
return a
def extended_euclidian(a, b):
if b == 0:
return a, 1, 0
gcd, s, t = extended_euclidian(b, a % b)
s, t = t, s - int(a / b) * t
return gcd, s, t
def random_element(list):
return list[random.randrange(len(list))]
def generate_keys(bound):
primes = get_primes(range(2, bound))
p = random_element(primes)
primes.remove(p)
q = random_element(primes)
n = p * q
phi = (p - 1) * (q - 1)
e = random_element(get_possible_e(phi))
_, _, d = extended_euclidian(phi, e)
return ((e, n), (d, n))
bound = 101
public, private = generate_keys(bound)
print(f'Public key: {public}\nPrivate key: {private}')
message = random_element(string.ascii_letters)
print(f'Message: {message}')
encrypted = crypt(public, message)
print(f'Encrypted: {encrypted}')
decrypted = crypt(private, encryped)
print(f'Decrypted: {decrypted}')
print(f'message == decrypted? {message == decrypted}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment