147 lines
3.4 KiB
Python
147 lines
3.4 KiB
Python
class RSA:
|
|
def __init__(self):
|
|
self.e = self.d = self.p = self.q = self.phi = 0
|
|
|
|
def __egcd(self, a, b):
|
|
if a == 0:
|
|
return (b, 0, 1)
|
|
else:
|
|
g, y, x = self.__egcd(b % a, a)
|
|
return (g, x - (b // a) * y, y)
|
|
|
|
def __modinv(self, a, m):
|
|
g, x, y = self.__egcd(a, m)
|
|
if g != 1:
|
|
raise Exception('modular inverse does not exist')
|
|
else:
|
|
return x % m
|
|
|
|
def encrypt(self, m, keyPair=None):
|
|
if (keyPair == None):
|
|
keyPair[0] = self.e
|
|
keyPair[1] = self.n
|
|
|
|
return pow(m, keyPair[0], keyPair[1])
|
|
|
|
def decrypt(self, c, keyPair=None):
|
|
if (keyPair == None):
|
|
keyPair[0] = self.d
|
|
keyPair[1] = self.n
|
|
|
|
return pow(c, keyPair[0], keyPair[1])
|
|
|
|
def generateKeys(self, p, q, e=3):
|
|
self.p = p
|
|
self.q = q
|
|
|
|
self.n = self.p * self.q
|
|
self.phi = (self.p - 1) * (self.q - 1)
|
|
self.e = e
|
|
self.d = self.__modinv(self.e, self.phi)
|
|
|
|
if (self.phi % self.e == 0):
|
|
raise Exception('invalid values for p and q')
|
|
|
|
def getPublicKey(self):
|
|
return self.e, self.n
|
|
|
|
def getPrivateKey(self):
|
|
return self.d, self.n
|
|
|
|
|
|
letterHashmap = {
|
|
'A': 10,
|
|
'B': 11,
|
|
'C': 12,
|
|
'D': 13,
|
|
'E': 14,
|
|
'F': 15,
|
|
'G': 16,
|
|
'H': 17,
|
|
'I': 18,
|
|
'J': 19,
|
|
'K': 20,
|
|
'L': 21,
|
|
'M': 22,
|
|
'N': 23,
|
|
'O': 24,
|
|
'P': 25,
|
|
'Q': 26,
|
|
'R': 27,
|
|
'S': 28,
|
|
'T': 29,
|
|
'U': 30,
|
|
'V': 31,
|
|
'W': 32,
|
|
'X': 33,
|
|
'Y': 34,
|
|
'Z': 35,
|
|
' ': 36
|
|
}
|
|
|
|
letterHashmapReverse = {
|
|
10: 'A',
|
|
11: 'B',
|
|
12: 'C',
|
|
13: 'D',
|
|
14: 'E',
|
|
15: 'F',
|
|
16: 'G',
|
|
17: 'H',
|
|
18: 'I',
|
|
19: 'J',
|
|
20: 'K',
|
|
21: 'L',
|
|
22: 'M',
|
|
23: 'N',
|
|
24: 'O',
|
|
25: 'P',
|
|
26: 'Q',
|
|
27: 'R',
|
|
28: 'S',
|
|
29: 'T',
|
|
30: 'U',
|
|
31: 'V',
|
|
32: 'W',
|
|
33: 'X',
|
|
34: 'Y',
|
|
35: 'Z',
|
|
36: ' '
|
|
}
|
|
|
|
|
|
def hashMessage(msg, init):
|
|
hashedMessage = letterHashmap[init]
|
|
for x in range(1, len(initialMessage)):
|
|
hashedMessage = hashedMessage * 100 + letterHashmap[initialMessage[x]]
|
|
return hashedMessage
|
|
|
|
|
|
def unhashMessage(msg):
|
|
letters = []
|
|
while msg > 10:
|
|
if msg % 100 in letterHashmapReverse:
|
|
letters.append(letterHashmapReverse[msg % 100])
|
|
msg = msg // 100
|
|
strn = ''.join(letters)
|
|
strn = strn[::-1]
|
|
return strn
|
|
|
|
|
|
rsa = RSA()
|
|
rsa.generateKeys(
|
|
17055899557196527525682810191339089909014331959812898993437334555169285087976951946809555356817674844913188193949144165887100694620944167618997411049745043243260854998720061941490491091205087788373487296637817044103762239946752241631032791287021875863785226376406279424552454153388492970310795447866569138481,
|
|
171994050316145327367864378293770397343246561147593187377005295591120640129800725892235968688434055779668692095961697434700708550594137135605048681344218643671046905252163983827396726536078773766353616572531688390937410451433665914394068509329532352022301339189851111636176939179510955519440490431177444857017)
|
|
|
|
initialMessage = "i love math".upper()
|
|
message = hashMessage(initialMessage, initialMessage[0])
|
|
|
|
encrypted = rsa.encrypt(message, keyPair=rsa.getPrivateKey())
|
|
decrypted = rsa.decrypt(encrypted, keyPair=rsa.getPublicKey())
|
|
|
|
print(initialMessage)
|
|
print(message)
|
|
print(encrypted)
|
|
print(decrypted)
|
|
print(unhashMessage(decrypted))
|