cryptotools/Cryptotools/Numbers/factorization.py
2026-01-11 09:19:22 +01:00

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