#!/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