Skip to content

Commit 0115ee7

Browse files
Merge pull request TheAlgorithms#53 from prateekiiest/master
Upadated RSA Algorithm under Cryptography Section
2 parents 02ea8d0 + ab9e034 commit 0115ee7

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

Cryptography/RSA.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import random
2+
3+
4+
'''
5+
Euclid's algorithm for determining the greatest common divisor
6+
Use iteration to make it faster for larger integers
7+
'''
8+
def gcd(a, b):
9+
while b != 0:
10+
a, b = b, a % b
11+
return a
12+
13+
'''
14+
Euclid's extended algorithm for finding the multiplicative inverse of two numbers
15+
'''
16+
def multiplicative_inverse(e, phi):
17+
d = 0
18+
x1 = 0
19+
x2 = 1
20+
y1 = 1
21+
temp_phi = phi
22+
23+
while e > 0:
24+
temp1 = temp_phi/e
25+
temp2 = temp_phi - temp1 * e
26+
temp_phi = e
27+
e = temp2
28+
29+
x = x2- temp1* x1
30+
y = d - temp1 * y1
31+
32+
x2 = x1
33+
x1 = x
34+
d = y1
35+
y1 = y
36+
37+
if temp_phi == 1:
38+
return d + phi
39+
40+
'''
41+
Tests to see if a number is prime.
42+
'''
43+
def is_prime(num):
44+
if num == 2:
45+
return True
46+
if num < 2 or num % 2 == 0:
47+
return False
48+
for n in xrange(3, int(num**0.5)+2, 2):
49+
if num % n == 0:
50+
return False
51+
return True
52+
53+
def generate_keypair(p, q):
54+
if not (is_prime(p) and is_prime(q)):
55+
raise ValueError('Both numbers must be prime.')
56+
elif p == q:
57+
raise ValueError('p and q cannot be equal')
58+
#n = pq
59+
n = p * q
60+
61+
#Phi is the totient of n
62+
phi = (p-1) * (q-1)
63+
64+
#Choose an integer e such that e and phi(n) are coprime
65+
e = random.randrange(1, phi)
66+
67+
#Use Euclid's Algorithm to verify that e and phi(n) are comprime
68+
g = gcd(e, phi)
69+
while g != 1:
70+
e = random.randrange(1, phi)
71+
g = gcd(e, phi)
72+
73+
#Use Extended Euclid's Algorithm to generate the private key
74+
d = multiplicative_inverse(e, phi)
75+
76+
#Return public and private keypair
77+
#Public key is (e, n) and private key is (d, n)
78+
return ((e, n), (d, n))
79+
80+
def encrypt(pk, plaintext):
81+
#Unpack the key into it's components
82+
key, n = pk
83+
#Convert each letter in the plaintext to numbers based on the character using a^b mod m
84+
cipher = [(ord(char) ** key) % n for char in plaintext]
85+
#Return the array of bytes
86+
return cipher
87+
88+
def decrypt(pk, ciphertext):
89+
#Unpack the key into its components
90+
key, n = pk
91+
#Generate the plaintext based on the ciphertext and key using a^b mod m
92+
plain = [chr((char ** key) % n) for char in ciphertext]
93+
#Return the array of bytes as a string
94+
return ''.join(plain)
95+
96+
97+
if __name__ == '__main__':
98+
'''
99+
Detect if the script is being run directly by the user
100+
'''
101+
print "RSA Encrypter/ Decrypter"
102+
p = int(raw_input("Enter a prime number (17, 19, 23, etc): "))
103+
q = int(raw_input("Enter another prime number (Not one you entered above): "))
104+
print "Generating your public/private keypairs now . . ."
105+
public, private = generate_keypair(p, q)
106+
print "Your public key is ", public ," and your private key is ", private
107+
message = raw_input("Enter a message to encrypt with your private key: ")
108+
encrypted_msg = encrypt(private, message)
109+
print "Your encrypted message is: "
110+
print ''.join(map(lambda x: str(x), encrypted_msg))
111+
print "Decrypting message with public key ", public ," . . ."
112+
print "Your message is:"
113+
print decrypt(public, encrypted_msg)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy