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