# This file contains a set of tools for doing RSA encryption. RSA depends on # a variation of Fermat's Little Theorem: # a ^ ((p - 1) * (q - 1)) = 1 (mod pq) when p and q are prime and (a, p, q) # are pairwise relatively prime # We first pick primes p and q, which gives us our modulus (n = p * q). Then # we pick values for e (our public key) and d (our private key). We then # publish n and e and instruct people to encrypt their messages to us as: # encrypted = msg ^ e % n # where msg is an integer between 0 and (n - 1). We then decrypt using d: # decrypted = encrypted ^ d % n # We'll find that decrypted = msg. # returns the prime factors of n as a list def factors(n): m = 2 result = [] while m * m <= n: if n % m == 0: result.append(m) n = n / m else: m += 1 result.append(n) return result # We start by picking our two primes using factors p = 224491 q = 470927 # This gives us the modulus n = p * q # Then we pick e and d such that e*d = (p - 1) * (q - 1) * k + 1 for some k. # We try different values of k and look at factors(temp) for possible values # for e. k = 55 temp = (p - 1) * (q - 1) * k + 1 e = 131 d = temp / e # We would encrypt this way msg = 1234567890 encrypted = msg ** e % n # convert a string to an int def to_int(str): result = 0 for ch in str: result = result * 1000 + ord(ch) return result # convert an int to a string def from_int(n): result = "" while (n > 0): result = chr(n % 1000) + result n = n / 1000 return result # returns a^n mod m def modpow(a, n, m): result = 1 while n > 0: if n % 2 == 0: a = a * a % m n = n / 2 else: result = result * a % m n = n - 1 return result % m # And decrypt this way: decrypted = modpow(encrypted, d, n)