2
2
import sys
3
3
from sympy import isprime , mod_inverse
4
4
5
+
5
6
def generate_prime_candidate (length ):
6
7
"""
7
8
Generate a large prime number candidate.
8
-
9
+
9
10
>>> p = generate_prime_candidate(16)
10
11
>>> isprime(p)
11
12
True
@@ -15,10 +16,11 @@ def generate_prime_candidate(length):
15
16
p = random .getrandbits (length )
16
17
return p
17
18
19
+
18
20
def generate_keys (keysize ):
19
21
"""
20
22
Generate RSA keys.
21
-
23
+
22
24
>>> public, private = generate_keys(16)
23
25
>>> len(bin(public)) - 2 # Check bit length of n
24
26
32
@@ -30,7 +32,7 @@ def generate_keys(keysize):
30
32
31
33
p = generate_prime_candidate (keysize )
32
34
q = generate_prime_candidate (keysize )
33
-
35
+
34
36
n = p * q
35
37
phi = (p - 1 ) * (q - 1 )
36
38
@@ -53,21 +55,23 @@ def generate_keys(keysize):
53
55
print (f"Unexpected error generating keys: { ex } " , file = sys .stderr )
54
56
sys .exit (1 )
55
57
58
+
56
59
def gcd (a , b ):
57
60
"""
58
61
Compute the greatest common divisor of a and b.
59
-
62
+
60
63
>>> gcd(48, 18)
61
64
6
62
65
"""
63
66
while b != 0 :
64
67
a , b = b , a % b
65
68
return a
66
69
70
+
67
71
def encrypt (pk , plaintext ):
68
72
"""
69
73
Encrypt a message with a public key.
70
-
74
+
71
75
>>> public, private = generate_keys(16)
72
76
>>> encrypted = encrypt(public, "test")
73
77
>>> isinstance(encrypted, list)
@@ -84,10 +88,11 @@ def encrypt(pk, plaintext):
84
88
print (f"Unexpected error during encryption: { ex } " , file = sys .stderr )
85
89
return None
86
90
91
+
87
92
def decrypt (pk , ciphertext ):
88
93
"""
89
94
Decrypt a message with a private key.
90
-
95
+
91
96
>>> public, private = generate_keys(16)
92
97
>>> encrypted = encrypt(public, "test")
93
98
>>> decrypted = decrypt(private, encrypted)
@@ -96,17 +101,19 @@ def decrypt(pk, ciphertext):
96
101
"""
97
102
try :
98
103
key , n = pk
99
- plain = [chr ((char ** key ) % n ) for char in ciphertext ]
100
- return '' .join (plain )
104
+ plain = [chr ((char ** key ) % n ) for char in ciphertext ]
105
+ return "" .join (plain )
101
106
except TypeError as ex :
102
107
print (f"Type error during decryption: { ex } " , file = sys .stderr )
103
108
return None
104
109
except Exception as ex :
105
110
print (f"Unexpected error during decryption: { ex } " , file = sys .stderr )
106
111
return None
107
112
108
- if __name__ == '__main__' :
113
+
114
+ if __name__ == "__main__" :
109
115
import doctest
116
+
110
117
doctest .testmod ()
111
118
112
119
try :
0 commit comments