c = 30691232452128669052305371115180097177294479938026014749161868515829428425138132603996202260560122315012913870349336288842909273354993573489869530575104380833275595193605165300908452032408792329246901352615423312079849067596198536334364108820925409520915833013632159139929170333544966895214174663797058473253 p = 10271280551288472856987510413460997884890943068375125000031548270778287320402104925104706174892136963176424819840044521307032212563934575625497632478103881 q = 12360589907705437261666506204292999164487703125392652130810029273222342650377968792952840678684622841895717217508994994151976676085089006546199016112674981 e = 65537
N = p * q phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, N)
from Crypto.Util.number import isPrime from gmpy2 import gcd from random import randrange
deffactorize_multi_prime(N, phi): """ Recovers the prime factors from a modulus if Euler's totient is known. This method works for a modulus consisting of any number of primes, but is considerably be slower than factorize. More information: Hinek M. J., Low M. K., Teske E., "On Some Attacks on Multi-prime RSA" (Section 3) :param N: the modulus :param phi: Euler's totient, the order of the multiplicative group modulo N :return: a tuple containing the prime factors """ prime_factors = set() factors = [N] whilelen(factors) > 0: # Element to factorize. N = factors[0]
w = randrange(2, N - 1) i = 1 while phi % (2 ** i) == 0: sqrt_1 = pow(w, phi // (2 ** i), N) if sqrt_1 > 1and sqrt_1 != N - 1: # We can remove the element to factorize now, because we have a factorization. factors = factors[1:]
p = gcd(N, sqrt_1 + 1) q = N // p
if isPrime(p): prime_factors.add(p) elif p > 1: factors.append(p)
if isPrime(q): prime_factors.add(q) elif q > 1: factors.append(q)
# Continue in the outer loop break
i += 1
returntuple(prime_factors)
primes = []
N = ... phiN = ...
for i in (factorize_multi_prime(N,phiN)): primes.append(int(i))