First commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
__pycache__/
|
||||||
|
build/**
|
||||||
|
Cryptotools.egg-info/**
|
||||||
|
dist/**
|
||||||
|
**.swp
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Metadata-Version: 2.1
|
||||||
|
Name: Cryptotools
|
||||||
|
Version: 1.0
|
||||||
|
Summary: Cryptography library
|
||||||
|
Author: Geoffrey Bucchino
|
||||||
|
Author-email: contact@bucchino.org
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
README.md
|
||||||
|
setup.py
|
||||||
|
Cryptotools/Cryptotools.egg-info/PKG-INFO
|
||||||
|
Cryptotools/Cryptotools.egg-info/SOURCES.txt
|
||||||
|
Cryptotools/Cryptotools.egg-info/dependency_links.txt
|
||||||
|
Cryptotools/Cryptotools.egg-info/top_level.txt
|
||||||
|
Cryptotools/Numbers/__init__.py
|
||||||
|
Cryptotools/Numbers/carmi.py
|
||||||
|
Cryptotools/Numbers/numbers.py
|
||||||
|
Cryptotools/Numbers/primeNumber.py
|
||||||
|
tests/test_carmi.py
|
||||||
|
tests/test_numbers.py
|
||||||
|
tests/test_phi.py
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Numbers
|
||||||
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Groups.group import Group
|
||||||
|
|
||||||
|
|
||||||
|
class Cyclic(Group):
|
||||||
|
"""
|
||||||
|
This object contain a list of the Group for a cyclic group. This class find all generator of the group.
|
||||||
|
This class is inherited from Group object
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
G (list): list of all elements in the group
|
||||||
|
n (Integer): it's the value where the group has been generated
|
||||||
|
operation (Function): it's the operation generating the group
|
||||||
|
generators (list): contain all generators of the group
|
||||||
|
generatorChecked (boolean): Check if generators has been found
|
||||||
|
"""
|
||||||
|
def __init__(self, G:list, n, ope):
|
||||||
|
super().__init__(n, G, ope) # Call the Group's constructor
|
||||||
|
self._G = G
|
||||||
|
self._n = n
|
||||||
|
self._operation = ope
|
||||||
|
self._generators = list()
|
||||||
|
self._generatorChecked = False
|
||||||
|
|
||||||
|
def generator(self):
|
||||||
|
"""
|
||||||
|
This function find all generators in the group G
|
||||||
|
"""
|
||||||
|
|
||||||
|
index = 1
|
||||||
|
G = sorted(self._g)
|
||||||
|
for g in range(2, self._n):
|
||||||
|
z = list()
|
||||||
|
for entry in range(1, self._n):
|
||||||
|
res = self._operation(g, index, self._n)
|
||||||
|
if res not in z:
|
||||||
|
z.append(res)
|
||||||
|
index = index + 1
|
||||||
|
|
||||||
|
# We check if that match with G
|
||||||
|
# If yes, we find a generator
|
||||||
|
if sorted(z) == G:
|
||||||
|
self._generators.append(g)
|
||||||
|
self._generatorChecked = True
|
||||||
|
|
||||||
|
def getPrimitiveRoot(self):
|
||||||
|
"""
|
||||||
|
This function return the primitive root modulo of n
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the primitive root of the group. None if no primitive has been found
|
||||||
|
"""
|
||||||
|
|
||||||
|
index = 1
|
||||||
|
G = sorted(self._g)
|
||||||
|
for g in range(2, self._n):
|
||||||
|
z = list()
|
||||||
|
for entry in range(1, self._n):
|
||||||
|
res = self._operation(g, index, self._n)
|
||||||
|
if res not in z:
|
||||||
|
z.append(res)
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
# If the group is the same has G, we found a generator
|
||||||
|
if sorted(z) == G:
|
||||||
|
return g
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getGenerators(self) -> list:
|
||||||
|
"""
|
||||||
|
This function return all generators of that group
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the list of generators found. The function generators() must be called before to call this function
|
||||||
|
"""
|
||||||
|
if not self._generatorChecked:
|
||||||
|
self.generator()
|
||||||
|
self._generatorChecked = True
|
||||||
|
return self._generators
|
||||||
|
|
||||||
|
def isCyclic(self) -> bool:
|
||||||
|
"""
|
||||||
|
Check if the group is a cyclic group, means we have at least one generator
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
REturn a boolean, False if the group is not Cyclic otherwise return True
|
||||||
|
"""
|
||||||
|
if len(self.getGenerators()) == 0:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Groups.group import Group
|
||||||
|
|
||||||
|
|
||||||
|
class Galois:
|
||||||
|
"""
|
||||||
|
This class contain the Galois Field (Finite Field)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
q (Integer): it's the number of the GF
|
||||||
|
operation (Function): Function for generating the group
|
||||||
|
identityAdd (Integer): it's the identity element in the GF(n) for the addition operation
|
||||||
|
identityMul (Integer): it's the identity element in the GF(n) for the multiplicative operation
|
||||||
|
"""
|
||||||
|
def __init__(self, q, operation):
|
||||||
|
self._q = q
|
||||||
|
self._operation = operation
|
||||||
|
self._identityAdd = 0
|
||||||
|
self._identityMul = 1
|
||||||
|
self._F = [x for x in range(q)]
|
||||||
|
self._add = [[0 for x in range(q)] for y in range(q)]
|
||||||
|
|
||||||
|
# TODO: May do we do a deep copy between all groups ?
|
||||||
|
self._div = [[0 for x in range(q)] for y in range(q)]
|
||||||
|
self._mul = [[0 for x in range(q)] for y in range(q)]
|
||||||
|
self._sub = [[0 for x in range(q)] for y in range(q)]
|
||||||
|
self._primitiveRoot = list()
|
||||||
|
|
||||||
|
def primitiveRoot(self):
|
||||||
|
"""
|
||||||
|
In this function, we going to find the primitive root modulo n of the galois field
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the list of primitive root of the GF(q)
|
||||||
|
"""
|
||||||
|
for x in range(2, self._q):
|
||||||
|
z = list()
|
||||||
|
for entry in range(1, self._q):
|
||||||
|
res = self._operation(x, entry, self._q)
|
||||||
|
if res not in z:
|
||||||
|
z.append(res)
|
||||||
|
|
||||||
|
if self.isPrimitiveRoot(z, self._q - 1):
|
||||||
|
if x not in self._primitiveRoot: # It's dirty, need to find why we have duplicate entry
|
||||||
|
self._primitiveRoot.append(x)
|
||||||
|
return z
|
||||||
|
|
||||||
|
def getPrimitiveRoot(self):
|
||||||
|
"""
|
||||||
|
Return the list of primitives root
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the primitive root
|
||||||
|
"""
|
||||||
|
return self._primitiveRoot
|
||||||
|
|
||||||
|
def isPrimitiveRoot(self, z, length):
|
||||||
|
"""
|
||||||
|
Check if z is a primitive root
|
||||||
|
|
||||||
|
Args:
|
||||||
|
z (list): check if z is a primitive root
|
||||||
|
length (Integer): Length of the GF(q)
|
||||||
|
"""
|
||||||
|
if len(z) == length:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def add(self):
|
||||||
|
"""
|
||||||
|
This function do the operation + on the Galois Field
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of the group with the addition operation
|
||||||
|
"""
|
||||||
|
for x in range(0, self._q):
|
||||||
|
for y in range(0, self._q):
|
||||||
|
self._add[x][y] = (x + y) % self._q
|
||||||
|
return self._add
|
||||||
|
|
||||||
|
def _inverseModular(self, a, n):
|
||||||
|
"""
|
||||||
|
This function find the reverse modular of a by n
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the reverse modular
|
||||||
|
"""
|
||||||
|
for b in range(1, n):
|
||||||
|
if (a * b) % n == 1:
|
||||||
|
inv = b
|
||||||
|
break
|
||||||
|
return inv
|
||||||
|
|
||||||
|
def div(self):
|
||||||
|
"""
|
||||||
|
This function do the operation / on the Galois Field
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of the group with the division operation
|
||||||
|
"""
|
||||||
|
for x in range(1, self._q):
|
||||||
|
for y in range(1, self._q):
|
||||||
|
inv = self._inverseModular(y, self._q)
|
||||||
|
|
||||||
|
self._div[x][y] = (x * inv) % self._q
|
||||||
|
return self._div
|
||||||
|
|
||||||
|
def mul(self):
|
||||||
|
"""
|
||||||
|
This function do the operation * on the Galois Field
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of the group with the multiplication operation
|
||||||
|
"""
|
||||||
|
for x in range(0, self._q):
|
||||||
|
for y in range(0, self._q):
|
||||||
|
self._mul[x][y] = (x * y) % self._q
|
||||||
|
return self._mul
|
||||||
|
|
||||||
|
def sub(self):
|
||||||
|
"""
|
||||||
|
This function do the operation - on the Galois Field
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of the group with the subtraction operation
|
||||||
|
"""
|
||||||
|
for x in range(0, self._q):
|
||||||
|
for y in range(0, self._q):
|
||||||
|
self._sub[x][y] = (x - y) % self._q
|
||||||
|
return self._sub
|
||||||
|
|
||||||
|
def check_closure_law(self, arithmetic):
|
||||||
|
"""
|
||||||
|
This function check the closure law.
|
||||||
|
By definition, every element in the GF is an abelian group, which respect the closure law: for a and b belongs to G, a + b belongs to G, the operation is a binary operation
|
||||||
|
|
||||||
|
Args:
|
||||||
|
Arithmetics (str): contain the operation to be made, must be '+', '*', '/' or /-'
|
||||||
|
"""
|
||||||
|
if arithmetic not in ['+', '*', '/', '-']:
|
||||||
|
raise Exception("The arithmetic need to be '+', '*', '/' or '-'")
|
||||||
|
|
||||||
|
if arithmetic == '+':
|
||||||
|
G = self._add
|
||||||
|
elif arithmetic == '*':
|
||||||
|
G = self._mul
|
||||||
|
elif arithmetic == '/':
|
||||||
|
G = self._div
|
||||||
|
else:
|
||||||
|
G = self._sub
|
||||||
|
|
||||||
|
start = 0
|
||||||
|
"""
|
||||||
|
In case of multiplicative, we bypass the first line, because all elements are zero, otherwise the test fail
|
||||||
|
"""
|
||||||
|
if arithmetic == '*' or arithmetic == '/':
|
||||||
|
start = 1
|
||||||
|
|
||||||
|
isClosure = True
|
||||||
|
for x in range(start, self._q):
|
||||||
|
gr = Group(self._q, G[x], self._operation)
|
||||||
|
if not gr.closure():
|
||||||
|
isClosure = False
|
||||||
|
del gr
|
||||||
|
|
||||||
|
if isClosure:
|
||||||
|
print(f"The group {arithmetic} respect closure law")
|
||||||
|
else:
|
||||||
|
print(f"The group {arithmetic} does not respect closure law")
|
||||||
|
|
||||||
|
def check_identity_add(self):
|
||||||
|
"""
|
||||||
|
This function check the identity element and must satisfy this condition: $a + 0 = a$ for each element in the GF(n)
|
||||||
|
In Group Theory, an identity element is an element in the group which do not change the value every element in the group
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
for x in self._F:
|
||||||
|
if not self._identityAdd + x == x:
|
||||||
|
raise Exception(
|
||||||
|
f"The identity element {self._identityAdd} "\
|
||||||
|
"do not satisfy $a + element = a$"
|
||||||
|
)
|
||||||
|
|
||||||
|
def check_identity_mul(self):
|
||||||
|
"""
|
||||||
|
This function check the identity element and must satisfy this condition: $a * 1 = a$ for each element in the GF(n)
|
||||||
|
In Group Theory, an identity element is an element in the group which do not change the value every element in the group
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
for x in self._F:
|
||||||
|
if not self._identityMul * x == x:
|
||||||
|
raise Exception(
|
||||||
|
f"The identity element {self._identityAdd} "\
|
||||||
|
"do not satisfy $a * element = a$"
|
||||||
|
)
|
||||||
|
|
||||||
|
def printMatrice(self, m):
|
||||||
|
"""
|
||||||
|
This function print the GF(m)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
m (list): Matrix of the GF
|
||||||
|
"""
|
||||||
|
header = str()
|
||||||
|
header = " "
|
||||||
|
for x in range(0, self._q):
|
||||||
|
header += f"{x} "
|
||||||
|
|
||||||
|
header += "\n--|" + "-" * (len(header)- 3) +"\n"
|
||||||
|
|
||||||
|
s = str()
|
||||||
|
|
||||||
|
for x in range(0, self._q):
|
||||||
|
s += f"{x} | "
|
||||||
|
for y in range(0, self._q):
|
||||||
|
s += f"{m[x][y]} "
|
||||||
|
s += "\n"
|
||||||
|
|
||||||
|
s = header + s
|
||||||
|
print(s)
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
class Group:
|
||||||
|
"""
|
||||||
|
This class generate a group self._g based on the operation (here denoted +)
|
||||||
|
with the function ope: (a ** b) % n
|
||||||
|
|
||||||
|
In group theory, any group has an identity element (e), which with the binary operation, do not change the value and must satisfy the condition: $a + e = 0$
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
n (Integer): It's the G_n elements in the Group
|
||||||
|
g (List): The set of the Group
|
||||||
|
operation (Function): Function for generating the Group
|
||||||
|
identity (Integer): The identity of the group.
|
||||||
|
reverse (Dict): For each elements of the Group of n, we have the reverse value
|
||||||
|
"""
|
||||||
|
def __init__(self, n, g, ope):
|
||||||
|
self._n = n
|
||||||
|
self._g = g
|
||||||
|
self._operation = ope
|
||||||
|
self._identity = 0
|
||||||
|
self._reverse = dict()
|
||||||
|
|
||||||
|
def getG(self) -> list():
|
||||||
|
"""
|
||||||
|
This function return the Group
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of all elements in the Group
|
||||||
|
"""
|
||||||
|
return self._g
|
||||||
|
|
||||||
|
def closure(self) -> bool:
|
||||||
|
"""
|
||||||
|
Check the closure law
|
||||||
|
In a group, each element a, b belongs to G, such as a + b belongs to G
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a Boolean if the closure law is respected. True if yes otherwise it's False
|
||||||
|
"""
|
||||||
|
for e1 in self._g:
|
||||||
|
for e2 in self._g:
|
||||||
|
res = self._operation(e1, e2, self._n)
|
||||||
|
if not res in self._g:
|
||||||
|
# raise Exception(f"{res} not in g. g is not a group")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def associative(self) -> bool:
|
||||||
|
"""
|
||||||
|
Check the associative law.
|
||||||
|
In a group, for any a, b and c belongs to G,
|
||||||
|
they must respect this condition: (a + b) + c = a + (a + b)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a boolean if the Associative law is respected. True if yes otherwise it's False
|
||||||
|
"""
|
||||||
|
a = self._g[0]
|
||||||
|
b = self._g[1]
|
||||||
|
c = self._g[2]
|
||||||
|
|
||||||
|
res_ope = self._operation(a, b, self._n)
|
||||||
|
res1 = self._operation(res_ope, c, self._n)
|
||||||
|
|
||||||
|
res_ope = self._operation(b, c, self._n)
|
||||||
|
res2 = self._operation(a, res_ope, self._n)
|
||||||
|
if res1 != res2:
|
||||||
|
# raise Exception(f"{res1} is different from {res2}. g is not a group")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def identity(self) -> bool:
|
||||||
|
"""
|
||||||
|
Check the identity law.
|
||||||
|
In a group, an identity element exist and must be uniq
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a Boolean if the identity elements has been found. True if found otherwise it's False
|
||||||
|
"""
|
||||||
|
for a in self._g:
|
||||||
|
for b in self._g:
|
||||||
|
if not self._operation(a, b, self._n) == b:
|
||||||
|
break
|
||||||
|
|
||||||
|
self._identity = a
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getIdentity(self) -> int:
|
||||||
|
"""
|
||||||
|
Return the identity element. The function identitu() must be called before.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the identity element if it has been found
|
||||||
|
"""
|
||||||
|
return self._identity
|
||||||
|
|
||||||
|
def reverse(self) -> bool:
|
||||||
|
"""
|
||||||
|
Check the inverse law
|
||||||
|
In a group, for each element belongs to G
|
||||||
|
they must have an inverse a ^ (-1) = e (identity)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a Boolean if the all elements ha a reverse element. True if yes otherwise it's False
|
||||||
|
"""
|
||||||
|
reverse = False
|
||||||
|
for a in self._g:
|
||||||
|
for b in self._g:
|
||||||
|
if self._operation(a, b, self._n) == self._identity:
|
||||||
|
self._reverse[a] = b
|
||||||
|
reverse = True
|
||||||
|
break
|
||||||
|
return reverse
|
||||||
|
|
||||||
|
def getReverses(self) -> dict:
|
||||||
|
"""
|
||||||
|
This function return the dictionary of all reverses elements. The key is the element in G and the value is the reverse element
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the reverse dictionary
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self._reverse
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,177 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.primeNumber import gcd, isPrimeNumber
|
||||||
|
from Cryptotools.lcm import lcm
|
||||||
|
from Cryptotools.Numbers.coprime import phi
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
from sympy import factorint
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
|
|
||||||
|
def carmichael_lambda(n: int) -> int:
|
||||||
|
"""
|
||||||
|
This function is a carmichael lambda for identifying the smallest integer m
|
||||||
|
and saisfy this condition: a ** m congrue 1 modulo n
|
||||||
|
This function is relatively closed with the euler's totient (phi of n)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): found the smallest integer of n
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
REturn the smallest integer of n
|
||||||
|
"""
|
||||||
|
|
||||||
|
# First, factorizing n number
|
||||||
|
# factorint return a list of prime factors of n
|
||||||
|
# Base on that theorem:
|
||||||
|
# https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic
|
||||||
|
factorsN = factorint(n)
|
||||||
|
|
||||||
|
"""
|
||||||
|
The result of the factorint, we have the following:
|
||||||
|
n = p ** e1, p ** e2, ..., p ** ek
|
||||||
|
"""
|
||||||
|
|
||||||
|
factors = list()
|
||||||
|
|
||||||
|
for p, e in factorsN.items():
|
||||||
|
# Base on the theorem of arithmetic, p is always prime
|
||||||
|
if isPrimeNumber(p):
|
||||||
|
if p == 2 and e >= 3:
|
||||||
|
factors.append(phi(pow(p, e)) // 2)
|
||||||
|
elif p >= 2 and e > 0:
|
||||||
|
factors.append(phi(pow(p, e)))
|
||||||
|
elif p > 2:
|
||||||
|
factors.append(phi(pow(p, e)))
|
||||||
|
|
||||||
|
# Now, we can compute lcm
|
||||||
|
result = reduce(lcm, factors)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def carmichael_lambda2(n):
|
||||||
|
"""
|
||||||
|
Deprecated function
|
||||||
|
"""
|
||||||
|
# Get all coprimes with n
|
||||||
|
coprimes = list()
|
||||||
|
for a in range(1, n):
|
||||||
|
if gcd(a, n) == 1:
|
||||||
|
coprimes.append(a)
|
||||||
|
|
||||||
|
# Need to find the smallest value
|
||||||
|
"""
|
||||||
|
Need to find the smallest value m. Must to satisfy this condition:
|
||||||
|
a ** m congrus 1 mod n
|
||||||
|
"""
|
||||||
|
for m in range(1, n):
|
||||||
|
print(f"{m} {a ** m % n}")
|
||||||
|
|
||||||
|
print(coprimes)
|
||||||
|
|
||||||
|
def carmi_numbers(n):
|
||||||
|
"""
|
||||||
|
This function get all GCD of the number if these number are prime or not
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): Iterate to n elements
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of prime numbers
|
||||||
|
"""
|
||||||
|
# https://kconrad.math.uconn.edu/blurbs/ugradnumthy/carmichaelkorselt.pdf
|
||||||
|
primes = list()
|
||||||
|
for i in range(2, n - 1):
|
||||||
|
if gcd(n, i) == i:
|
||||||
|
if isPrimeNumber(i):
|
||||||
|
primes.append(i)
|
||||||
|
|
||||||
|
return primes
|
||||||
|
|
||||||
|
def is_carmichael(n, primes):
|
||||||
|
"""
|
||||||
|
This function check if the n number is a carmichael number. The arguments primes at least 3 prime numbers
|
||||||
|
As it's said in the Carmichael theorem, a carmichael number has three factors and they are all primes: https://en.wikipedia.org/wiki/Carmichael_number
|
||||||
|
With the Korselt's criterion, to check if the number is a carmichael number p - 1 / n - 1.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): the carmichael number
|
||||||
|
primes (list): list of prime numbers
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Boolean of the carmichael's number result
|
||||||
|
"""
|
||||||
|
r = True
|
||||||
|
n = n - 1
|
||||||
|
|
||||||
|
if len(primes) < 3:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Korselt's criterion
|
||||||
|
for p in primes:
|
||||||
|
p = p - 1
|
||||||
|
if n % p != 0:
|
||||||
|
r = False
|
||||||
|
break
|
||||||
|
return r
|
||||||
|
|
||||||
|
def is_carmi_number(n) -> bool:
|
||||||
|
"""
|
||||||
|
This function check if the number n is a carmichael number (pseudoprime)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): Iterate to n elements
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a Boolean if n is a carmichael number or not. True if yes
|
||||||
|
"""
|
||||||
|
j = 0
|
||||||
|
for i in range(n):
|
||||||
|
if i ** n % n == i:
|
||||||
|
j += 1
|
||||||
|
if j == n:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def generate_carmi_numbers(nbr) -> list:
|
||||||
|
"""
|
||||||
|
This function generate carmichael numbers, they are called pseudoprimes
|
||||||
|
For instance: a = 545, n = 561
|
||||||
|
gcd(a, n) = 1
|
||||||
|
pow(a, n - 1) % n = 1
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nbr (Integer): Find all pseudoprimes until nbr is achieves
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the list of pseudoprimes
|
||||||
|
"""
|
||||||
|
carmi = list()
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
n = 2
|
||||||
|
while count < nbr:
|
||||||
|
# First, we need to find a, coprime with n
|
||||||
|
for a in range(1, n):
|
||||||
|
# We check if n is coprime with a
|
||||||
|
# All integers must be coprime with n, a belong to n
|
||||||
|
if gcd(a, n) == 1:
|
||||||
|
# Check if is a carmichael number
|
||||||
|
# Fermat's little theorem, a ** (n - 1) % n, must be congruent to 1
|
||||||
|
if pow(a, (n - 1)) % n == 1:
|
||||||
|
#if (a ** (n - 1)) % n == 1:
|
||||||
|
#print(f"{gcd(a, n)} {a} {n}")
|
||||||
|
if n not in carmi:
|
||||||
|
count += 1
|
||||||
|
carmi.append(n)
|
||||||
|
else:
|
||||||
|
print(f"{gcd(a, n)} {a} {n}")
|
||||||
|
|
||||||
|
break
|
||||||
|
n += 1
|
||||||
|
print(carmi)
|
||||||
|
#for cop in range(2, n):
|
||||||
|
# if gcd(cop, n) == 1:
|
||||||
|
# coprimes.append(cop)
|
||||||
|
|
||||||
|
return carmi
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
|
||||||
|
|
||||||
|
# https://oeis.org/A000010
|
||||||
|
def phi(n):
|
||||||
|
"""
|
||||||
|
This function count all phi(n)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (integer): it's the phi(n) value
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the phi(n)
|
||||||
|
"""
|
||||||
|
y = 1
|
||||||
|
for i in range(2, n):
|
||||||
|
if gcd(n, i) == 1:
|
||||||
|
y += 1
|
||||||
|
return y
|
||||||
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from random import randint
|
||||||
|
from Cryptotools.Numbers.primeNumber import _millerRabinTest, isPrimeNumber
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
from Cryptotools.lcm import lcm
|
||||||
|
from math import floor, log
|
||||||
|
|
||||||
|
|
||||||
|
def pollard_p_minus_1(n, B=None) -> int:
|
||||||
|
"""
|
||||||
|
This function factorize the number n into factor based on the Pollard's p - 1 algorithm
|
||||||
|
|
||||||
|
The first is to choose B, which is a positive integer and B < n
|
||||||
|
In the second step, we need to define $M=\prod _{primes~q\leq B}q^{\lfloor \log_{q}{B}\rfloor }$
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): The number n to factorize
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the factorize of the number n or None
|
||||||
|
"""
|
||||||
|
|
||||||
|
if B is None:
|
||||||
|
B = randint(1, n - 1)
|
||||||
|
# B = randint(1, n - 1)
|
||||||
|
|
||||||
|
#### We define M
|
||||||
|
# Select all prime numbers 1 < B
|
||||||
|
q = list()
|
||||||
|
for x in range(2, B):
|
||||||
|
# with the _millerRabinTest, the program crash, because the randint() is empty
|
||||||
|
# because, both min value and max value are 2
|
||||||
|
# if _millerRabinTest(x):
|
||||||
|
if isPrimeNumber(x):
|
||||||
|
q.append(x)
|
||||||
|
|
||||||
|
M = 1
|
||||||
|
for prime in q:
|
||||||
|
e = floor(log(B, prime))
|
||||||
|
# print(prime, e)
|
||||||
|
M *= pow(prime, e)
|
||||||
|
|
||||||
|
# We choose a and coprime with n
|
||||||
|
a = 2
|
||||||
|
while True:
|
||||||
|
if gcd(a, n) == 1:
|
||||||
|
break
|
||||||
|
a += 1
|
||||||
|
|
||||||
|
# We can compute g = gcd((a ** M) - 1, n)
|
||||||
|
g = gcd(pow(a, M, n) - 1, n)
|
||||||
|
if g > 1:
|
||||||
|
return g
|
||||||
|
|
||||||
|
return None
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
def fibonacci(n) -> list:
|
||||||
|
"""
|
||||||
|
This function generate the list of Fibonacci
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (integer): it's maximum value of Fibonacci sequence
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of n element in the Fibonacci sequence
|
||||||
|
"""
|
||||||
|
fibo = [0, 1]
|
||||||
|
fibo.append(fibo[0] + fibo[1])
|
||||||
|
for i in range(2, n):
|
||||||
|
fibo.append(fibo[i - 1] + fibo[i])
|
||||||
|
return fibo
|
||||||
|
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from random import randint, seed, getrandbits
|
||||||
|
from math import log2
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
|
||||||
|
|
||||||
|
def isPrimeNumber(p):
|
||||||
|
"""
|
||||||
|
Check if the number p is a prime number or not. The function iterate until p is achieve.
|
||||||
|
|
||||||
|
This function is not the efficient way to determine if p is prime or a composite.
|
||||||
|
|
||||||
|
To identify if p is prime or not, the function check the result of the Euclidean Division has a remainder. If yes, it's means it's not a prime number
|
||||||
|
|
||||||
|
Args:
|
||||||
|
p (Integer): number if possible prime or not
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a boolean if the number p is a prime number or not. True if yes
|
||||||
|
"""
|
||||||
|
for i in range(2, p):
|
||||||
|
if p % i == 0:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
# https://people.csail.mit.edu/rivest/Rsapaper.pdf
|
||||||
|
# https://arxiv.org/pdf/1912.11546
|
||||||
|
# https://link.springer.com/content/pdf/10.1007/3-540-44499-8_27.pdf
|
||||||
|
# https://link.springer.com/article/10.1007/BF00202269
|
||||||
|
# https://www.geeksforgeeks.org/dsa/how-to-generate-large-prime-numbers-for-rsa-algorithm/
|
||||||
|
# https://crypto.stackexchange.com/questions/20548/generation-of-strong-primes
|
||||||
|
# https://crypto.stackexchange.com/questions/71/how-can-i-generate-large-prime-numbers-for-rsa
|
||||||
|
|
||||||
|
def getPrimeNumber(n, safe=True):
|
||||||
|
"""
|
||||||
|
This function generate a large prime number
|
||||||
|
based on "A method for Obtaining Digital Signatures
|
||||||
|
and Public-Key Cryptosystems"
|
||||||
|
Section B. How to Find Large Prime Numbers
|
||||||
|
https://dl.acm.org/doi/pdf/10.1145/359340.359342
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): The size of the prime number. Must be a multiple of 64
|
||||||
|
safe (Boolean): When generating the prime number, the function must find a safe prime number, based on the Germain primes (2p + 1 is also a prime number)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the prime number
|
||||||
|
"""
|
||||||
|
if n % 64 != 0:
|
||||||
|
print("Must be multiple of 64")
|
||||||
|
return
|
||||||
|
# from sys import getsizeof
|
||||||
|
upper = getrandbits(n)
|
||||||
|
lower = upper >> 7
|
||||||
|
r = randint(lower, upper)
|
||||||
|
|
||||||
|
while r % 2 == 0:
|
||||||
|
r += 1
|
||||||
|
|
||||||
|
# Now, we are going to compute r as prime number
|
||||||
|
i = 100
|
||||||
|
while 1:
|
||||||
|
# Check if it's a prime number
|
||||||
|
if _millerRabinTest(r):
|
||||||
|
break
|
||||||
|
|
||||||
|
# TODO: it's dirty, need to change that
|
||||||
|
# i = int(log2(r))
|
||||||
|
# i *= randint(2, 50)
|
||||||
|
|
||||||
|
r += i
|
||||||
|
# print(f"{i} {r}")
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
|
# print(_fermatLittleTheorem(r))
|
||||||
|
# print(getsizeof(r))
|
||||||
|
return r
|
||||||
|
|
||||||
|
def getSmallPrimeNumber(n) -> int:
|
||||||
|
"""
|
||||||
|
This function is deprecated
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): Get the small prime number until n
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return the first prime number found
|
||||||
|
"""
|
||||||
|
is_prime = True
|
||||||
|
|
||||||
|
while True:
|
||||||
|
for i in range(2, n):
|
||||||
|
# If n is divisible by i, it's not a prime, we break the loop
|
||||||
|
if n % i == 0:
|
||||||
|
is_prime = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if is_prime:
|
||||||
|
break
|
||||||
|
is_prime = True
|
||||||
|
n = n + 1
|
||||||
|
|
||||||
|
p = n
|
||||||
|
return p
|
||||||
|
|
||||||
|
def get_prime_numbers(n) -> list:
|
||||||
|
"""
|
||||||
|
This function get all prime number of the n
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): find all prime number until n is achieves
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of prime numbers
|
||||||
|
"""
|
||||||
|
l = list()
|
||||||
|
for i in range(2, n):
|
||||||
|
if n % i == 0:
|
||||||
|
l.append(i)
|
||||||
|
return l
|
||||||
|
|
||||||
|
def get_n_prime_numbers(n) -> list:
|
||||||
|
"""
|
||||||
|
This function return a list of n prime numbers
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): the range, must be an integer
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of n prime numbers
|
||||||
|
"""
|
||||||
|
l = list()
|
||||||
|
|
||||||
|
count = 2
|
||||||
|
index = 0
|
||||||
|
while index < n:
|
||||||
|
is_prime = True
|
||||||
|
for x in range(2, count):
|
||||||
|
if count % x == 0:
|
||||||
|
is_prime = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if is_prime:
|
||||||
|
l.append(count)
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
return l
|
||||||
|
|
||||||
|
def are_coprime(p1, p2):
|
||||||
|
"""
|
||||||
|
This function check if p1 and p2 are coprime
|
||||||
|
|
||||||
|
Args:
|
||||||
|
p1 (list): list of prime numbers of the first number
|
||||||
|
p2 (list): list of prime number of the second number
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a boolean result
|
||||||
|
"""
|
||||||
|
r = True
|
||||||
|
for entry in p1:
|
||||||
|
if entry in p2:
|
||||||
|
r = False
|
||||||
|
break
|
||||||
|
return r
|
||||||
|
|
||||||
|
def sieveOfEratosthenes(n) -> list:
|
||||||
|
"""
|
||||||
|
This function build a list of prime number based on the Sieve of Erastosthenes
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): Interate until n is achives
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a list of all prime numbers to n
|
||||||
|
"""
|
||||||
|
if n < 1:
|
||||||
|
return list()
|
||||||
|
|
||||||
|
eratost = dict()
|
||||||
|
for i in range(2, n):
|
||||||
|
eratost[i] = True
|
||||||
|
|
||||||
|
for i in range(2, n):
|
||||||
|
if eratost[i]:
|
||||||
|
for j in range(i*i, n, i):
|
||||||
|
eratost[j] = False
|
||||||
|
|
||||||
|
sieve = list()
|
||||||
|
for i in range(2, n):
|
||||||
|
if eratost[i]:
|
||||||
|
sieve.append(i)
|
||||||
|
|
||||||
|
return sieve
|
||||||
|
|
||||||
|
def _fermatLittleTheorem(n) -> bool:
|
||||||
|
"""
|
||||||
|
The Fermat's little theorem. if n is a prime number, any number from 0 to n- 1 is a multiple of n
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): Check if n is prime or not
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return True if the number a is a multiple of n, otherwise it's False
|
||||||
|
"""
|
||||||
|
a = randint(1, n - 1)
|
||||||
|
# We compute a ** (n - 1) % n
|
||||||
|
if pow(a, n - 1, n) == 1:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _millerRabinTest(n) -> bool:
|
||||||
|
"""
|
||||||
|
This function execute a Miller Rabin test
|
||||||
|
For the algorithm, it's based on the pseudo-algo provided by this document:
|
||||||
|
* https://www.cs.cornell.edu/courses/cs4820/2010sp/handouts/MillerRabin.pdf
|
||||||
|
The Mille-Rabin test is an efficient way to determine if n is prime or not
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): Check if n is a prime number
|
||||||
|
Returns:
|
||||||
|
Return a boolean. True for a prime otherwise, it's a composite number
|
||||||
|
|
||||||
|
"""
|
||||||
|
if n < 2 or (n > 2 and n % 2 == 0): # If n is even, it's a composite
|
||||||
|
return False
|
||||||
|
|
||||||
|
k = 0
|
||||||
|
q = n - 1
|
||||||
|
#while (q & 1) == 0:
|
||||||
|
# k += 1
|
||||||
|
# q >>= 1
|
||||||
|
while q % 2 == 0:
|
||||||
|
k += 1
|
||||||
|
q //= 2
|
||||||
|
|
||||||
|
# We choose a: a < n - 1
|
||||||
|
for _ in range(40):
|
||||||
|
a = randint(2, n - 1)
|
||||||
|
# We compute a ** q % n
|
||||||
|
x = pow(a, q, n)
|
||||||
|
|
||||||
|
# If it's a composite number
|
||||||
|
if x == 1 or x == n - 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for _ in range(k):
|
||||||
|
z = pow(x, 2, n)
|
||||||
|
if z == 1 or z == n - 1:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def sophieGermainPrime(p) -> bool:
|
||||||
|
"""
|
||||||
|
Check if the number p is a safe prime number: 2p + 1 is also a prime
|
||||||
|
|
||||||
|
Args:
|
||||||
|
p (Integer): Possible prime number
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return True if p is a safe prime number, otherwise it's False
|
||||||
|
"""
|
||||||
|
pp = 2 * p + 1
|
||||||
|
return _millerRabinTest(pp)
|
||||||
|
|
||||||
|
def isSafePrime(n) -> bool:
|
||||||
|
"""
|
||||||
|
This function has not been implemented yet, but check if the number n is a safe prime number. This function will test different properties of the possible prime number n
|
||||||
|
|
||||||
|
Args:
|
||||||
|
n (Integer): the prime number to check
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Return a Boolean if the prime number n is safe or not. True if yes, otherwise it's False
|
||||||
|
"""
|
||||||
|
if n.bit_length() >= 256:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Do Sophie Germain's test
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
COMPOSITE = 0
|
||||||
|
PRIME = 1
|
||||||
|
|
||||||
|
class Number:
|
||||||
|
def __init__(self):
|
||||||
|
self._int = int()
|
||||||
|
self._kind = COMPOSITE
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
def gcd(a, b):
|
||||||
|
"""
|
||||||
|
This function calculate the GCD (Greatest Common Divisor of the number a of b
|
||||||
|
Args:
|
||||||
|
a (Integer): the number a
|
||||||
|
b (integer): the number b
|
||||||
|
|
||||||
|
Return:
|
||||||
|
the GCD
|
||||||
|
"""
|
||||||
|
|
||||||
|
if b == 0:
|
||||||
|
return a
|
||||||
|
return gcd(b, a%b)
|
||||||
|
|
||||||
|
def egcd(a, b):
|
||||||
|
"""
|
||||||
|
This function compute the Extended Euclidean algorithm
|
||||||
|
https://user.eng.umd.edu/~danadach/Cryptography_20/ExtEuclAlg.pdf
|
||||||
|
https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
|
||||||
|
|
||||||
|
Args:
|
||||||
|
a (Integer): the number a
|
||||||
|
b (Integer): the number b
|
||||||
|
"""
|
||||||
|
if a == 0:
|
||||||
|
return b, 0, 1
|
||||||
|
gcd, x1, y1 = egcd(b % a, a)
|
||||||
|
x = y1 - (b // a) * x1
|
||||||
|
y = x1
|
||||||
|
return gcd, x, y
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
__all__ = ["Numbers", "Groups"]
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.primeNumber import gcd
|
||||||
|
|
||||||
|
def compute_multiple(a):
|
||||||
|
"""
|
||||||
|
This function compute the 20 first multiples of the number a
|
||||||
|
|
||||||
|
Args:
|
||||||
|
a (Integer): the number
|
||||||
|
|
||||||
|
Return:
|
||||||
|
list of multiple of a
|
||||||
|
"""
|
||||||
|
|
||||||
|
r = list()
|
||||||
|
for i in range(1, 20):
|
||||||
|
r.append(a * i)
|
||||||
|
return r
|
||||||
|
|
||||||
|
def lcm(a, b):
|
||||||
|
"""
|
||||||
|
This function get the LCM (Least Common Multiple) a of b
|
||||||
|
|
||||||
|
Args:
|
||||||
|
a (Integer): the number
|
||||||
|
b (Integer): the number
|
||||||
|
|
||||||
|
Return:
|
||||||
|
the LCM
|
||||||
|
"""
|
||||||
|
return (b // gcd(a, b)) * a
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Introduction
|
||||||
|
This project contains the module *cryptotools* which can used for cryptography
|
||||||
|
|
||||||
|
# Install the program
|
||||||
|
```
|
||||||
|
$ virtualenv ~/venv/myenv
|
||||||
|
$ source ~/venv/myenv/bin/activate
|
||||||
|
$ python3 setup.py install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
In the directory *examples/*, you have different python files for using the module
|
||||||
|
|
||||||
|
## Unitests
|
||||||
|
### Test phi
|
||||||
|
```
|
||||||
|
$ python3 tests/test_phi.py -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Fibonacci
|
||||||
|
For testing Fibonacci sequence, I generate a list from OEIS wich contains 40 first numbers of Fibonacci. The `test_numbers.py` test the Fibonacci sequence generated from the functions `fibonacci` in `utils/numbers.py`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python3 tests/test_numbers.py -v
|
||||||
|
```
|
||||||
|
|
||||||
|
# Build the doc
|
||||||
|
|
||||||
|
```
|
||||||
|
$ mkdocs build
|
||||||
|
```
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Generating RSA Keys
|
||||||
|
In the following section, we are going to see how to generate RSA Keys and how to encrypt data with these keys.
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Encryptions.RSA import RSA
|
||||||
|
|
||||||
|
|
||||||
|
rsa = RSA()
|
||||||
|
rsa.generateKeys(size=512)
|
||||||
|
|
||||||
|
e = rsa.e
|
||||||
|
d = rsa.d
|
||||||
|
n = rsa.n
|
||||||
|
|
||||||
|
s = "I am encrypted with RSA"
|
||||||
|
print(f"plaintext: {s}")
|
||||||
|
encrypted = rsa.encrypt(s)
|
||||||
|
|
||||||
|
# Encrypt data
|
||||||
|
print(f"ciphertext: {encrypted}")
|
||||||
|
|
||||||
|
# We decrypt
|
||||||
|
plaintext = rsa.decrypt(encrypted)
|
||||||
|
print(f"Plaintext: {plaintext}")
|
||||||
|
```
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Group Theory
|
||||||
|
## Group
|
||||||
|
::: Cryptotools.Groups.group
|
||||||
|
|
||||||
|
## Cyclic group
|
||||||
|
::: Cryptotools.Groups.cyclic
|
||||||
|
|
||||||
|
## Galois Field (Finite Field)
|
||||||
|
::: Cryptotools.Groups.galois
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Welcome to CryptoTools
|
||||||
|
|
||||||
|
* [Introduction](/introduction)
|
||||||
|
* [Installation](/installation)
|
||||||
|
* Low-Level Cryptographic
|
||||||
|
* [Number Theory](/number-theory)
|
||||||
|
* [Group Theory](/group-theory)
|
||||||
|
* Public Keys:
|
||||||
|
* [RSA](/rsa)
|
||||||
|
* Examples:
|
||||||
|
* [Generating RSA keys](/examples-rsa-keys)
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Installation
|
||||||
|
To install the project, you should install from my own Python repository but, you first need to deploy your virtual enviroment.
|
||||||
|
|
||||||
|
## Installation from source
|
||||||
|
You can install from the source. Download the [project](https://gitea.bucchino.org/gbucchino/cryptotools.git) and install it in your virtual environment:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ virtualenv ~/venv/cryptotools
|
||||||
|
$ source ~/venv/cryptotools/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git clone https://gitea.bucchino.org/gbucchino/cryptotools.git
|
||||||
|
$ cd cryptotools
|
||||||
|
$ python3 setup.py install
|
||||||
|
```
|
||||||
|
|
||||||
|
The installation is completed. You can know use Cryptotools package into your project. In the directory `examples` you may find some examples scripts
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# CryptoTools
|
||||||
|
CryptoTools is a Python package that provides low-level cryptographic primitives for generating strong numbers. With this project, it's possible to generate public key cryptosystems such as RSA.
|
||||||
|
This project has a academic purpose and can not be used in production enviroment yet.
|
||||||
|
|
||||||
|
So far, my cryptographic modules are not compliant with [FIPS 140-3](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-3.pdf) but in the future, that will be.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Number Theory
|
||||||
|
For generating keys, we need strong prime number, they are the basis. CryptoTools provides functions for generating these numbers.
|
||||||
|
|
||||||
|
## prime numbers
|
||||||
|
::: Cryptotools.Numbers.primeNumber
|
||||||
|
|
||||||
|
## Fibonacci sequence
|
||||||
|
::: Cryptotools.Numbers.numbers
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
CryptoTools provides several functions for generating a RSA Keys
|
||||||
|
|
||||||
|
::: Cryptotools.Encryptions.RSA
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
|
||||||
|
|
||||||
|
def carmi_first_method(n) -> int:
|
||||||
|
coprimes = list()
|
||||||
|
for i in range(1, n):
|
||||||
|
if gcd(i, n) == 1:
|
||||||
|
coprimes.append(i)
|
||||||
|
print(coprimes)
|
||||||
|
smallest = list()
|
||||||
|
for m in range(1, n):
|
||||||
|
l = 0
|
||||||
|
for a in coprimes:
|
||||||
|
if a ** m % n == 1:
|
||||||
|
l += 1
|
||||||
|
if l == len(coprimes):
|
||||||
|
smallest.append(m)
|
||||||
|
|
||||||
|
#print(smallest)
|
||||||
|
return min(smallest)
|
||||||
|
|
||||||
|
print(f"lambda(12) = {carmi_first_method(12)}")
|
||||||
|
print(f"lambda(19) = {carmi_first_method(19)}")
|
||||||
|
#print(f"lambda(28) = {carmi_first_method(28)}")
|
||||||
|
#print(f"lambda(32) = {carmi_first_method(32)}")
|
||||||
|
#print(f"lambda(33) = {carmi_first_method(33)}")
|
||||||
|
#print(f"lambda(35) = {carmi_first_method(35)}")
|
||||||
|
#print(f"lambda(36) = {carmi_first_method(36)}")
|
||||||
|
#print(f"lambda(135) = {carmi_first_method(135)}")
|
||||||
|
#print(f"lambda(1200) = {carmi_first_method(1200)}")
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.coprime import phi
|
||||||
|
from Cryptotools.lcm import lcm
|
||||||
|
from Cryptotools.Numbers.carmi import carmi_numbers, is_carmichael, carmichael_lambda
|
||||||
|
|
||||||
|
print(f"phi(19) = {phi(19)}")
|
||||||
|
|
||||||
|
print("Carmichael's number")
|
||||||
|
l = carmi_numbers(561)
|
||||||
|
print(is_carmichael(561, l))
|
||||||
|
|
||||||
|
# Test Carmichael lambda
|
||||||
|
print("Carmichael")
|
||||||
|
print(f"12 {carmichael_lambda(12)}")
|
||||||
|
print(f"19 {carmichael_lambda(19)}")
|
||||||
|
print(f"28 {carmichael_lambda(28)}")
|
||||||
|
print(f"32 {carmichael_lambda(32)}")
|
||||||
|
print(f"33 {carmichael_lambda(33)}")
|
||||||
|
print(f"35 {carmichael_lambda(35)}")
|
||||||
|
print(f"36 {carmichael_lambda(36)}")
|
||||||
|
print(f"135 {carmichael_lambda(135)}")
|
||||||
|
print(f"1200 {carmichael_lambda(1200)}")
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Groups.cyclic import Cyclic
|
||||||
|
from Cryptotools.Numbers.primeNumber import isPrimeNumber
|
||||||
|
from random import choice
|
||||||
|
|
||||||
|
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
n = 19
|
||||||
|
g = list()
|
||||||
|
for i in range(1, n):
|
||||||
|
g.append(i)
|
||||||
|
|
||||||
|
print(f"n = {n}")
|
||||||
|
print(f"G = {g}")
|
||||||
|
|
||||||
|
cyclic = Cyclic(g, n, operation)
|
||||||
|
order = len(g) # Length of the group
|
||||||
|
print(f"len: {order}")
|
||||||
|
print(f"prime: {isPrimeNumber(order)}")
|
||||||
|
|
||||||
|
cyclic.generator()
|
||||||
|
|
||||||
|
print(f"All generators: {cyclic.getGenerators()}")
|
||||||
|
print(f"Is cyclic: {cyclic.isCyclic()}")
|
||||||
|
|
||||||
|
# Check if the abelian group is respected
|
||||||
|
print(f"It is an abelian group: {cyclic.closure()}\n")
|
||||||
|
|
||||||
|
|
||||||
|
e = choice(cyclic.getGenerators())
|
||||||
|
z = list()
|
||||||
|
for a in range(1, n):
|
||||||
|
res = operation(e, a, n)
|
||||||
|
z.append(res)
|
||||||
|
|
||||||
|
print(z)
|
||||||
|
if z == g:
|
||||||
|
print(f"The group generated with the generator {e} works")
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from Cryptotools.Groups.cyclic import Cyclic
|
||||||
|
from Cryptotools.Numbers.primeNumber import getPrimeNumber
|
||||||
|
from random import randint, choice
|
||||||
|
from math import log, log10, log2
|
||||||
|
|
||||||
|
"""
|
||||||
|
Here, we will try to understand why we need to have a generator when we encrypt data for Diffie-Hellman
|
||||||
|
https://crypto.stackexchange.com/questions/25489/why-does-diffie-hellman-need-be-a-cyclic-group
|
||||||
|
"""
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
def getGenerator(gr, p):
|
||||||
|
index = 1
|
||||||
|
for g in range(2, p):
|
||||||
|
z = list()
|
||||||
|
for entry in range(1, p):
|
||||||
|
res = operation(g, index, p)
|
||||||
|
#if res not in z:
|
||||||
|
z.append(res)
|
||||||
|
index = index + 1
|
||||||
|
print(f"{g}: {sorted(z)}")
|
||||||
|
|
||||||
|
def generateGroupByG(gr, p, g):
|
||||||
|
index = 1
|
||||||
|
z = list()
|
||||||
|
for entry in range(1, p):
|
||||||
|
res = operation(g, index, p)
|
||||||
|
#if res not in z:
|
||||||
|
z.append(res)
|
||||||
|
index = index + 1
|
||||||
|
return z
|
||||||
|
|
||||||
|
def computePublicKey(key, p, g):
|
||||||
|
return (g ** key) % p
|
||||||
|
|
||||||
|
|
||||||
|
gr = list()
|
||||||
|
# Public value
|
||||||
|
p = 5
|
||||||
|
g = 0
|
||||||
|
for i in range(1, p):
|
||||||
|
gr.append(i)
|
||||||
|
|
||||||
|
print(f"p = {p}")
|
||||||
|
print(f"G = {gr}")
|
||||||
|
# We try with a generator which is not in list
|
||||||
|
cyclic = Cyclic(gr, p, operation)
|
||||||
|
generators = cyclic.getGenerators()
|
||||||
|
print(f"All generators: {generators}")
|
||||||
|
|
||||||
|
# Generate group with g = 2
|
||||||
|
grWithG = generateGroupByG(gr, p, 2)
|
||||||
|
print(f"Group generated with g = 2: {grWithG}")
|
||||||
|
|
||||||
|
for a in grWithG:
|
||||||
|
# print(f"log2({a}) = {log(a, 2)}") # Same as below
|
||||||
|
print(f"log2({a}) = {log2(a)}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
for a in range(1, len(grWithG) + 1):
|
||||||
|
print(f"log2({a}) = {log2(a)}")
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Groups.cyclic import Cyclic
|
||||||
|
from random import choice
|
||||||
|
|
||||||
|
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
n = 19
|
||||||
|
g = list()
|
||||||
|
for i in range(1, n):
|
||||||
|
g.append(i)
|
||||||
|
|
||||||
|
print(f"n = {n}")
|
||||||
|
print(f"G = {g}")
|
||||||
|
|
||||||
|
cyclic = Cyclic(g, n, operation)
|
||||||
|
|
||||||
|
cyclic.generator()
|
||||||
|
generators = cyclic.getGenerators()
|
||||||
|
print(f"All generators: {generators}")
|
||||||
|
|
||||||
|
e = choice(generators)
|
||||||
|
z = list()
|
||||||
|
for a in range(1, n):
|
||||||
|
res = operation(e, a, n)
|
||||||
|
z.append(res)
|
||||||
|
|
||||||
|
z = sorted(z)
|
||||||
|
if z == g:
|
||||||
|
print(f"Working with the generator {e}")
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from Cryptotools.Groups.cyclic import Cyclic
|
||||||
|
from Cryptotools.Numbers.primeNumber import getPrimeNumber
|
||||||
|
from random import randint, choice
|
||||||
|
from math import log, log10
|
||||||
|
|
||||||
|
"""
|
||||||
|
Here, we will try to understand why we need to have a generator when we encrypt data for Diffie-Hellman
|
||||||
|
https://crypto.stackexchange.com/questions/25489/why-does-diffie-hellman-need-be-a-cyclic-group
|
||||||
|
"""
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
def getGenerator(gr, p):
|
||||||
|
cyclic = Cyclic(gr, p, operation)
|
||||||
|
generators = cyclic.getGenerators()
|
||||||
|
print(f"All generators: {generators}")
|
||||||
|
cyclic.identity()
|
||||||
|
print(f"Identity: {cyclic.getIdentity()}")
|
||||||
|
|
||||||
|
return generators
|
||||||
|
|
||||||
|
|
||||||
|
gr = list()
|
||||||
|
# Public value
|
||||||
|
p = 13
|
||||||
|
g = 0
|
||||||
|
for i in range(1, p):
|
||||||
|
gr.append(i)
|
||||||
|
|
||||||
|
print(f"p = {p}")
|
||||||
|
print(f"G = {gr}")
|
||||||
|
# We try with a generator which is not in list
|
||||||
|
generators = getGenerator(gr, p)
|
||||||
|
|
||||||
|
g = 3 # In the group
|
||||||
|
#g = # Not in the group
|
||||||
|
#print(f"g = {g}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Try to compute the cyclic subgroup
|
||||||
|
for G in range(p + 1):
|
||||||
|
res = 0
|
||||||
|
for a in range(G):
|
||||||
|
r = operation(G, a, p)
|
||||||
|
res = res + r
|
||||||
|
if res == p:
|
||||||
|
print(f"G = {G}; res = {res}")
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Groups.cyclic import Cyclic
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
from Cryptotools.Numbers.primeNumber import isPrimeNumber
|
||||||
|
from random import choice
|
||||||
|
|
||||||
|
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
def test1(n):
|
||||||
|
"""
|
||||||
|
We test with n is not prime but the order of the group is a prime number
|
||||||
|
"""
|
||||||
|
g = list()
|
||||||
|
g2 = list()
|
||||||
|
for i in range(1, n):
|
||||||
|
#if gcd(i, n) == 1:
|
||||||
|
g.append(i)
|
||||||
|
|
||||||
|
print(f"n = {n}")
|
||||||
|
print(f"G = {g}")
|
||||||
|
Gsorted = sorted(g)
|
||||||
|
|
||||||
|
cyclic = Cyclic(g, n, operation)
|
||||||
|
order = len(g) # https://en.wikipedia.org/wiki/Order_(group_theory)
|
||||||
|
print(f"len: {order}")
|
||||||
|
print(f"prime: {isPrimeNumber(order)}")
|
||||||
|
g2 = list()
|
||||||
|
for i in range(1, order):
|
||||||
|
if gcd(i, order) == 1:
|
||||||
|
g2.append(i)
|
||||||
|
pass
|
||||||
|
|
||||||
|
print(g2)
|
||||||
|
# Pick a number in the previous list and check if we can generate all number with it
|
||||||
|
item = choice(g2)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# if the order is prime, the group is cyclic ?
|
||||||
|
|
||||||
|
# Check if we have all items
|
||||||
|
g3 = list()
|
||||||
|
for i in range(1, n):
|
||||||
|
res = operation(i, item, n)
|
||||||
|
if gcd(res, item) == 1:
|
||||||
|
g3.append(res)
|
||||||
|
#print(res)
|
||||||
|
pass
|
||||||
|
|
||||||
|
G2sorted = sorted(g2)
|
||||||
|
G3sorted = sorted(g3)
|
||||||
|
print()
|
||||||
|
# print(f"{g} = {cyclic.generator(g)}")
|
||||||
|
gen = cyclic.generator()
|
||||||
|
|
||||||
|
print(f"All generators: {cyclic.getGenerators()}")
|
||||||
|
print(f"Is cyclic: {cyclic.isCyclic()}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(G2sorted)
|
||||||
|
print(G3sorted)
|
||||||
|
if G3sorted == Gsorted:
|
||||||
|
print(f"Matching with item {item}") # Always match with item 1
|
||||||
|
|
||||||
|
# Check if the abelian group is respected
|
||||||
|
print(f"It is an abelian group: {cyclic.closure()}\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
test1(19)
|
||||||
|
test1(12)
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from Cryptotools.Groups.cyclic import Cyclic
|
||||||
|
from Cryptotools.Numbers.primeNumber import getPrimeNumber
|
||||||
|
from random import randint, choice
|
||||||
|
from math import log, log10
|
||||||
|
|
||||||
|
"""
|
||||||
|
Here, we will try to understand why we need to have a generator when we encrypt data for Diffie-Hellman
|
||||||
|
https://crypto.stackexchange.com/questions/25489/why-does-diffie-hellman-need-be-a-cyclic-group
|
||||||
|
"""
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
def getGenerator(gr, p):
|
||||||
|
cyclic = Cyclic(gr, p, operation)
|
||||||
|
generators = cyclic.getGenerators()
|
||||||
|
print(f"All generators: {generators}")
|
||||||
|
|
||||||
|
# Test with a no generator
|
||||||
|
item = 2
|
||||||
|
while item in generators: # we loop until we found an item which is not a generators of the group
|
||||||
|
item = randint(1, p)
|
||||||
|
return item
|
||||||
|
|
||||||
|
def computePublicKey(key, p, g):
|
||||||
|
return (g ** key) % p
|
||||||
|
|
||||||
|
def computeEphemeralKey(public, secret, p):
|
||||||
|
return (public ** secret) % p
|
||||||
|
|
||||||
|
gr = list()
|
||||||
|
# Public value
|
||||||
|
#p = getPrimeNumber(n = 8)
|
||||||
|
#p = 257
|
||||||
|
p = 19
|
||||||
|
g = 0
|
||||||
|
for i in range(1, p):
|
||||||
|
gr.append(i)
|
||||||
|
|
||||||
|
print(f"p = {p}")
|
||||||
|
print(f"G = {gr}")
|
||||||
|
# We try with a generator which is not in list
|
||||||
|
g = getGenerator(gr, p)
|
||||||
|
#g = [3, 5, 6, 7, 10, 12, 14, 19, 20, 24, 27, 28, 33, 37, 38, 39, 40, 41, 43, 45, 47, 48, 51, 53, 54, 55, 56, 63, 65, 66, 69, 71, 74, 75, 76, 77, 78, 80, 82, 83, 85, 86, 87, 90, 91, 93, 94, 96, 97, 101, 102, 103, 105, 106, 107, 108, 109, 110, 112, 115, 119, 125, 126, 127, 130, 131, 132, 138, 142, 145, 147, 148, 149, 150, 151, 152, 154, 155, 156, 160, 161, 163, 164, 166, 167, 170, 171, 172, 174, 175, 177, 179, 180, 181, 182, 183, 186, 188, 191, 192, 194, 201, 202, 203, 204, 206, 209, 210, 212, 214, 216, 217, 218, 219, 220, 224, 229, 230, 233, 237, 238, 243, 245, 247, 250, 251, 252, 254]
|
||||||
|
g = 29 # Not in the group
|
||||||
|
print(f"g = {g}")
|
||||||
|
|
||||||
|
# We can compute with the secret key
|
||||||
|
secretKeyA = 5
|
||||||
|
secretKeyB = 10
|
||||||
|
publicKeyA = computePublicKey(secretKeyA, p, g)
|
||||||
|
publicKeyB = computePublicKey(secretKeyB, p, g)
|
||||||
|
print(f"Public key A: {publicKeyA}")
|
||||||
|
print(f"Public key B: {publicKeyB}")
|
||||||
|
|
||||||
|
# Eve sniff the traffic and knows p, g and publicKeyA and B
|
||||||
|
|
||||||
|
|
||||||
|
# Generator need to be use, because that avoid to Eve to try to find a secret key of Alice or Bob ???
|
||||||
|
# Utiliser un generateur qui genere la tout le groupe, va permettre d'éviter à Eve de trouver la secret key de Alice ou Bob ????
|
||||||
|
# https://eitca.org/cybersecurity/eitc-is-acc-advanced-classical-cryptography/diffie-hellman-cryptosystem/diffie-hellman-key-exchange-and-the-discrete-log-problem/examination-review-diffie-hellman-key-exchange-and-the-discrete-log-problem/what-are-the-roles-of-the-prime-number-p-and-the-generator-alpha-in-the-diffie-hellman-key-exchange-process/
|
||||||
|
# https://www.perplexity.ai/search/why-generator-in-cyclic-group-QRYR6.rxSI218hs_x5CvnQ#0
|
||||||
|
|
||||||
|
# They exchange their public keys
|
||||||
|
ephemeralKeyA = computeEphemeralKey(publicKeyB, secretKeyA, p)
|
||||||
|
ephemeralKeyB = computeEphemeralKey(publicKeyA, secretKeyB, p)
|
||||||
|
print(f"Ephemeral key A: {ephemeralKeyA}")
|
||||||
|
print(f"Ephemeral key B: {ephemeralKeyB}")
|
||||||
|
|
||||||
|
# Test log10
|
||||||
|
#for i in range(1, 1000):
|
||||||
|
# r = log10(i)
|
||||||
|
# if isinstance(r, int):
|
||||||
|
# print(f"{i} = {r}")
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from Cryptotools.Groups.cyclic import Cyclic
|
||||||
|
from Cryptotools.Numbers.primeNumber import getPrimeNumber
|
||||||
|
from random import randint, choice
|
||||||
|
from math import log, log10
|
||||||
|
|
||||||
|
"""
|
||||||
|
Here, we will try to understand why we need to have a generator when we encrypt data for Diffie-Hellman
|
||||||
|
https://crypto.stackexchange.com/questions/25489/why-does-diffie-hellman-need-be-a-cyclic-group
|
||||||
|
"""
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
def getGenerator(gr, p):
|
||||||
|
index = 1
|
||||||
|
for g in range(2, p):
|
||||||
|
z = list()
|
||||||
|
for entry in range(1, p):
|
||||||
|
res = operation(g, index, p)
|
||||||
|
#if res not in z:
|
||||||
|
z.append(res)
|
||||||
|
index = index + 1
|
||||||
|
print(f"{g}: {sorted(z)}")
|
||||||
|
|
||||||
|
def getGenerator2(gr, p, g):
|
||||||
|
index = 1
|
||||||
|
z = list()
|
||||||
|
for entry in range(1, p):
|
||||||
|
res = operation(g, index, p)
|
||||||
|
if res not in z:
|
||||||
|
z.append(res)
|
||||||
|
index = index + 1
|
||||||
|
return z
|
||||||
|
|
||||||
|
|
||||||
|
def computePublicKey(key, p, g):
|
||||||
|
return (g ** key) % p
|
||||||
|
|
||||||
|
def computeEphemeralKey(public, secret, p):
|
||||||
|
return (public ** secret) % p
|
||||||
|
|
||||||
|
gr = list()
|
||||||
|
# Public value
|
||||||
|
p = 43
|
||||||
|
g = 0
|
||||||
|
for i in range(1, p):
|
||||||
|
gr.append(i)
|
||||||
|
|
||||||
|
print(f"p = {p}")
|
||||||
|
print(f"G = {gr}")
|
||||||
|
# We try with a generator which is not in list
|
||||||
|
cyclic = Cyclic(gr, p, operation)
|
||||||
|
generators = cyclic.getGenerators()
|
||||||
|
print(f"All generators: {generators}")
|
||||||
|
|
||||||
|
g = 3 # In the group
|
||||||
|
print(f"g = {g}")
|
||||||
|
|
||||||
|
# We can compute with the secret key
|
||||||
|
secretKeyA = 5
|
||||||
|
secretKeyB = 10
|
||||||
|
publicKeyA = computePublicKey(secretKeyA, p, g)
|
||||||
|
publicKeyB = computePublicKey(secretKeyB, p, g)
|
||||||
|
print(f"Public key A: {publicKeyA}")
|
||||||
|
print(f"Public key B: {publicKeyB}\n")
|
||||||
|
|
||||||
|
# Here, g is in the generator, we need to compute all values until that match with publicKeyA
|
||||||
|
for a in range(1, p):
|
||||||
|
res = operation(g, a, p)
|
||||||
|
if res == publicKeyA:
|
||||||
|
print(f"Brute forced secret key of A: {a}")
|
||||||
|
|
||||||
|
for a in range(1, p):
|
||||||
|
res = operation(g, a, p)
|
||||||
|
if res == publicKeyB:
|
||||||
|
print(f"Brute forced secret key of B: {a}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
#for a in generators:
|
||||||
|
# print(a)
|
||||||
|
#
|
||||||
|
#print()
|
||||||
|
|
||||||
|
# Here, we generate all key withthe same generator
|
||||||
|
keys = list()
|
||||||
|
for a in range(1, p):
|
||||||
|
keys.append(operation(g, a, p))
|
||||||
|
|
||||||
|
print((keys))
|
||||||
|
print(sorted(keys))
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(f"Keys with g = 4: {sorted(getGenerator2(gr, p, 4))}")
|
||||||
|
|
||||||
|
# Do the same, but g is not a generator
|
||||||
|
g = 4 # Not in the generator group
|
||||||
|
publicKeyA = computePublicKey(secretKeyA, p, g)
|
||||||
|
publicKeyB = computePublicKey(secretKeyB, p, g)
|
||||||
|
print(f"Public key A: {publicKeyA}")
|
||||||
|
print(f"Public key B: {publicKeyB}")
|
||||||
|
|
||||||
|
keys = list()
|
||||||
|
for a in range(1, p):
|
||||||
|
keys.append(operation(g, a, p))
|
||||||
|
print(keys)
|
||||||
|
|
||||||
|
# Eve sniff the traffic and knows p, g and publicKeyA and B
|
||||||
|
# Eve, knows p and g, because it's public
|
||||||
|
# Eve need to guess the secretKey of A.
|
||||||
|
# For doing that, we iterate all posibility until that match with the publicKeyA
|
||||||
|
|
||||||
|
#for a in range(1, 4):
|
||||||
|
# res = operation(g, a, p)
|
||||||
|
# print(res)
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from Cryptotools.Numbers.primeNumber import isPrimeNumber, _millerRabinTest, getPrimeNumber
|
||||||
|
from math import sqrt, isqrt, ceil
|
||||||
|
from sympy import sqrt as sq
|
||||||
|
|
||||||
|
def get_closest_prime(p):
|
||||||
|
q = p + 1
|
||||||
|
l = list()
|
||||||
|
while True:
|
||||||
|
if _millerRabinTest(q):
|
||||||
|
l.append(q)
|
||||||
|
if len(l) == 20:
|
||||||
|
break
|
||||||
|
q += 1
|
||||||
|
return l
|
||||||
|
|
||||||
|
def test():
|
||||||
|
while True:
|
||||||
|
p = getPrimeNumber(64)
|
||||||
|
b = sqrt(p)
|
||||||
|
if b % 2 == 0.0:
|
||||||
|
break
|
||||||
|
print(p)
|
||||||
|
|
||||||
|
#test()
|
||||||
|
#exit(1)
|
||||||
|
p = 7901
|
||||||
|
q = 7817
|
||||||
|
#p = getPrimeNumber(64)
|
||||||
|
#q = get_closest_prime(p)[1]
|
||||||
|
p = 7943202761666983 # Works
|
||||||
|
q = 7943202761667119
|
||||||
|
#p = 314159200000000028138418196395985880850000485810513
|
||||||
|
#q = 314159200000000028138415196395985880850000485810479
|
||||||
|
print(f"p = {p}")
|
||||||
|
print(f"q = {q}")
|
||||||
|
n = p * q
|
||||||
|
print(f"n = {n}")
|
||||||
|
|
||||||
|
a = ceil(sqrt(n))
|
||||||
|
#print(a)
|
||||||
|
#print(sqrt(n))
|
||||||
|
#print(sqrt(n) < n) # True
|
||||||
|
#print(a * a)
|
||||||
|
#print(a * a < n)
|
||||||
|
#print()
|
||||||
|
#a = isqrt(n) + 1
|
||||||
|
iteration = 0
|
||||||
|
while True:
|
||||||
|
# b2 = (a ** 2) - n
|
||||||
|
iteration += 1
|
||||||
|
b2 = pow(a, 2) - n
|
||||||
|
#b2 = ceil(a*a) - n
|
||||||
|
# print(b2)
|
||||||
|
sqb2 = ceil(sqrt(b2))
|
||||||
|
# print(b2, isqrt(pow(b2, 2)))
|
||||||
|
if b2 % 2 == 0.0:
|
||||||
|
#if isqrt(pow(b2, 2)) == b2:
|
||||||
|
b = isqrt(b2)
|
||||||
|
break
|
||||||
|
a = a + 1
|
||||||
|
|
||||||
|
print(f"Iteration: {iteration}")
|
||||||
|
print(f"a = {a}")
|
||||||
|
print(f"b2 = {b2}")
|
||||||
|
print(f"b = {b}")
|
||||||
|
p = int((a + b))
|
||||||
|
q = int((a - b))
|
||||||
|
print(p)
|
||||||
|
print(q)
|
||||||
|
#N = (a + b) * (a - b)
|
||||||
|
N = p * q
|
||||||
|
print(_millerRabinTest(p))
|
||||||
|
print(_millerRabinTest(q))
|
||||||
|
print(f"N = {N}")
|
||||||
|
print(n == N)
|
||||||
|
print()
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.numbers import fibonacci
|
||||||
|
|
||||||
|
print(fibonacci(40))
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Groups.galois import Galois
|
||||||
|
import matplotlib.pyplot as plt # pip install numpy==1.26.4
|
||||||
|
|
||||||
|
|
||||||
|
def operation(a, b, n):
|
||||||
|
return (a ** b) % n
|
||||||
|
|
||||||
|
q = 13
|
||||||
|
g = Galois(q, operation)
|
||||||
|
add = g.add()
|
||||||
|
div = g.div()
|
||||||
|
mul = g.mul()
|
||||||
|
sub = g.sub()
|
||||||
|
g.check_closure_law('+')
|
||||||
|
g.check_closure_law('*')
|
||||||
|
g.check_closure_law('-')
|
||||||
|
g.check_closure_law('/')
|
||||||
|
|
||||||
|
print("Addition")
|
||||||
|
g.printMatrice(add)
|
||||||
|
print("Division")
|
||||||
|
g.printMatrice(div)
|
||||||
|
print("Multiplication")
|
||||||
|
g.printMatrice(mul)
|
||||||
|
print("Substraction")
|
||||||
|
g.printMatrice(sub)
|
||||||
|
|
||||||
|
|
||||||
|
print("Primitives root")
|
||||||
|
print(g.primitiveRoot(), end="\n\n")
|
||||||
|
|
||||||
|
#print("Identity elements")
|
||||||
|
g.check_identity_add()
|
||||||
|
g.check_identity_mul()
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Groups.group import Group
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
|
n = 18
|
||||||
|
def operation(e1, e2, n) -> int:
|
||||||
|
return e1 * e2 % n
|
||||||
|
|
||||||
|
# Generate the group G
|
||||||
|
g = list()
|
||||||
|
for i in range(1, n):
|
||||||
|
#if gcd(i, n) == 1:
|
||||||
|
g.append(i)
|
||||||
|
|
||||||
|
G = Group(n = n, g = g, ope=operation)
|
||||||
|
print(f"n = {n}")
|
||||||
|
print(f"G = {G.getG()}")
|
||||||
|
|
||||||
|
if G.closure() is False:
|
||||||
|
print("The closure law is not respected. It's not an abelian (commutative) group")
|
||||||
|
else:
|
||||||
|
print("It is a closure group")
|
||||||
|
|
||||||
|
if G.associative() is False:
|
||||||
|
print("The associative law is not respected. It's not a group")
|
||||||
|
else:
|
||||||
|
print("It is an associative group")
|
||||||
|
|
||||||
|
if G.identity() is False:
|
||||||
|
print("The group hasn't an identity element")
|
||||||
|
else:
|
||||||
|
print(f"Identity: {G.getIdentity()}")
|
||||||
|
|
||||||
|
if G.reverse() is False:
|
||||||
|
print(f"The group hasn't a reverse")
|
||||||
|
else:
|
||||||
|
print(f"Reverses: {G.getReverses()}")
|
||||||
|
|
||||||
|
#reverses = G.getReverses()
|
||||||
|
#plt.rcParams["figure.figsize"] = [7.00, 3.50]
|
||||||
|
#plt.rcParams["figure.autolayout"] = True
|
||||||
|
#for key, value in reverses.items():
|
||||||
|
# x = key
|
||||||
|
# y = value
|
||||||
|
# plt.plot(x, y, marker="o", markersize=2, markeredgecolor="blue")
|
||||||
|
# #plt.Circle((0, n), 0.2, color='r')
|
||||||
|
#
|
||||||
|
#plt.xlim(0, n)
|
||||||
|
#plt.ylim(0, n)
|
||||||
|
#plt.grid()
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from utils.primeNumber import primeNumber
|
||||||
|
|
||||||
|
print(primeNumber(19))
|
||||||
|
print(primeNumber(20))
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.primeNumber import get_n_prime_numbers
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
#import numpy as np
|
||||||
|
|
||||||
|
# Get list of n prime numbers
|
||||||
|
n = 100
|
||||||
|
primes = get_n_prime_numbers(n)
|
||||||
|
print(primes)
|
||||||
|
|
||||||
|
# With matplotlib, show into a graphics and try to explain that
|
||||||
|
plt.rcParams["figure.figsize"] = [7.00, 3.50]
|
||||||
|
plt.rcParams["figure.autolayout"] = True
|
||||||
|
for i in range(0, n):
|
||||||
|
x = primes[i]
|
||||||
|
y = primes[i]
|
||||||
|
plt.plot(x, y, marker="o", markersize=2, markeredgecolor="blue")
|
||||||
|
|
||||||
|
|
||||||
|
plt.xlim(0, n)
|
||||||
|
plt.ylim(0, n)
|
||||||
|
plt.grid()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.factorization import pollard_p_minus_1
|
||||||
|
from Cryptotools.Numbers.primeNumber import _millerRabinTest, getPrimeNumber
|
||||||
|
from sympy.ntheory.factor_ import pollard_pm1
|
||||||
|
from sympy import factorint
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def pollard(n):
|
||||||
|
p = pollard_p_minus_1(n, B=10)
|
||||||
|
if p is not None:
|
||||||
|
print(p, n / p)
|
||||||
|
print(pollard_pm1(n, B=10))
|
||||||
|
print()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def safePrime(p):
|
||||||
|
nP = 2 * p + 1
|
||||||
|
return _millerRabinTest(nP)
|
||||||
|
|
||||||
|
#pollard(299)
|
||||||
|
#pollard(257 * 1009)
|
||||||
|
#pollard(1684) # Doesn't works
|
||||||
|
|
||||||
|
# Test for RSA
|
||||||
|
#p = 281
|
||||||
|
while True:
|
||||||
|
while True:
|
||||||
|
p = getPrimeNumber(64)
|
||||||
|
if ((p - 1) / 2520) % 2 == 0.0:
|
||||||
|
#print(p)
|
||||||
|
break
|
||||||
|
#p = 322506219347091343
|
||||||
|
#q = 13953581789873249851
|
||||||
|
# n = p * q
|
||||||
|
while True:
|
||||||
|
q = getPrimeNumber(64)
|
||||||
|
if int(((q - 1) / 2520) % 2) == 1:
|
||||||
|
#print(q)
|
||||||
|
break
|
||||||
|
|
||||||
|
#q = 223
|
||||||
|
n = p * q
|
||||||
|
##print(n)
|
||||||
|
#print(pollard(n))
|
||||||
|
#break
|
||||||
|
if pollard(n): # We can factorize n
|
||||||
|
break
|
||||||
|
|
||||||
|
print(safePrime(p))
|
||||||
|
#print(safePrime(q))
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.primeNumber import getPrimeNumber, sophieGermainPrime
|
||||||
|
|
||||||
|
p = getPrimeNumber(512)
|
||||||
|
print(p)
|
||||||
|
if sophieGermainPrime(p):
|
||||||
|
print("It's a safe prime")
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.primeNumber import _millerRabinTest, _fermatLittleTheorem
|
||||||
|
from Cryptotools.Numbers.carmi import carmi_numbers, is_carmi_number, generate_carmi_numbers
|
||||||
|
|
||||||
|
print(_fermatLittleTheorem(1729))
|
||||||
|
print(_fermatLittleTheorem(1105))
|
||||||
|
print(_fermatLittleTheorem(6601))
|
||||||
|
print(_millerRabinTest(1729))
|
||||||
|
|
||||||
|
print(f"1729: {is_carmi_number(1729)}")
|
||||||
|
print(f"1105: {is_carmi_number(1105)}")
|
||||||
|
print(f"110: {is_carmi_number(110)}")
|
||||||
|
print(f"2465: {is_carmi_number(2465)}")
|
||||||
|
print(f"6601: {is_carmi_number(6601)}")
|
||||||
|
#print(carmi_numbers(1729))
|
||||||
|
print(generate_carmi_numbers(10))
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Encryptions.RSA import RSA
|
||||||
|
|
||||||
|
|
||||||
|
rsa = RSA()
|
||||||
|
rsa.generateKeys(size=512)
|
||||||
|
|
||||||
|
e = rsa.e
|
||||||
|
d = rsa.d
|
||||||
|
n = rsa.n
|
||||||
|
|
||||||
|
s = "I am encrypted with RSA"
|
||||||
|
print(f"plaintext: {s}")
|
||||||
|
encrypted = rsa.encrypt(s)
|
||||||
|
|
||||||
|
# Encrypt data
|
||||||
|
# print(f"ciphertext: {encrypted}")
|
||||||
|
|
||||||
|
# We decrypt
|
||||||
|
plaintext = rsa.decrypt(encrypted)
|
||||||
|
print(f"Plaintext: {plaintext}")
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.coprime import phi
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
|
||||||
|
def generate_keys():
|
||||||
|
p = 7853
|
||||||
|
q = 7919
|
||||||
|
n = p * q
|
||||||
|
e = 65536 # It's public value, must be coprime with phi n
|
||||||
|
|
||||||
|
print(n)
|
||||||
|
#phin = phi(n)
|
||||||
|
phin = (p - 1) * (q - 1)
|
||||||
|
print(phin)
|
||||||
|
|
||||||
|
for _ in range(2, phin):
|
||||||
|
if gcd(phin, e) == 1:
|
||||||
|
break
|
||||||
|
e += 1
|
||||||
|
|
||||||
|
print(e)
|
||||||
|
plaintext = 'A'
|
||||||
|
ciphertext = pow(ord(plaintext), e, n)
|
||||||
|
print(f"Ciphertext: {ciphertext}")
|
||||||
|
|
||||||
|
# Now, we can test
|
||||||
|
|
||||||
|
# To resolve that formula: C = x ** e mod n
|
||||||
|
# Where C is the ciphertext, and C, e and n are known (public values)
|
||||||
|
# First, we need to find the reverse modular of phi(n) or carmi(n)
|
||||||
|
# z = e -1 mod phi(n)
|
||||||
|
# After that, we have our decryption key, we can resolve x
|
||||||
|
# x = C ** z mod n
|
||||||
|
# The RSA Problem is to decrypt with the public-key
|
||||||
|
# We just need to find the decryption key with the public-key and the modulus
|
||||||
|
|
||||||
|
# First, we need to find phi(n)
|
||||||
|
# phin = phi(n) # I computed here, result = 62172136
|
||||||
|
|
||||||
|
n = 62187907
|
||||||
|
phin = 62172136
|
||||||
|
e = 65537
|
||||||
|
ciphertext = 38605768
|
||||||
|
# print(phin)
|
||||||
|
|
||||||
|
# Find the reverse modular
|
||||||
|
d = pow(e, -1, phin)
|
||||||
|
# print(d)
|
||||||
|
plaintext = pow(ciphertext, d, n)
|
||||||
|
print(chr(plaintext))
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.primeNumber import sieveOfEratosthenes
|
||||||
|
|
||||||
|
print(sieveOfEratosthenes(100))
|
||||||
|
print()
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
from Cryptotools.Utils.utils import gcd
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(1, 30):
|
||||||
|
if 30 % i == 0:
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
for i in range(1, 40):
|
||||||
|
if 40 % i == 0:
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
print(gcd(30, 40))
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
site_name: CryptoTools documentation
|
||||||
|
theme:
|
||||||
|
name: "readthedocs"
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- mkdocstrings
|
||||||
|
|
||||||
|
nav:
|
||||||
|
- Introduction: introduction.md
|
||||||
|
- Installation: installation.md
|
||||||
|
- Low-level cryptographic:
|
||||||
|
- Number theory: number-theory.md
|
||||||
|
- Group theory: group-theory.md
|
||||||
|
- Public Keys:
|
||||||
|
- RSA: rsa.md
|
||||||
|
- Examples:
|
||||||
|
- Generating RSA Keys: examples-rsa-keys.md
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[project]
|
||||||
|
name = "Cryptotools"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = [
|
||||||
|
{name = "gbucchino",email = "gbucchino@fortinet-us.com"}
|
||||||
|
]
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
sympy
|
||||||
|
mkdocs
|
||||||
|
mkdocstrings[python]
|
||||||
|
mkdocs-readthedocs
|
||||||
|
mkdocs-material
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
|
||||||
|
_version = "1.0"
|
||||||
|
_project_name = "Cryptotools"
|
||||||
|
|
||||||
|
_packages = [
|
||||||
|
"Numbers",
|
||||||
|
"Groups",
|
||||||
|
"Utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name=_project_name,
|
||||||
|
version=_version,
|
||||||
|
description="Cryptography library",
|
||||||
|
author="Geoffrey Bucchino",
|
||||||
|
author_email="contact@bucchino.org",
|
||||||
|
packages=find_packages(),
|
||||||
|
#packages=_packages,
|
||||||
|
#package_dir={"": "Cryptotools"}
|
||||||
|
)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Numbers.primeNumber import isPrimeNumber
|
||||||
|
|
||||||
|
def get_bases(n):
|
||||||
|
# Generate the n first prime numbers
|
||||||
|
bases = list()
|
||||||
|
i = 2
|
||||||
|
while (len(bases) < n):
|
||||||
|
if isPrimeNumber(i):
|
||||||
|
bases.append(i)
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
return bases
|
||||||
|
|
||||||
|
bases = get_bases(1000)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("(")
|
||||||
|
index = 0
|
||||||
|
for i in range(0, len(bases)):
|
||||||
|
if index == 10:
|
||||||
|
index = 0
|
||||||
|
print(f"\n", end="")
|
||||||
|
else:
|
||||||
|
print(f"{bases[i]}", end=",")
|
||||||
|
index = index + 1
|
||||||
|
print(")")
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="writer-html5" lang="en" >
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="/img/favicon.ico" />
|
||||||
|
<title>CryptoTools documentation</title>
|
||||||
|
<link rel="stylesheet" href="/css/theme.css" />
|
||||||
|
<link rel="stylesheet" href="/css/theme_extra.css" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css" />
|
||||||
|
<link href="/assets/_mkdocstrings.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="/js/html5shiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="wy-body-for-nav" role="document">
|
||||||
|
|
||||||
|
<div class="wy-grid-for-nav">
|
||||||
|
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||||
|
<div class="wy-side-scroll">
|
||||||
|
<div class="wy-side-nav-search">
|
||||||
|
<a href="/." class="icon icon-home"> CryptoTools documentation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="/introduction/">Introduction</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="/installation/">Installation</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Low-level cryptographic</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="/number-theory/">Number theory</a>
|
||||||
|
</li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="/group-theory/">Group theory</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Public Keys</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="/rsa/">RSA</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Examples</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="/examples-rsa-keys/">Generating RSA Keys</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||||
|
<nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu">
|
||||||
|
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||||
|
<a href="/.">CryptoTools documentation</a>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
<div class="wy-nav-content">
|
||||||
|
<div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation">
|
||||||
|
<ul class="wy-breadcrumbs">
|
||||||
|
<li><a href="/." class="icon icon-home" aria-label="Docs"></a></li>
|
||||||
|
<li class="wy-breadcrumbs-aside">
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||||
|
<div class="section" itemprop="articleBody">
|
||||||
|
|
||||||
|
|
||||||
|
<h1 id="404-page-not-found">404</h1>
|
||||||
|
|
||||||
|
<p><strong>Page not found</strong></p>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div><footer>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div role="contentinfo">
|
||||||
|
<!-- Copyright etc -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rst-versions" role="note" aria-label="Versions">
|
||||||
|
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<script src="/js/jquery-3.6.0.min.js"></script>
|
||||||
|
<script>var base_url = "/";</script>
|
||||||
|
<script src="/js/theme_extra.js"></script>
|
||||||
|
<script src="/js/theme.js"></script>
|
||||||
|
<script>
|
||||||
|
jQuery(function () {
|
||||||
|
SphinxRtdTheme.Navigation.enable(true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
/* Avoid breaking parameters name, etc. in table cells. */
|
||||||
|
.doc-contents td code {
|
||||||
|
word-break: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No line break before first paragraph of descriptions. */
|
||||||
|
.doc-md-description,
|
||||||
|
.doc-md-description>p:first-child {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Avoid breaking code headings. */
|
||||||
|
.doc-heading code {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Improve rendering of parameters, returns and exceptions. */
|
||||||
|
.doc-contents .field-name {
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Other curious-spacing fixes. */
|
||||||
|
.doc-contents .field-name,
|
||||||
|
.doc-contents .field-body {
|
||||||
|
border: none !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-contents p {
|
||||||
|
margin: 1em 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-contents .field-list {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-contents pre {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-contents .wy-table-responsive {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-contents td.code {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-contents td.linenos {
|
||||||
|
padding: 0 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-children,
|
||||||
|
footer {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* Wrap inline code samples otherwise they shoot of the side and
|
||||||
|
* can't be read at all.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/313
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/233
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/834
|
||||||
|
*/
|
||||||
|
.rst-content code {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make code blocks display as blocks and give them the appropriate
|
||||||
|
* font size and padding.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/855
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/834
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/233
|
||||||
|
*/
|
||||||
|
.rst-content pre code {
|
||||||
|
white-space: pre;
|
||||||
|
word-wrap: normal;
|
||||||
|
display: block;
|
||||||
|
padding: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix code colors
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/2027
|
||||||
|
*/
|
||||||
|
.rst-content code {
|
||||||
|
color: #E74C3C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rst-content pre code {
|
||||||
|
color: #000;
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix link colors when the link text is inline code.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/718
|
||||||
|
*/
|
||||||
|
a code {
|
||||||
|
color: #2980B9;
|
||||||
|
}
|
||||||
|
a:hover code {
|
||||||
|
color: #3091d1;
|
||||||
|
}
|
||||||
|
a:visited code {
|
||||||
|
color: #9B59B6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The CSS classes from highlight.js seem to clash with the
|
||||||
|
* ReadTheDocs theme causing some code to be incorrectly made
|
||||||
|
* bold and italic.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/411
|
||||||
|
*/
|
||||||
|
pre .cs, pre .c {
|
||||||
|
font-weight: inherit;
|
||||||
|
font-style: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix some issues with the theme and non-highlighted code
|
||||||
|
* samples. Without and highlighting styles attached the
|
||||||
|
* formatting is broken.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/319
|
||||||
|
*/
|
||||||
|
.rst-content .no-highlight {
|
||||||
|
display: block;
|
||||||
|
padding: 0.5em;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Additions specific to the search functionality provided by MkDocs
|
||||||
|
*/
|
||||||
|
|
||||||
|
.search-results {
|
||||||
|
margin-top: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-results article {
|
||||||
|
border-top: 1px solid #E1E4E5;
|
||||||
|
padding-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-results article:first-child {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
form .search-query {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-color: #D1D4D5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Improve inline code blocks within admonitions.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/656
|
||||||
|
*/
|
||||||
|
.rst-content .admonition code {
|
||||||
|
color: #404040;
|
||||||
|
border: 1px solid #c7c9cb;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
background: #f8fbfd;
|
||||||
|
background: rgba(255, 255, 255, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Account for wide tables which go off the side.
|
||||||
|
* Override borders to avoid weirdness on narrow tables.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/834
|
||||||
|
* https://github.com/mkdocs/mkdocs/pull/1034
|
||||||
|
*/
|
||||||
|
.rst-content .section .docutils {
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
display: block;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
td, th {
|
||||||
|
border: 1px solid #e1e4e5 !important;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Without the following amendments, the navigation in the theme will be
|
||||||
|
* slightly cut off. This is due to the fact that the .wy-nav-side has a
|
||||||
|
* padding-bottom of 2em, which must not necessarily align with the font-size of
|
||||||
|
* 90 % on the .rst-current-version container, combined with the padding of 12px
|
||||||
|
* above and below. These amendments fix this in two steps: First, make sure the
|
||||||
|
* .rst-current-version container has a fixed height of 40px, achieved using
|
||||||
|
* line-height, and then applying a padding-bottom of 40px to this container. In
|
||||||
|
* a second step, the items within that container are re-aligned using flexbox.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/2012
|
||||||
|
*/
|
||||||
|
.wy-nav-side {
|
||||||
|
padding-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For section-index only */
|
||||||
|
.wy-menu-vertical .current-section p {
|
||||||
|
background-color: #e3e3e3;
|
||||||
|
color: #404040;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The second step of above amendment: Here we make sure the items are aligned
|
||||||
|
* correctly within the .rst-current-version container. Using flexbox, we
|
||||||
|
* achieve it in such a way that it will look like the following:
|
||||||
|
*
|
||||||
|
* [No repo_name]
|
||||||
|
* Next >> // On the first page
|
||||||
|
* << Previous Next >> // On all subsequent pages
|
||||||
|
*
|
||||||
|
* [With repo_name]
|
||||||
|
* <repo_name> Next >> // On the first page
|
||||||
|
* <repo_name> << Previous Next >> // On all subsequent pages
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/2012
|
||||||
|
*/
|
||||||
|
.rst-versions .rst-current-version {
|
||||||
|
padding: 0 12px;
|
||||||
|
display: flex;
|
||||||
|
font-size: initial;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Please note that this amendment also involves removing certain inline-styles
|
||||||
|
* from the file ./mkdocs/themes/readthedocs/versions.html.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/2012
|
||||||
|
*/
|
||||||
|
.rst-current-version span {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="writer-html5" lang="en" >
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="../img/favicon.ico" />
|
||||||
|
<title>Generating RSA Keys - CryptoTools documentation</title>
|
||||||
|
<link rel="stylesheet" href="../css/theme.css" />
|
||||||
|
<link rel="stylesheet" href="../css/theme_extra.css" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css" />
|
||||||
|
<link href="../assets/_mkdocstrings.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Current page data
|
||||||
|
var mkdocs_page_name = "Generating RSA Keys";
|
||||||
|
var mkdocs_page_input_path = "examples-rsa-keys.md";
|
||||||
|
var mkdocs_page_url = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="../js/html5shiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="wy-body-for-nav" role="document">
|
||||||
|
|
||||||
|
<div class="wy-grid-for-nav">
|
||||||
|
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||||
|
<div class="wy-side-scroll">
|
||||||
|
<div class="wy-side-nav-search">
|
||||||
|
<a href=".." class="icon icon-home"> CryptoTools documentation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../introduction/">Introduction</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../installation/">Installation</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Low-level cryptographic</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../number-theory/">Number theory</a>
|
||||||
|
</li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../group-theory/">Group theory</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Public Keys</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../rsa/">RSA</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Examples</span></p>
|
||||||
|
<ul class="current">
|
||||||
|
<li class="toctree-l1 current"><a class="reference internal current" href="#">Generating RSA Keys</a>
|
||||||
|
<ul class="current">
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||||
|
<nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu">
|
||||||
|
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||||
|
<a href="..">CryptoTools documentation</a>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
<div class="wy-nav-content">
|
||||||
|
<div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation">
|
||||||
|
<ul class="wy-breadcrumbs">
|
||||||
|
<li><a href=".." class="icon icon-home" aria-label="Docs"></a></li>
|
||||||
|
<li class="breadcrumb-item">Examples</li>
|
||||||
|
<li class="breadcrumb-item active">Generating RSA Keys</li>
|
||||||
|
<li class="wy-breadcrumbs-aside">
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||||
|
<div class="section" itemprop="articleBody">
|
||||||
|
|
||||||
|
<h1 id="generating-rsa-keys">Generating RSA Keys</h1>
|
||||||
|
<p>In the following section, we are going to see how to generate RSA Keys and how to encrypt data with these keys.</p>
|
||||||
|
<pre><code>#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from Cryptotools.Encryptions.RSA import RSA
|
||||||
|
|
||||||
|
|
||||||
|
rsa = RSA()
|
||||||
|
rsa.generateKeys(size=512)
|
||||||
|
|
||||||
|
e = rsa.e
|
||||||
|
d = rsa.d
|
||||||
|
n = rsa.n
|
||||||
|
|
||||||
|
s = "I am encrypted with RSA"
|
||||||
|
print(f"plaintext: {s}")
|
||||||
|
encrypted = rsa.encrypt(s)
|
||||||
|
|
||||||
|
# Encrypt data
|
||||||
|
print(f"ciphertext: {encrypted}")
|
||||||
|
|
||||||
|
# We decrypt
|
||||||
|
plaintext = rsa.decrypt(encrypted)
|
||||||
|
print(f"Plaintext: {plaintext}")
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div><footer>
|
||||||
|
<div class="rst-footer-buttons" role="navigation" aria-label="Footer Navigation">
|
||||||
|
<a href="../rsa/" class="btn btn-neutral float-left" title="RSA"><span class="icon icon-circle-arrow-left"></span> Previous</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div role="contentinfo">
|
||||||
|
<!-- Copyright etc -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rst-versions" role="note" aria-label="Versions">
|
||||||
|
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||||
|
|
||||||
|
|
||||||
|
<span><a href="../rsa/" style="color: #fcfcfc">« Previous</a></span>
|
||||||
|
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<script src="../js/jquery-3.6.0.min.js"></script>
|
||||||
|
<script>var base_url = "..";</script>
|
||||||
|
<script src="../js/theme_extra.js"></script>
|
||||||
|
<script src="../js/theme.js"></script>
|
||||||
|
<script>
|
||||||
|
jQuery(function () {
|
||||||
|
SphinxRtdTheme.Navigation.enable(true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
+148
@@ -0,0 +1,148 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="writer-html5" lang="en" >
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="description" content="None" />
|
||||||
|
<link rel="shortcut icon" href="img/favicon.ico" />
|
||||||
|
<title>CryptoTools documentation</title>
|
||||||
|
<link rel="stylesheet" href="css/theme.css" />
|
||||||
|
<link rel="stylesheet" href="css/theme_extra.css" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css" />
|
||||||
|
<link href="assets/_mkdocstrings.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Current page data
|
||||||
|
var mkdocs_page_name = "Welcome to CryptoTools";
|
||||||
|
var mkdocs_page_input_path = "index.md";
|
||||||
|
var mkdocs_page_url = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="js/html5shiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="wy-body-for-nav" role="document">
|
||||||
|
|
||||||
|
<div class="wy-grid-for-nav">
|
||||||
|
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||||
|
<div class="wy-side-scroll">
|
||||||
|
<div class="wy-side-nav-search">
|
||||||
|
<a href="." class="icon icon-home"> CryptoTools documentation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="introduction/">Introduction</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="installation/">Installation</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Low-level cryptographic</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="number-theory/">Number theory</a>
|
||||||
|
</li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="group-theory/">Group theory</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Public Keys</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="rsa/">RSA</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Examples</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="examples-rsa-keys/">Generating RSA Keys</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||||
|
<nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu">
|
||||||
|
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||||
|
<a href=".">CryptoTools documentation</a>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
<div class="wy-nav-content">
|
||||||
|
<div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation">
|
||||||
|
<ul class="wy-breadcrumbs">
|
||||||
|
<li><a href="." class="icon icon-home" aria-label="Docs"></a></li>
|
||||||
|
<li class="breadcrumb-item active">Welcome to CryptoTools</li>
|
||||||
|
<li class="wy-breadcrumbs-aside">
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||||
|
<div class="section" itemprop="articleBody">
|
||||||
|
|
||||||
|
<h1 id="welcome-to-cryptotools">Welcome to CryptoTools</h1>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/introduction">Introduction</a></li>
|
||||||
|
<li><a href="/installation">Installation</a></li>
|
||||||
|
<li>Low-Level Cryptographic<ul>
|
||||||
|
<li><a href="/number-theory">Number Theory</a></li>
|
||||||
|
<li><a href="/group-theory">Group Theory</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Public Keys:<ul>
|
||||||
|
<li><a href="/rsa">RSA</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Examples:<ul>
|
||||||
|
<li><a href="/examples-rsa-keys">Generating RSA keys</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div><footer>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div role="contentinfo">
|
||||||
|
<!-- Copyright etc -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rst-versions" role="note" aria-label="Versions">
|
||||||
|
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<script src="js/jquery-3.6.0.min.js"></script>
|
||||||
|
<script>var base_url = ".";</script>
|
||||||
|
<script src="js/theme_extra.js"></script>
|
||||||
|
<script src="js/theme.js"></script>
|
||||||
|
<script>
|
||||||
|
jQuery(function () {
|
||||||
|
SphinxRtdTheme.Navigation.enable(true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
MkDocs version : 1.6.1
|
||||||
|
Build Date UTC : 2026-01-06 07:48:31.465035+00:00
|
||||||
|
-->
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="writer-html5" lang="en" >
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="../img/favicon.ico" />
|
||||||
|
<title>Installation - CryptoTools documentation</title>
|
||||||
|
<link rel="stylesheet" href="../css/theme.css" />
|
||||||
|
<link rel="stylesheet" href="../css/theme_extra.css" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css" />
|
||||||
|
<link href="../assets/_mkdocstrings.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Current page data
|
||||||
|
var mkdocs_page_name = "Installation";
|
||||||
|
var mkdocs_page_input_path = "installation.md";
|
||||||
|
var mkdocs_page_url = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="../js/html5shiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="wy-body-for-nav" role="document">
|
||||||
|
|
||||||
|
<div class="wy-grid-for-nav">
|
||||||
|
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||||
|
<div class="wy-side-scroll">
|
||||||
|
<div class="wy-side-nav-search">
|
||||||
|
<a href=".." class="icon icon-home"> CryptoTools documentation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../introduction/">Introduction</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="current">
|
||||||
|
<li class="toctree-l1 current"><a class="reference internal current" href="#">Installation</a>
|
||||||
|
<ul class="current">
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="#installation-from-source">Installation from source</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Low-level cryptographic</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../number-theory/">Number theory</a>
|
||||||
|
</li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../group-theory/">Group theory</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Public Keys</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../rsa/">RSA</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Examples</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../examples-rsa-keys/">Generating RSA Keys</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||||
|
<nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu">
|
||||||
|
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||||
|
<a href="..">CryptoTools documentation</a>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
<div class="wy-nav-content">
|
||||||
|
<div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation">
|
||||||
|
<ul class="wy-breadcrumbs">
|
||||||
|
<li><a href=".." class="icon icon-home" aria-label="Docs"></a></li>
|
||||||
|
<li class="breadcrumb-item active">Installation</li>
|
||||||
|
<li class="wy-breadcrumbs-aside">
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||||
|
<div class="section" itemprop="articleBody">
|
||||||
|
|
||||||
|
<h1 id="installation">Installation</h1>
|
||||||
|
<p>To install the project, you should install from my own Python repository but, you first need to deploy your virtual enviroment.</p>
|
||||||
|
<h2 id="installation-from-source">Installation from source</h2>
|
||||||
|
<p>You can install from the source. Download the <a href="https://gitea.bucchino.org/gbucchino/cryptotools.git">project</a> and install it in your virtual environment:</p>
|
||||||
|
<pre><code>$ virtualenv ~/venv/cryptotools
|
||||||
|
$ source ~/venv/cryptotools/bin/activate
|
||||||
|
</code></pre>
|
||||||
|
<pre><code>$ git clone https://gitea.bucchino.org/gbucchino/cryptotools.git
|
||||||
|
$ cd cryptotools
|
||||||
|
$ python3 setup.py install
|
||||||
|
</code></pre>
|
||||||
|
<p>The installation is completed. You can know use Cryptotools package into your project. In the directory <code>examples</code> you may find some examples scripts</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div><footer>
|
||||||
|
<div class="rst-footer-buttons" role="navigation" aria-label="Footer Navigation">
|
||||||
|
<a href="../introduction/" class="btn btn-neutral float-left" title="Introduction"><span class="icon icon-circle-arrow-left"></span> Previous</a>
|
||||||
|
<a href="../number-theory/" class="btn btn-neutral float-right" title="Number theory">Next <span class="icon icon-circle-arrow-right"></span></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div role="contentinfo">
|
||||||
|
<!-- Copyright etc -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rst-versions" role="note" aria-label="Versions">
|
||||||
|
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||||
|
|
||||||
|
|
||||||
|
<span><a href="../introduction/" style="color: #fcfcfc">« Previous</a></span>
|
||||||
|
|
||||||
|
|
||||||
|
<span><a href="../number-theory/" style="color: #fcfcfc">Next »</a></span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<script src="../js/jquery-3.6.0.min.js"></script>
|
||||||
|
<script>var base_url = "..";</script>
|
||||||
|
<script src="../js/theme_extra.js"></script>
|
||||||
|
<script src="../js/theme.js"></script>
|
||||||
|
<script>
|
||||||
|
jQuery(function () {
|
||||||
|
SphinxRtdTheme.Navigation.enable(true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="writer-html5" lang="en" >
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="../img/favicon.ico" />
|
||||||
|
<title>Introduction - CryptoTools documentation</title>
|
||||||
|
<link rel="stylesheet" href="../css/theme.css" />
|
||||||
|
<link rel="stylesheet" href="../css/theme_extra.css" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css" />
|
||||||
|
<link href="../assets/_mkdocstrings.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Current page data
|
||||||
|
var mkdocs_page_name = "Introduction";
|
||||||
|
var mkdocs_page_input_path = "introduction.md";
|
||||||
|
var mkdocs_page_url = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="../js/html5shiv.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
|
||||||
|
<script>hljs.highlightAll();</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="wy-body-for-nav" role="document">
|
||||||
|
|
||||||
|
<div class="wy-grid-for-nav">
|
||||||
|
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
|
||||||
|
<div class="wy-side-scroll">
|
||||||
|
<div class="wy-side-nav-search">
|
||||||
|
<a href=".." class="icon icon-home"> CryptoTools documentation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||||
|
<ul class="current">
|
||||||
|
<li class="toctree-l1 current"><a class="reference internal current" href="#">Introduction</a>
|
||||||
|
<ul class="current">
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../installation/">Installation</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Low-level cryptographic</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../number-theory/">Number theory</a>
|
||||||
|
</li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../group-theory/">Group theory</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Public Keys</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../rsa/">RSA</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p class="caption"><span class="caption-text">Examples</span></p>
|
||||||
|
<ul>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="../examples-rsa-keys/">Generating RSA Keys</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||||
|
<nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu">
|
||||||
|
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||||
|
<a href="..">CryptoTools documentation</a>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
<div class="wy-nav-content">
|
||||||
|
<div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation">
|
||||||
|
<ul class="wy-breadcrumbs">
|
||||||
|
<li><a href=".." class="icon icon-home" aria-label="Docs"></a></li>
|
||||||
|
<li class="breadcrumb-item active">Introduction</li>
|
||||||
|
<li class="wy-breadcrumbs-aside">
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||||
|
<div class="section" itemprop="articleBody">
|
||||||
|
|
||||||
|
<h1 id="cryptotools">CryptoTools</h1>
|
||||||
|
<p>CryptoTools is a Python package that provides low-level cryptographic primitives for generating strong numbers. With this project, it's possible to generate public key cryptosystems such as RSA.
|
||||||
|
This project has a academic purpose and can not be used in production enviroment yet.</p>
|
||||||
|
<p>So far, my cryptographic modules are not compliant with <a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-3.pdf">FIPS 140-3</a> but in the future, that will be.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div><footer>
|
||||||
|
<div class="rst-footer-buttons" role="navigation" aria-label="Footer Navigation">
|
||||||
|
<a href="../installation/" class="btn btn-neutral float-right" title="Installation">Next <span class="icon icon-circle-arrow-right"></span></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div role="contentinfo">
|
||||||
|
<!-- Copyright etc -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rst-versions" role="note" aria-label="Versions">
|
||||||
|
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<span><a href="../installation/" style="color: #fcfcfc">Next »</a></span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<script src="../js/jquery-3.6.0.min.js"></script>
|
||||||
|
<script>var base_url = "..";</script>
|
||||||
|
<script src="../js/theme_extra.js"></script>
|
||||||
|
<script src="../js/theme.js"></script>
|
||||||
|
<script>
|
||||||
|
jQuery(function () {
|
||||||
|
SphinxRtdTheme.Navigation.enable(true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||||
|
*/
|
||||||
|
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
|
||||||
Vendored
+2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* Assign 'docutils' class to tables so styling and
|
||||||
|
* JavaScript behavior is applied.
|
||||||
|
*
|
||||||
|
* https://github.com/mkdocs/mkdocs/issues/2028
|
||||||
|
*/
|
||||||
|
|
||||||
|
$('div.rst-content table').addClass('docutils');
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+1086
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
</urlset>
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
1, 1, 2, 2, 4, 2, 6, 2, 6, 4, 10, 2, 12, 6, 4, 4, 16, 6, 18, 4, 6, 10, 22, 2, 20, 12, 18, 6, 28, 4, 30, 8, 10, 16, 12, 6, 36, 18, 12, 4, 40, 6, 42, 10, 12, 22, 46, 4, 42, 20, 16, 12, 52, 18, 20, 6, 18, 28, 58, 4, 60, 30, 6, 16, 12, 10, 66, 16, 22, 12, 70, 6, 72, 36, 20, 18, 30, 12, 78, 4, 54
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341, 41041, 46657, 52633, 62745, 63973, 75361, 101101, 115921, 126217, 162401, 172081, 188461, 252601, 278545, 294409, 314821, 334153, 340561, 399001, 410041, 449065, 488881, 512461, 530881, 552721
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
source /home/geoffrey/venv/forensic/bin/activate;
|
||||||
|
for test in `ls tests/test_*.py`; do
|
||||||
|
echo $test;
|
||||||
|
python3 $test -v;
|
||||||
|
done
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user