First commit
This commit is contained in:
commit
50f7b1159e
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
__pycache__/
|
||||
build/**
|
||||
Cryptotools.egg-info/**
|
||||
dist/**
|
||||
**.swp
|
||||
6
Cryptotools/Cryptotools.egg-info/PKG-INFO
Normal file
6
Cryptotools/Cryptotools.egg-info/PKG-INFO
Normal file
@ -0,0 +1,6 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: Cryptotools
|
||||
Version: 1.0
|
||||
Summary: Cryptography library
|
||||
Author: Geoffrey Bucchino
|
||||
Author-email: contact@bucchino.org
|
||||
13
Cryptotools/Cryptotools.egg-info/SOURCES.txt
Normal file
13
Cryptotools/Cryptotools.egg-info/SOURCES.txt
Normal file
@ -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
|
||||
1
Cryptotools/Cryptotools.egg-info/dependency_links.txt
Normal file
1
Cryptotools/Cryptotools.egg-info/dependency_links.txt
Normal file
@ -0,0 +1 @@
|
||||
|
||||
1
Cryptotools/Cryptotools.egg-info/top_level.txt
Normal file
1
Cryptotools/Cryptotools.egg-info/top_level.txt
Normal file
@ -0,0 +1 @@
|
||||
Numbers
|
||||
174
Cryptotools/Encryptions/RSA.py
Normal file
174
Cryptotools/Encryptions/RSA.py
Normal file
@ -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
|
||||
1
Cryptotools/Encryptions/__init__.py
Normal file
1
Cryptotools/Encryptions/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
#!/usr/bin/env python3
|
||||
1
Cryptotools/Groups/__init__.py
Normal file
1
Cryptotools/Groups/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
#!/usr/bin/env python3
|
||||
91
Cryptotools/Groups/cyclic.py
Normal file
91
Cryptotools/Groups/cyclic.py
Normal file
@ -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
|
||||
227
Cryptotools/Groups/galois.py
Normal file
227
Cryptotools/Groups/galois.py
Normal file
@ -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)
|
||||
124
Cryptotools/Groups/group.py
Normal file
124
Cryptotools/Groups/group.py
Normal file
@ -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
|
||||
1
Cryptotools/Numbers/__init__.py
Normal file
1
Cryptotools/Numbers/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
#!/usr/bin/env python3
|
||||
BIN
Cryptotools/Numbers/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
Cryptotools/Numbers/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
Cryptotools/Numbers/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
Cryptotools/Numbers/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
Cryptotools/Numbers/__pycache__/carmi.cpython-310.pyc
Normal file
BIN
Cryptotools/Numbers/__pycache__/carmi.cpython-310.pyc
Normal file
Binary file not shown.
BIN
Cryptotools/Numbers/__pycache__/carmi.cpython-39.pyc
Normal file
BIN
Cryptotools/Numbers/__pycache__/carmi.cpython-39.pyc
Normal file
Binary file not shown.
177
Cryptotools/Numbers/carmi.py
Normal file
177
Cryptotools/Numbers/carmi.py
Normal file
@ -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
|
||||
22
Cryptotools/Numbers/coprime.py
Normal file
22
Cryptotools/Numbers/coprime.py
Normal file
@ -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
|
||||
|
||||
56
Cryptotools/Numbers/factorization.py
Normal file
56
Cryptotools/Numbers/factorization.py
Normal file
@ -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
|
||||
19
Cryptotools/Numbers/numbers.py
Normal file
19
Cryptotools/Numbers/numbers.py
Normal file
@ -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
|
||||
|
||||
288
Cryptotools/Numbers/primeNumber.py
Normal file
288
Cryptotools/Numbers/primeNumber.py
Normal file
@ -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
|
||||
|
||||
1
Cryptotools/Utils/__init__.py
Normal file
1
Cryptotools/Utils/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
#!/usr/bin/env python3
|
||||
9
Cryptotools/Utils/number.py
Normal file
9
Cryptotools/Utils/number.py
Normal file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
COMPOSITE = 0
|
||||
PRIME = 1
|
||||
|
||||
class Number:
|
||||
def __init__(self):
|
||||
self._int = int()
|
||||
self._kind = COMPOSITE
|
||||
34
Cryptotools/Utils/utils.py
Normal file
34
Cryptotools/Utils/utils.py
Normal file
@ -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
|
||||
|
||||
3
Cryptotools/__init__.py
Normal file
3
Cryptotools/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
__all__ = ["Numbers", "Groups"]
|
||||
33
Cryptotools/lcm.py
Normal file
33
Cryptotools/lcm.py
Normal file
@ -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
|
||||
|
||||
31
README.md
Normal file
31
README.md
Normal file
@ -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
|
||||
```
|
||||
27
docs/examples-rsa-keys.md
Normal file
27
docs/examples-rsa-keys.md
Normal file
@ -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}")
|
||||
```
|
||||
9
docs/group-theory.md
Normal file
9
docs/group-theory.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Group Theory
|
||||
## Group
|
||||
::: Cryptotools.Groups.group
|
||||
|
||||
## Cyclic group
|
||||
::: Cryptotools.Groups.cyclic
|
||||
|
||||
## Galois Field (Finite Field)
|
||||
::: Cryptotools.Groups.galois
|
||||
13
docs/index.md
Normal file
13
docs/index.md
Normal file
@ -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)
|
||||
|
||||
|
||||
18
docs/installation.md
Normal file
18
docs/installation.md
Normal file
@ -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
|
||||
5
docs/introduction.md
Normal file
5
docs/introduction.md
Normal file
@ -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.
|
||||
9
docs/number-theory.md
Normal file
9
docs/number-theory.md
Normal file
@ -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
|
||||
|
||||
3
docs/rsa.md
Normal file
3
docs/rsa.md
Normal file
@ -0,0 +1,3 @@
|
||||
CryptoTools provides several functions for generating a RSA Keys
|
||||
|
||||
::: Cryptotools.Encryptions.RSA
|
||||
32
examples/carmi.py
Normal file
32
examples/carmi.py
Normal file
@ -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)}")
|
||||
23
examples/coprime.py
Normal file
23
examples/coprime.py
Normal file
@ -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)}")
|
||||
41
examples/cyclic.py
Normal file
41
examples/cyclic.py
Normal file
@ -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")
|
||||
64
examples/cyclic_dlp.py
Normal file
64
examples/cyclic_dlp.py
Normal file
@ -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)}")
|
||||
32
examples/cyclic_generator.py
Normal file
32
examples/cyclic_generator.py
Normal file
@ -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}")
|
||||
49
examples/cyclic_subgroup.py
Normal file
49
examples/cyclic_subgroup.py
Normal file
@ -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}")
|
||||
73
examples/cyclic_test.py
Normal file
73
examples/cyclic_test.py
Normal file
@ -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)
|
||||
74
examples/dh_cyclic.py
Normal file
74
examples/dh_cyclic.py
Normal file
@ -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}")
|
||||
116
examples/dh_no_generator.py
Normal file
116
examples/dh_no_generator.py
Normal file
@ -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)
|
||||
80
examples/fermat_factorization.py
Normal file
80
examples/fermat_factorization.py
Normal file
@ -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()
|
||||
|
||||
5
examples/fibonacci.py
Normal file
5
examples/fibonacci.py
Normal file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from Cryptotools.Numbers.numbers import fibonacci
|
||||
|
||||
print(fibonacci(40))
|
||||
36
examples/galois.py
Normal file
36
examples/galois.py
Normal file
@ -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()
|
||||
55
examples/group.py
Normal file
55
examples/group.py
Normal file
@ -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()
|
||||
|
||||
6
examples/main.py
Normal file
6
examples/main.py
Normal file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from utils.primeNumber import primeNumber
|
||||
|
||||
print(primeNumber(19))
|
||||
print(primeNumber(20))
|
||||
25
examples/plotlib.py
Normal file
25
examples/plotlib.py
Normal file
@ -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()
|
||||
|
||||
53
examples/pollard.py
Normal file
53
examples/pollard.py
Normal file
@ -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))
|
||||
8
examples/prime.py
Normal file
8
examples/prime.py
Normal file
@ -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")
|
||||
17
examples/pseudoprimes.py
Normal file
17
examples/pseudoprimes.py
Normal file
@ -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))
|
||||
22
examples/rsa.py
Normal file
22
examples/rsa.py
Normal file
@ -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}")
|
||||
52
examples/rsa_problem.py
Normal file
52
examples/rsa_problem.py
Normal file
@ -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))
|
||||
|
||||
6
examples/sieveOfEratosthenes.py
Normal file
6
examples/sieveOfEratosthenes.py
Normal file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from Cryptotools.Numbers.primeNumber import sieveOfEratosthenes
|
||||
|
||||
print(sieveOfEratosthenes(100))
|
||||
print()
|
||||
15
examples/test_gcd.py
Normal file
15
examples/test_gcd.py
Normal file
@ -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
mkdocs.yml
Normal file
17
mkdocs.yml
Normal file
@ -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
|
||||
16
pyproject.toml
Normal file
16
pyproject.toml
Normal file
@ -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"
|
||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@ -0,0 +1,5 @@
|
||||
sympy
|
||||
mkdocs
|
||||
mkdocstrings[python]
|
||||
mkdocs-readthedocs
|
||||
mkdocs-material
|
||||
22
setup.py
Normal file
22
setup.py
Normal file
@ -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"}
|
||||
)
|
||||
29
sieves_base.py
Normal file
29
sieves_base.py
Normal file
@ -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
site/404.html
Normal file
122
site/404.html
Normal file
@ -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>
|
||||
57
site/assets/_mkdocstrings.css
Normal file
57
site/assets/_mkdocstrings.css
Normal file
@ -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;
|
||||
}
|
||||
BIN
site/css/fonts/Roboto-Slab-Bold.woff
Normal file
BIN
site/css/fonts/Roboto-Slab-Bold.woff
Normal file
Binary file not shown.
BIN
site/css/fonts/Roboto-Slab-Bold.woff2
Normal file
BIN
site/css/fonts/Roboto-Slab-Bold.woff2
Normal file
Binary file not shown.
BIN
site/css/fonts/Roboto-Slab-Regular.woff
Normal file
BIN
site/css/fonts/Roboto-Slab-Regular.woff
Normal file
Binary file not shown.
BIN
site/css/fonts/Roboto-Slab-Regular.woff2
Normal file
BIN
site/css/fonts/Roboto-Slab-Regular.woff2
Normal file
Binary file not shown.
BIN
site/css/fonts/fontawesome-webfont.eot
Normal file
BIN
site/css/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
2671
site/css/fonts/fontawesome-webfont.svg
Normal file
2671
site/css/fonts/fontawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 434 KiB |
BIN
site/css/fonts/fontawesome-webfont.ttf
Normal file
BIN
site/css/fonts/fontawesome-webfont.ttf
Normal file
Binary file not shown.
BIN
site/css/fonts/fontawesome-webfont.woff
Normal file
BIN
site/css/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
site/css/fonts/fontawesome-webfont.woff2
Normal file
BIN
site/css/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-bold-italic.woff
Normal file
BIN
site/css/fonts/lato-bold-italic.woff
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-bold-italic.woff2
Normal file
BIN
site/css/fonts/lato-bold-italic.woff2
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-bold.woff
Normal file
BIN
site/css/fonts/lato-bold.woff
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-bold.woff2
Normal file
BIN
site/css/fonts/lato-bold.woff2
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-normal-italic.woff
Normal file
BIN
site/css/fonts/lato-normal-italic.woff
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-normal-italic.woff2
Normal file
BIN
site/css/fonts/lato-normal-italic.woff2
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-normal.woff
Normal file
BIN
site/css/fonts/lato-normal.woff
Normal file
Binary file not shown.
BIN
site/css/fonts/lato-normal.woff2
Normal file
BIN
site/css/fonts/lato-normal.woff2
Normal file
Binary file not shown.
13
site/css/theme.css
Normal file
13
site/css/theme.css
Normal file
File diff suppressed because one or more lines are too long
197
site/css/theme_extra.css
Normal file
197
site/css/theme_extra.css
Normal file
@ -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;
|
||||
}
|
||||
158
site/examples-rsa-keys/index.html
Normal file
158
site/examples-rsa-keys/index.html
Normal file
@ -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>
|
||||
3059
site/group-theory/index.html
Normal file
3059
site/group-theory/index.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
site/img/favicon.ico
Normal file
BIN
site/img/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
148
site/index.html
Normal file
148
site/index.html
Normal file
@ -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
|
||||
-->
|
||||
149
site/installation/index.html
Normal file
149
site/installation/index.html
Normal file
@ -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>
|
||||
136
site/introduction/index.html
Normal file
136
site/introduction/index.html
Normal file
@ -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>
|
||||
4
site/js/html5shiv.min.js
vendored
Normal file
4
site/js/html5shiv.min.js
vendored
Normal file
@ -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);
|
||||
2
site/js/jquery-3.6.0.min.js
vendored
Normal file
2
site/js/jquery-3.6.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
site/js/theme.js
Normal file
2
site/js/theme.js
Normal file
File diff suppressed because one or more lines are too long
8
site/js/theme_extra.js
Normal file
8
site/js/theme_extra.js
Normal file
@ -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');
|
||||
1380
site/number-theory/index.html
Normal file
1380
site/number-theory/index.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
site/objects.inv
Normal file
BIN
site/objects.inv
Normal file
Binary file not shown.
1086
site/rsa/index.html
Normal file
1086
site/rsa/index.html
Normal file
File diff suppressed because it is too large
Load Diff
3
site/sitemap.xml
Normal file
3
site/sitemap.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
</urlset>
|
||||
BIN
site/sitemap.xml.gz
Normal file
BIN
site/sitemap.xml.gz
Normal file
Binary file not shown.
1
tests/carmi_function_oeis
Normal file
1
tests/carmi_function_oeis
Normal file
@ -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
|
||||
1
tests/carmi_numbers_oeis
Normal file
1
tests/carmi_numbers_oeis
Normal file
@ -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
|
||||
8
tests/execute_tests.py
Executable file
8
tests/execute_tests.py
Executable file
@ -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
Loading…
Reference in New Issue
Block a user