Find the factorization of number N = p*q where p and q are prime to each other
| 6 | |
| 7 | |
| 8 | class Factoring: |
| 9 | """" |
| 10 | Find the factorization of number N = p*q |
| 11 | where p and q are prime to each other |
| 12 | """ |
| 13 | |
| 14 | def __init__(self, N): |
| 15 | self.N = N |
| 16 | |
| 17 | def factoring(self): |
| 18 | |
| 19 | prev_trials_for_a = [] |
| 20 | factored = False |
| 21 | |
| 22 | while not factored: |
| 23 | new_a_found = False |
| 24 | |
| 25 | # Sample a new "a" not already sampled |
| 26 | while not new_a_found: |
| 27 | a = np.random.randint(2, self.N) |
| 28 | if a not in prev_trials_for_a: |
| 29 | new_a_found = True |
| 30 | |
| 31 | # "a" not co-prime to N are not periodic |
| 32 | if euclid_gcd(self.N, a) == 1: |
| 33 | # Call the period_finding_routine from PeriodFinding |
| 34 | # Implementation |
| 35 | period = period_finding_routine(a=a, N=self.N) |
| 36 | |
| 37 | # Check if the period is even. |
| 38 | # It period even (a^(r/2))^2 = 1 mod (N) |
| 39 | # for integer a^(r/2) |
| 40 | if period % 2 == 0: |
| 41 | |
| 42 | # Check if a^(r/2) != +/- 1 mod(N) |
| 43 | # if condition satisfied number gets |
| 44 | # factorized in this iteration |
| 45 | if a ** (period / 2) % self.N not in [+1, -1]: |
| 46 | prime_1 = euclid_gcd(self.N, a ** (period / 2) + 1) |
| 47 | prime_2 = euclid_gcd(self.N, a ** (period / 2) - 1) |
| 48 | factored = True |
| 49 | return prime_1, prime_2 |
| 50 | else: |
| 51 | # If we have exhausted all "a"s and |
| 52 | # still havent got prime factors something |
| 53 | # is off |
| 54 | if len(prev_trials_for_a) == self.N - 2: |
| 55 | raise ValueError(f"Check input is a product of two primes") |
| 56 | |
| 57 | |
| 58 | if __name__ == '__main__': |