-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcipherRSA.py
150 lines (117 loc) · 3.76 KB
/
cipherRSA.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
# @@ @@ @@
# @@ @@ @@
# @@ @@ @@
# @@ @@@ @@ @@ @@@
# @@@@@@@* ,&@@@@@@@*
# @ @@ @@
# @@ ,@# @@
# @@@ @@@ &@#
# @@@& @@@
# @@@@@@@@@@@@@@@@@
from encod import Encod
from random import randint
enc = Encod()
def inversion(d, modulus):
"""
Инверсия по модулю на основе расширенного алгоритма Евклида.
(c*d) mod modulus
:param d: Число, относительно которого нужно найти инверсию.
:param modulus: Число, по которому нужно найти инверсию.
:return: Инверсия числа d по модулю p.
"""
u1 = modulus
u2 = 0
v1 = d
v2 = 1
while v1 != 1:
q = u1 // v1
t1 = u1 % v1
t2 = u2 - (q * v2)
u1 = v1
u2 = v2
v1 = t1
v2 = t2
if v2 < 0:
v2 = v2 + modulus
return v2
def __powerMod(base, exp, modulus):
"""
Быстрое возведение в степень и деление по модулю:
(base^exp) mod p
:param base: Основание степени.
:param exp: Степень.
:param modulus: Делитель по модулю.
:return: Деление по модулю p числа base в степени exp.
"""
if modulus == 1:
return 0
result = 1
base = base % modulus
while exp > 0:
if exp % 2 == 1:
result = (result * base) % modulus
exp = exp // 2
base = (base ** 2) % modulus
return result
def encode(m, d, n, encod="32_lw"):
"""
Кодирование сообщения m шифром RSA
:param encod: Кодировка.
:param m: Исходное сообщение.
:param d: Открытый ключ d.
:param n: Открытая часть n.
:return: Закодированное сообщение.
"""
# Преобразование из строки в цифры.
# Функция enc.encoding приводится сначала к str, потом к int
m = int("".join(enc.encoding(m, len(m), encod=encod)))
e = __powerMod(m, d, n) # Кодирование сообщения
return e
def decode(e, c, n, encod="32_lw"):
"""
Декодирование сообщения e шифром RSA.
:param encod: Кодировка.
:param e: Зашифрованное сообщение.
:param c: Закрытый ключ c.
:param n: Открытая часть n.
:return: Раскодированное сообщение.
"""
m_sh = __powerMod(e, c, n)
m_sh = str(m_sh).split() # Строка в массив.
m_sh = enc.decoding(m_sh, encod=encod) # Массив в буквы.
return m_sh
def __isPrime(n):
if n <= 1:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def __generateRandomPrime(a, b):
while True:
n = randint(a, b)
if __isPrime(n):
return n
def __gcd(a, b):
while b:
a, b = b, a % b
return a
def __isCoprime(a, b):
return __gcd(a, b) == 1
def __findCoprime(n):
while True:
i = randint(3, n-1)
if __isCoprime(n, i):
return i
def generateKey(a=1000, b=100000000000):
p = __generateRandomPrime(a, b)
q = __generateRandomPrime(a, b)
N = p * q
phi = (p - 1) * (q - 1)
c = __findCoprime(phi)
d = inversion(c, phi)
return {
"N": N,
"c": c, # Секретный ключ.
"d": d # Открытый ключ.
}