-
Notifications
You must be signed in to change notification settings - Fork 0
/
RSA.py
221 lines (103 loc) · 2.99 KB
/
RSA.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import random
import math
# A set will be the collection of prime numbers,
# where we can select random primes p and q
prime = set()
public_key = None
private_key = None
n = None
# We will run the function only once to fill the set of
# prime numbers
def primefiller():
# Method used to fill the primes set is Sieve of
# Eratosthenes (a method to collect prime numbers)
seive = [True] * 250
seive[0] = False
seive[1] = False
for i in range(2, 250):
for j in range(i * 2, 250, i):
seive[j] = False
# Filling the prime numbers
for i in range(len(seive)):
if seive[i]:
prime.add(i)
# Picking a random prime number and erasing that prime
# number from list because p!=q
def pickrandomprime():
global prime
k = random.randint(0, len(prime) - 1)
it = iter(prime)
for _ in range(k):
next(it)
ret = next(it)
prime.remove(ret)
return ret
def setkeys():
global public_key, private_key, n
prime1 = pickrandomprime() # First prime number
prime2 = pickrandomprime() # Second prime number
n = prime1 * prime2
fi = (prime1 - 1) * (prime2 - 1)
e = 2
while True:
if math.gcd(e, fi) == 1:
break
e += 1
# d = (k*Φ(n) + 1) / e for some integer k
public_key = e
d = 2
while True:
if (d * e) % fi == 1:
break
d += 1
private_key = d
# To encrypt the given number
def encrypt(message):
global public_key, n
e = public_key
encrypted_text = 1
while e > 0:
encrypted_text *= message
encrypted_text %= n
e -= 1
return encrypted_text
# To decrypt the given number
def decrypt(encrypted_text):
global private_key, n
d = private_key
decrypted = 1
while d > 0:
decrypted *= encrypted_text
decrypted %= n
d -= 1
return decrypted
# First converting each character to its ASCII value and
# then encoding it then decoding the number to get the
# ASCII and converting it to character
def encoder(message):
encoded = []
# Calling the encrypting function in encoding function
for letter in message:
encoded.append(encrypt(ord(letter)))
return encoded
def decoder(encoded):
s = ''
# Calling the decrypting function decoding function
for num in encoded:
s += chr(decrypt(num))
return s
if __name__ == '__main__':
primefiller()
setkeys()
# message = "Test Message"
# Uncomment below for manual input
message = input("Enter the message\n")
# Calling the encoding function
coded = encoder(message)
print("Initial message:")
print(message)
print("\n\nThe encoded message(encrypted by public key)\n")
print(coded)
print(''.join(str(p) for p in coded))
print("\n\nThe decoded message(decrypted by public key)\n")
print(''.join(str(p) for p in decoder(coded)))