57 lines
1.4 KiB
Python
57 lines
1.4 KiB
Python
#!/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
|