First commit
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from Cryptotools.Numbers.coprime import phi
|
||||
from Cryptotools.Numbers.carmi import carmichael_lambda
|
||||
from Cryptotools.Utils.utils import gcd
|
||||
from Cryptotools.Numbers.primeNumber import getPrimeNumber
|
||||
from sys import getsizeof
|
||||
|
||||
class RSAKey:
|
||||
"""
|
||||
This class store the RSA key with the modulus associated
|
||||
The key is a tuple of the key and the modulus n
|
||||
|
||||
Attributes:
|
||||
key: It's the exponent key, can be public or private
|
||||
modulus: It's the public modulus
|
||||
length: It's the key length
|
||||
"""
|
||||
def __init__(self, key, modulus, length):
|
||||
"""
|
||||
Contain the RSA Key. An object of RSAKey can be a public key or a private key
|
||||
|
||||
Args:
|
||||
key (Integer): it's the exponent of the key
|
||||
modulus (Integer): it's the public modulus of the key
|
||||
length (Integer): length of the key
|
||||
"""
|
||||
|
||||
self._key = key
|
||||
self._modulus = modulus
|
||||
self._length = length
|
||||
|
||||
@property
|
||||
def key(self):
|
||||
return self._key
|
||||
|
||||
@property
|
||||
def modulus(self):
|
||||
return self._modulus
|
||||
|
||||
@property
|
||||
def length(self):
|
||||
return self.length
|
||||
|
||||
class RSA:
|
||||
"""
|
||||
This class generate public key based on RSA algorithm
|
||||
|
||||
Attributes:
|
||||
p: it's the prime number for generating the modulus
|
||||
q: it's the second prime number for the modulus
|
||||
public: Object of the RSAKey which is the public key
|
||||
private: Object of the RSAKey for the private key
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Build a RSA Key
|
||||
"""
|
||||
self._p = None
|
||||
self._q = None
|
||||
self._public = None
|
||||
self._private = None
|
||||
|
||||
def generateKeys(self, size=512):
|
||||
"""
|
||||
This function generate both public and private keys
|
||||
Args:
|
||||
size: It's the size of the key and must be multiple of 64
|
||||
"""
|
||||
# p and q must be coprime
|
||||
self._p = getPrimeNumber(size)
|
||||
self._q = getPrimeNumber(size)
|
||||
|
||||
# compute n = pq
|
||||
n = self._p * self._q
|
||||
|
||||
phin = (self._p - 1) * (self._q - 1)
|
||||
|
||||
# e must be coprime with phi(n)
|
||||
# According to the FIPS 186-5, the public key exponent must be odd
|
||||
# and the minimum size is 65536 (Cf. Section 5.4 PKCS #1)
|
||||
# https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
|
||||
e = 65535 # Works
|
||||
for i in range(2, phin - 1):
|
||||
if gcd(phin, e) == 1:
|
||||
break
|
||||
e += 1
|
||||
# print(gcd(phin, e))
|
||||
self._public = RSAKey(e, n, getsizeof(e))
|
||||
|
||||
# d is the reverse modulo of phi(n)
|
||||
# d = self._inverseModular(e, phin)
|
||||
d = pow(e, -1, phin) # Works in python 3.8
|
||||
self._private = RSAKey(d, n, getsizeof(d))
|
||||
|
||||
@property
|
||||
def e(self):
|
||||
return self._public.key
|
||||
|
||||
@property
|
||||
def d(self):
|
||||
return self._private.key
|
||||
|
||||
@property
|
||||
def n(self):
|
||||
return self._public.modulus
|
||||
|
||||
@property
|
||||
def p(self):
|
||||
return self._p
|
||||
|
||||
@property
|
||||
def q(self):
|
||||
return self._q
|
||||
|
||||
def encrypt(self, data) -> list:
|
||||
"""
|
||||
This function return a list of data encrypted with the public key
|
||||
|
||||
Args:
|
||||
data (str): it's the plaintext which need to be encrypted
|
||||
|
||||
Returns:
|
||||
return a list of the data encrypted, each entries contains the value encoded
|
||||
"""
|
||||
dataEncoded = self._str2bin(data)
|
||||
return list(
|
||||
pow(int(x), self._public.key, self._public.modulus)
|
||||
for x in dataEncoded
|
||||
)
|
||||
|
||||
def decrypt(self, data) -> list:
|
||||
"""
|
||||
This function return a list decrypted with the private key
|
||||
|
||||
Args:
|
||||
data (str): It's the encrypted data which need to be decrypted
|
||||
|
||||
Returns:
|
||||
Return the list of data uncrypted into plaintext
|
||||
"""
|
||||
decrypted = list()
|
||||
for x in data:
|
||||
d = pow(x, self._private.key, self._private.modulus)
|
||||
decrypted.append(chr(d))
|
||||
return ''.join(decrypted)
|
||||
|
||||
def _str2bin(self, data) -> list:
|
||||
"""
|
||||
This function convert a string into the unicode value
|
||||
|
||||
Args:
|
||||
data: the string which need to be converted
|
||||
|
||||
Returns:
|
||||
Return a list of unicode values of data
|
||||
"""
|
||||
return list(ord(x) for x in data)
|
||||
|
||||
def _inverseModular(self, a, n):
|
||||
"""
|
||||
This function compute the modular inverse for finding d, the decryption key
|
||||
|
||||
Args:
|
||||
a (Integer): the base of the exponent
|
||||
n (Integer): the modulus
|
||||
"""
|
||||
for b in range(1, n):
|
||||
#if pow(a, b, n) == 1:
|
||||
if (a * b) % n == 1:
|
||||
inv = b
|
||||
break
|
||||
return inv
|
||||
@@ -0,0 +1 @@
|
||||
#!/usr/bin/env python3
|
||||
Reference in New Issue
Block a user