mdelatorre icon

RSA Python

mdelatorre | PRO | 09/30/16 03:32:42 PM UTC | 0 ⭐ | 661 👁️ | Never ⏰ | []
Python |

3.75 KB

|

None

|

0 👍

/

0 👎

#!/usr/bin/env python2.6
"""
rsa.py
 
Key generation, encryption, decryption via standard RSA.
http://programmingpraxis.com/2010/11/16/rsa-cryptography/
 
GRE, 11/19/10
"""
 
##########################################
#                                        #
#            Preliminaries               #
#                                        #
##########################################
 
import random
try:
# If we can use gmpy's fast procedures, we will...
    import gmpy
 
    def prime_gen(k):
        """
        Prime number p in [2^(k/2-1), 2^(k/2).
        """
        assert k >= 1, "Sorry, need a bigger input"
        p = 0
        while not gmpy.is_prime(p):
            p = random.randrange(pow(2, k//2-1) + 1, pow(2, k//2), 2)
        return p
 
    def extended_euclid(a, m):
        return [int(x) for x in gmpy.gcdext(a, m)]
 
except ImportError:
# ...if we can't, we build our own.
    def gcd(a, b):
        while b:
            a, b = b, a % b
        return a
 
    def extended_euclid(a, b):
        (x1, x2, x3) = (1, 0, a)
        (y1, y2, y3) = (0, 1, b)
        while (y3 != 0):
            quotient = x3 / y3
            tmp1 = x1 - quotient * y1
            tmp2 = x2 - quotient * y2
            tmp3 = x3 - quotient * y3
            (x1, x2, x3) = (y1, y2, y3)
            (y1, y2, y3) = (tmp1, tmp2, tmp3)
        return x3, x1, x2
 
# Miller-Rabin primality stuff:
 
    def split(n):
        """
        Splits n into 2^s * r for an odd r; used in Miller-Rabin.
        """
        s = 0
        while (n > 0) and (n % 2 == 0):
            s += 1
            n >>= 1
        return (s,n)
 
 
    def P(a,r,s,n):
        """
        Condition for primality in Miller-Rabin test.
        """
        if pow(a, r, n) == 1:
            return True
        elif (n - 1) in [pow(a, r*(2**j), n) for j in range(s)]:
            return True
        else:
            return False
 
 
    def miller_rabin(n, t):
        """
        Tests n for primality t times.
        """
        (s, r) = split(n - 1)
        for i in xrange(t):
            a = random.randint(2, n-1)
            if not P(a, r, s, n):
                return False
        return True
 
 
    def prime_gen(k):
        """
        Generates an odd that passes the Miller Rabin primality test for t = 50
        in the interval [2^(k-1), 2^k].
        """
        assert k >= 1, "Sorry, need a bigger input"
        p = 0
        while (p == 0):
            p = random.randrange(pow(2,k//2-1) + 1, pow(2, k//2), 2)
            if not miller_rabin(p, 50):
                p = 0
        return p
 
finally:
# Modular inversion
    def mod_inv(a, m):
        g, s, t = extended_euclid(a, m)
        if g == 1:
            return s % m
        else:
            return None
 
##########################################
#                                        #
#              Main Work                 #
#                                        #
##########################################
 
def key_gen(k = 32, e = prime_gen(32)):
    """
    Build keys for RSA
    """
    p = prime_gen(k)
    q = prime_gen(k)
    d = mod_inv(e, (p-1)*(q-1))
    return p*q, d
 
 
 
def crypt(message, key, mod):
    return pow(message, key, mod)
 
 
##########################################
#                                        #
#               Testing                  #
#                                        #
##########################################
if __name__ == '__main__':
    k = 32
    e = 65537
    n, d = key_gen(k, e)
    print "n = %s\nd = %s" % (n, d)
    m = 42
    print "Message m = %s" % m
    c = crypt(m, e, n)
    print "Encrypted c = %s" % c
    m2 = crypt(c, d, n)
    print "Decrypted m2 = %s" % m2

Comments