from __future__ import unicode_literals from math import sqrt import random from random import randint as rand def gcd(a, b): if b == 0: return a else: return gcd(b, a % b) def mod_inverse(a, m): for x in range(1, m): if (a * x) % m == 1: return x return -1 def isprime(n): if n < 2: return False elif n == 2: return True else: for i in range(1, int(sqrt(n)) + 1): if n % i == 0: return False return True def generate_keypair(keysize): p = rand(1, 1000) q = rand(1, 1000) nMin = 1 << (keysize - 1) nMax = (1 << keysize) - 1 primes = [2] start = 1 << (keysize // 2 - 1) stop = 1 << (keysize // 2 + 1) if start >= stop: return [] for i in range(3, stop + 1, 2): for p in primes: if i % p == 0: break else: primes.append(i) while (primes and primes[0] < start): del primes[0] while primes: p = random.choice(primes) primes.remove(p) q_values = [q for q in primes if nMin <= p * q <= nMax] if q_values: q = random.choice(q_values) break print(p, q) n = p * q phi = (p - 1) * (q - 1) e = random.randrange(1, phi) g = gcd(e, phi) while True: e = random.randrange(1, phi) g = gcd(e, phi) d = mod_inverse(e, phi) if g == 1 and e != d: break return ((e, n), (d, n)) def encrypt(msg_plaintext, package): e, n = package msg_ciphertext = [pow(ord(c), e, n) for c in msg_plaintext] return ''.join(map(lambda x: str(x), msg_ciphertext)), msg_ciphertext def decrypt(msg_ciphertext, package): d, n = package msg_plaintext = [chr(pow(c, d, n)) for c in msg_ciphertext] return (''.join(msg_plaintext))