First commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
#!/usr/bin/env python3
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from Cryptotools.Numbers.primeNumber import gcd, isPrimeNumber
|
||||
from Cryptotools.lcm import lcm
|
||||
from Cryptotools.Numbers.coprime import phi
|
||||
from Cryptotools.Utils.utils import gcd
|
||||
from sympy import factorint
|
||||
from functools import reduce
|
||||
|
||||
|
||||
def carmichael_lambda(n: int) -> int:
|
||||
"""
|
||||
This function is a carmichael lambda for identifying the smallest integer m
|
||||
and saisfy this condition: a ** m congrue 1 modulo n
|
||||
This function is relatively closed with the euler's totient (phi of n)
|
||||
|
||||
Args:
|
||||
n (Integer): found the smallest integer of n
|
||||
|
||||
Returns:
|
||||
REturn the smallest integer of n
|
||||
"""
|
||||
|
||||
# First, factorizing n number
|
||||
# factorint return a list of prime factors of n
|
||||
# Base on that theorem:
|
||||
# https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic
|
||||
factorsN = factorint(n)
|
||||
|
||||
"""
|
||||
The result of the factorint, we have the following:
|
||||
n = p ** e1, p ** e2, ..., p ** ek
|
||||
"""
|
||||
|
||||
factors = list()
|
||||
|
||||
for p, e in factorsN.items():
|
||||
# Base on the theorem of arithmetic, p is always prime
|
||||
if isPrimeNumber(p):
|
||||
if p == 2 and e >= 3:
|
||||
factors.append(phi(pow(p, e)) // 2)
|
||||
elif p >= 2 and e > 0:
|
||||
factors.append(phi(pow(p, e)))
|
||||
elif p > 2:
|
||||
factors.append(phi(pow(p, e)))
|
||||
|
||||
# Now, we can compute lcm
|
||||
result = reduce(lcm, factors)
|
||||
|
||||
return result
|
||||
|
||||
def carmichael_lambda2(n):
|
||||
"""
|
||||
Deprecated function
|
||||
"""
|
||||
# Get all coprimes with n
|
||||
coprimes = list()
|
||||
for a in range(1, n):
|
||||
if gcd(a, n) == 1:
|
||||
coprimes.append(a)
|
||||
|
||||
# Need to find the smallest value
|
||||
"""
|
||||
Need to find the smallest value m. Must to satisfy this condition:
|
||||
a ** m congrus 1 mod n
|
||||
"""
|
||||
for m in range(1, n):
|
||||
print(f"{m} {a ** m % n}")
|
||||
|
||||
print(coprimes)
|
||||
|
||||
def carmi_numbers(n):
|
||||
"""
|
||||
This function get all GCD of the number if these number are prime or not
|
||||
|
||||
Args:
|
||||
n (Integer): Iterate to n elements
|
||||
|
||||
Returns:
|
||||
Return a list of prime numbers
|
||||
"""
|
||||
# https://kconrad.math.uconn.edu/blurbs/ugradnumthy/carmichaelkorselt.pdf
|
||||
primes = list()
|
||||
for i in range(2, n - 1):
|
||||
if gcd(n, i) == i:
|
||||
if isPrimeNumber(i):
|
||||
primes.append(i)
|
||||
|
||||
return primes
|
||||
|
||||
def is_carmichael(n, primes):
|
||||
"""
|
||||
This function check if the n number is a carmichael number. The arguments primes at least 3 prime numbers
|
||||
As it's said in the Carmichael theorem, a carmichael number has three factors and they are all primes: https://en.wikipedia.org/wiki/Carmichael_number
|
||||
With the Korselt's criterion, to check if the number is a carmichael number p - 1 / n - 1.
|
||||
|
||||
Args:
|
||||
n (Integer): the carmichael number
|
||||
primes (list): list of prime numbers
|
||||
|
||||
Returns:
|
||||
Boolean of the carmichael's number result
|
||||
"""
|
||||
r = True
|
||||
n = n - 1
|
||||
|
||||
if len(primes) < 3:
|
||||
return False
|
||||
|
||||
# Korselt's criterion
|
||||
for p in primes:
|
||||
p = p - 1
|
||||
if n % p != 0:
|
||||
r = False
|
||||
break
|
||||
return r
|
||||
|
||||
def is_carmi_number(n) -> bool:
|
||||
"""
|
||||
This function check if the number n is a carmichael number (pseudoprime)
|
||||
|
||||
Args:
|
||||
n (Integer): Iterate to n elements
|
||||
|
||||
Returns:
|
||||
Return a Boolean if n is a carmichael number or not. True if yes
|
||||
"""
|
||||
j = 0
|
||||
for i in range(n):
|
||||
if i ** n % n == i:
|
||||
j += 1
|
||||
if j == n:
|
||||
return True
|
||||
return False
|
||||
|
||||
def generate_carmi_numbers(nbr) -> list:
|
||||
"""
|
||||
This function generate carmichael numbers, they are called pseudoprimes
|
||||
For instance: a = 545, n = 561
|
||||
gcd(a, n) = 1
|
||||
pow(a, n - 1) % n = 1
|
||||
|
||||
Args:
|
||||
nbr (Integer): Find all pseudoprimes until nbr is achieves
|
||||
|
||||
Returns:
|
||||
Return the list of pseudoprimes
|
||||
"""
|
||||
carmi = list()
|
||||
|
||||
count = 0
|
||||
n = 2
|
||||
while count < nbr:
|
||||
# First, we need to find a, coprime with n
|
||||
for a in range(1, n):
|
||||
# We check if n is coprime with a
|
||||
# All integers must be coprime with n, a belong to n
|
||||
if gcd(a, n) == 1:
|
||||
# Check if is a carmichael number
|
||||
# Fermat's little theorem, a ** (n - 1) % n, must be congruent to 1
|
||||
if pow(a, (n - 1)) % n == 1:
|
||||
#if (a ** (n - 1)) % n == 1:
|
||||
#print(f"{gcd(a, n)} {a} {n}")
|
||||
if n not in carmi:
|
||||
count += 1
|
||||
carmi.append(n)
|
||||
else:
|
||||
print(f"{gcd(a, n)} {a} {n}")
|
||||
|
||||
break
|
||||
n += 1
|
||||
print(carmi)
|
||||
#for cop in range(2, n):
|
||||
# if gcd(cop, n) == 1:
|
||||
# coprimes.append(cop)
|
||||
|
||||
return carmi
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from Cryptotools.Utils.utils import gcd
|
||||
|
||||
|
||||
# https://oeis.org/A000010
|
||||
def phi(n):
|
||||
"""
|
||||
This function count all phi(n)
|
||||
|
||||
Args:
|
||||
n (integer): it's the phi(n) value
|
||||
|
||||
Returns:
|
||||
Return the phi(n)
|
||||
"""
|
||||
y = 1
|
||||
for i in range(2, n):
|
||||
if gcd(n, i) == 1:
|
||||
y += 1
|
||||
return y
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from random import randint
|
||||
from Cryptotools.Numbers.primeNumber import _millerRabinTest, isPrimeNumber
|
||||
from Cryptotools.Utils.utils import gcd
|
||||
from Cryptotools.lcm import lcm
|
||||
from math import floor, log
|
||||
|
||||
|
||||
def pollard_p_minus_1(n, B=None) -> int:
|
||||
"""
|
||||
This function factorize the number n into factor based on the Pollard's p - 1 algorithm
|
||||
|
||||
The first is to choose B, which is a positive integer and B < n
|
||||
In the second step, we need to define $M=\prod _{primes~q\leq B}q^{\lfloor \log_{q}{B}\rfloor }$
|
||||
|
||||
Args:
|
||||
n (Integer): The number n to factorize
|
||||
|
||||
Returns:
|
||||
Return the factorize of the number n or None
|
||||
"""
|
||||
|
||||
if B is None:
|
||||
B = randint(1, n - 1)
|
||||
# B = randint(1, n - 1)
|
||||
|
||||
#### We define M
|
||||
# Select all prime numbers 1 < B
|
||||
q = list()
|
||||
for x in range(2, B):
|
||||
# with the _millerRabinTest, the program crash, because the randint() is empty
|
||||
# because, both min value and max value are 2
|
||||
# if _millerRabinTest(x):
|
||||
if isPrimeNumber(x):
|
||||
q.append(x)
|
||||
|
||||
M = 1
|
||||
for prime in q:
|
||||
e = floor(log(B, prime))
|
||||
# print(prime, e)
|
||||
M *= pow(prime, e)
|
||||
|
||||
# We choose a and coprime with n
|
||||
a = 2
|
||||
while True:
|
||||
if gcd(a, n) == 1:
|
||||
break
|
||||
a += 1
|
||||
|
||||
# We can compute g = gcd((a ** M) - 1, n)
|
||||
g = gcd(pow(a, M, n) - 1, n)
|
||||
if g > 1:
|
||||
return g
|
||||
|
||||
return None
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
def fibonacci(n) -> list:
|
||||
"""
|
||||
This function generate the list of Fibonacci
|
||||
|
||||
Args:
|
||||
n (integer): it's maximum value of Fibonacci sequence
|
||||
|
||||
Returns:
|
||||
Return a list of n element in the Fibonacci sequence
|
||||
"""
|
||||
fibo = [0, 1]
|
||||
fibo.append(fibo[0] + fibo[1])
|
||||
for i in range(2, n):
|
||||
fibo.append(fibo[i - 1] + fibo[i])
|
||||
return fibo
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from random import randint, seed, getrandbits
|
||||
from math import log2
|
||||
from Cryptotools.Utils.utils import gcd
|
||||
|
||||
|
||||
def isPrimeNumber(p):
|
||||
"""
|
||||
Check if the number p is a prime number or not. The function iterate until p is achieve.
|
||||
|
||||
This function is not the efficient way to determine if p is prime or a composite.
|
||||
|
||||
To identify if p is prime or not, the function check the result of the Euclidean Division has a remainder. If yes, it's means it's not a prime number
|
||||
|
||||
Args:
|
||||
p (Integer): number if possible prime or not
|
||||
|
||||
Returns:
|
||||
Return a boolean if the number p is a prime number or not. True if yes
|
||||
"""
|
||||
for i in range(2, p):
|
||||
if p % i == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
# https://people.csail.mit.edu/rivest/Rsapaper.pdf
|
||||
# https://arxiv.org/pdf/1912.11546
|
||||
# https://link.springer.com/content/pdf/10.1007/3-540-44499-8_27.pdf
|
||||
# https://link.springer.com/article/10.1007/BF00202269
|
||||
# https://www.geeksforgeeks.org/dsa/how-to-generate-large-prime-numbers-for-rsa-algorithm/
|
||||
# https://crypto.stackexchange.com/questions/20548/generation-of-strong-primes
|
||||
# https://crypto.stackexchange.com/questions/71/how-can-i-generate-large-prime-numbers-for-rsa
|
||||
|
||||
def getPrimeNumber(n, safe=True):
|
||||
"""
|
||||
This function generate a large prime number
|
||||
based on "A method for Obtaining Digital Signatures
|
||||
and Public-Key Cryptosystems"
|
||||
Section B. How to Find Large Prime Numbers
|
||||
https://dl.acm.org/doi/pdf/10.1145/359340.359342
|
||||
|
||||
Args:
|
||||
n (Integer): The size of the prime number. Must be a multiple of 64
|
||||
safe (Boolean): When generating the prime number, the function must find a safe prime number, based on the Germain primes (2p + 1 is also a prime number)
|
||||
|
||||
Returns:
|
||||
Return the prime number
|
||||
"""
|
||||
if n % 64 != 0:
|
||||
print("Must be multiple of 64")
|
||||
return
|
||||
# from sys import getsizeof
|
||||
upper = getrandbits(n)
|
||||
lower = upper >> 7
|
||||
r = randint(lower, upper)
|
||||
|
||||
while r % 2 == 0:
|
||||
r += 1
|
||||
|
||||
# Now, we are going to compute r as prime number
|
||||
i = 100
|
||||
while 1:
|
||||
# Check if it's a prime number
|
||||
if _millerRabinTest(r):
|
||||
break
|
||||
|
||||
# TODO: it's dirty, need to change that
|
||||
# i = int(log2(r))
|
||||
# i *= randint(2, 50)
|
||||
|
||||
r += i
|
||||
# print(f"{i} {r}")
|
||||
i += 1
|
||||
|
||||
|
||||
# print(_fermatLittleTheorem(r))
|
||||
# print(getsizeof(r))
|
||||
return r
|
||||
|
||||
def getSmallPrimeNumber(n) -> int:
|
||||
"""
|
||||
This function is deprecated
|
||||
|
||||
Args:
|
||||
n (Integer): Get the small prime number until n
|
||||
|
||||
Returns:
|
||||
Return the first prime number found
|
||||
"""
|
||||
is_prime = True
|
||||
|
||||
while True:
|
||||
for i in range(2, n):
|
||||
# If n is divisible by i, it's not a prime, we break the loop
|
||||
if n % i == 0:
|
||||
is_prime = False
|
||||
break
|
||||
|
||||
if is_prime:
|
||||
break
|
||||
is_prime = True
|
||||
n = n + 1
|
||||
|
||||
p = n
|
||||
return p
|
||||
|
||||
def get_prime_numbers(n) -> list:
|
||||
"""
|
||||
This function get all prime number of the n
|
||||
|
||||
Args:
|
||||
n (Integer): find all prime number until n is achieves
|
||||
|
||||
Returns:
|
||||
Return a list of prime numbers
|
||||
"""
|
||||
l = list()
|
||||
for i in range(2, n):
|
||||
if n % i == 0:
|
||||
l.append(i)
|
||||
return l
|
||||
|
||||
def get_n_prime_numbers(n) -> list:
|
||||
"""
|
||||
This function return a list of n prime numbers
|
||||
|
||||
Args:
|
||||
n (Integer): the range, must be an integer
|
||||
|
||||
Returns:
|
||||
Return a list of n prime numbers
|
||||
"""
|
||||
l = list()
|
||||
|
||||
count = 2
|
||||
index = 0
|
||||
while index < n:
|
||||
is_prime = True
|
||||
for x in range(2, count):
|
||||
if count % x == 0:
|
||||
is_prime = False
|
||||
break
|
||||
|
||||
if is_prime:
|
||||
l.append(count)
|
||||
index += 1
|
||||
|
||||
count += 1
|
||||
|
||||
return l
|
||||
|
||||
def are_coprime(p1, p2):
|
||||
"""
|
||||
This function check if p1 and p2 are coprime
|
||||
|
||||
Args:
|
||||
p1 (list): list of prime numbers of the first number
|
||||
p2 (list): list of prime number of the second number
|
||||
|
||||
Returns:
|
||||
Return a boolean result
|
||||
"""
|
||||
r = True
|
||||
for entry in p1:
|
||||
if entry in p2:
|
||||
r = False
|
||||
break
|
||||
return r
|
||||
|
||||
def sieveOfEratosthenes(n) -> list:
|
||||
"""
|
||||
This function build a list of prime number based on the Sieve of Erastosthenes
|
||||
|
||||
Args:
|
||||
n (Integer): Interate until n is achives
|
||||
|
||||
Returns:
|
||||
Return a list of all prime numbers to n
|
||||
"""
|
||||
if n < 1:
|
||||
return list()
|
||||
|
||||
eratost = dict()
|
||||
for i in range(2, n):
|
||||
eratost[i] = True
|
||||
|
||||
for i in range(2, n):
|
||||
if eratost[i]:
|
||||
for j in range(i*i, n, i):
|
||||
eratost[j] = False
|
||||
|
||||
sieve = list()
|
||||
for i in range(2, n):
|
||||
if eratost[i]:
|
||||
sieve.append(i)
|
||||
|
||||
return sieve
|
||||
|
||||
def _fermatLittleTheorem(n) -> bool:
|
||||
"""
|
||||
The Fermat's little theorem. if n is a prime number, any number from 0 to n- 1 is a multiple of n
|
||||
|
||||
Args:
|
||||
n (Integer): Check if n is prime or not
|
||||
|
||||
Returns:
|
||||
Return True if the number a is a multiple of n, otherwise it's False
|
||||
"""
|
||||
a = randint(1, n - 1)
|
||||
# We compute a ** (n - 1) % n
|
||||
if pow(a, n - 1, n) == 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _millerRabinTest(n) -> bool:
|
||||
"""
|
||||
This function execute a Miller Rabin test
|
||||
For the algorithm, it's based on the pseudo-algo provided by this document:
|
||||
* https://www.cs.cornell.edu/courses/cs4820/2010sp/handouts/MillerRabin.pdf
|
||||
The Mille-Rabin test is an efficient way to determine if n is prime or not
|
||||
|
||||
Args:
|
||||
n (Integer): Check if n is a prime number
|
||||
Returns:
|
||||
Return a boolean. True for a prime otherwise, it's a composite number
|
||||
|
||||
"""
|
||||
if n < 2 or (n > 2 and n % 2 == 0): # If n is even, it's a composite
|
||||
return False
|
||||
|
||||
k = 0
|
||||
q = n - 1
|
||||
#while (q & 1) == 0:
|
||||
# k += 1
|
||||
# q >>= 1
|
||||
while q % 2 == 0:
|
||||
k += 1
|
||||
q //= 2
|
||||
|
||||
# We choose a: a < n - 1
|
||||
for _ in range(40):
|
||||
a = randint(2, n - 1)
|
||||
# We compute a ** q % n
|
||||
x = pow(a, q, n)
|
||||
|
||||
# If it's a composite number
|
||||
if x == 1 or x == n - 1:
|
||||
continue
|
||||
|
||||
for _ in range(k):
|
||||
z = pow(x, 2, n)
|
||||
if z == 1 or z == n - 1:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
def sophieGermainPrime(p) -> bool:
|
||||
"""
|
||||
Check if the number p is a safe prime number: 2p + 1 is also a prime
|
||||
|
||||
Args:
|
||||
p (Integer): Possible prime number
|
||||
|
||||
Returns:
|
||||
Return True if p is a safe prime number, otherwise it's False
|
||||
"""
|
||||
pp = 2 * p + 1
|
||||
return _millerRabinTest(pp)
|
||||
|
||||
def isSafePrime(n) -> bool:
|
||||
"""
|
||||
This function has not been implemented yet, but check if the number n is a safe prime number. This function will test different properties of the possible prime number n
|
||||
|
||||
Args:
|
||||
n (Integer): the prime number to check
|
||||
|
||||
Returns:
|
||||
Return a Boolean if the prime number n is safe or not. True if yes, otherwise it's False
|
||||
"""
|
||||
if n.bit_length() >= 256:
|
||||
return True
|
||||
|
||||
# Do Sophie Germain's test
|
||||
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user