diff --git a/algo.py b/algo.py index 1b76bd8ee5cf305339fdbe8d5907300fd61cf88b..67f728b086d776dde4d78bb82c56c2a6fa88a290 100644 --- a/algo.py +++ b/algo.py @@ -1,4 +1,5 @@ import math +import random def bachet_bezout(a, b): """Does the Bachet-Bezout algorithm on a of b @@ -34,6 +35,7 @@ def bachet_bezout(a, b): return a, u[i-2], v[i-2] + def inverse_modulaire(a, n): """Does the inverse modular of a by n, using Bachet-Bezout @@ -47,6 +49,7 @@ def inverse_modulaire(a, n): return bachet_bezout(a, n)[1] + def exponentiation_rapide(a, exp, n): """Does the quick explanation of a pow x modulo n @@ -74,6 +77,7 @@ def exponentiation_rapide(a, exp, n): return int(r) + def is_square(a): """Check if a number is a perfect square, based on the "Babylonian algorithm" for square root, from : https://stackoverflow.com/questions/2489435/check-if-a-number-is-a-perfect-square @@ -98,6 +102,7 @@ def is_square(a): return True + def fermat_factorization(n): """Does the Fermat's factorization on n, n = a² - b² = (a + b) * (a - b) = p * q <=> b² = a² - n @@ -138,3 +143,89 @@ def decode_msg(M): """ return M.to_bytes((M.bit_length() + 7) // 8, "little").decode("utf-8") + + +def miller_rabin_test(d, n): + """Make the test of Miller Rabin (called for all k trials) + from : https://www.geeksforgeeks.org/primality-test-set-3-miller-rabin/ + + Args: + d (uint): the exponent d is an odd number such that d*2^r = n-1 for some r >= 1 + n (uint): the modulo + + Returns: + bool: False if n is composite, True if n is probably prime. + """ + + # Pick a random number in [2..n-2], corner cases make sure that n > 4 + a = 2 + random.randint(1, n - 4) + + # Compute a^d % n + x = exponentiation_rapide(a, d, n) + + if (x == 1 or x == n - 1): + return True + + # Keep squaring x while one of the following doesn't happen + # 1. d does not reach n-1 + # 2. (x^2) % n is not 1 + # 3. (x^2) % n is not n-1 + while (d != n - 1): + x = (x * x) % n + d *= 2 + + if (x == 1): + return False + if (x == n - 1): + return True + + return False # Return composite + + +def is_prime(n, k): + """Check if a number is prime using the test ofMiller Rabin. + from : https://www.geeksforgeeks.org/primality-test-set-3-miller-rabin/ + + Args: + n (uint): the value checked (n must be greater than 4) + k (uint): an input parameter that determines accuracy level, higher value of k indicates more accuracy. + + Returns: + bool: True if the number is probably prime, False if n is composite + """ + + # Corner cases + if (n <= 1 or n == 4): + return False + if (n <= 3): + return True + + # Find r such that n = 2^d * r + 1 for some r >= 1 + d = n - 1 + while (d % 2 == 0): + d //= 2 + + # Iterate given number of 'k' times + for i in range(k): + if (miller_rabin_test(d, n) == False): + return False + + return True + + +def get_prime_divider(n): + """Get the first prime divider of n, starting with the root of n going to 0 + + Args: + n (uint): number used + + Returns: + uint: the prime divider of n + """ + + for i in reversed(range(math.ceil(math.sqrt(n)))): + + if (n % i == 0 and is_prime(i, 4)): + return i + + return 1 \ No newline at end of file diff --git a/main.py b/main.py index a2927fb28f063bc12be37fe570348268b959fdd9..91f63a0b600bc7845921e96bec9caf4178d6463a 100644 --- a/main.py +++ b/main.py @@ -27,12 +27,16 @@ def main(): q = 0 # second prime number d = 0 # private key - #--- crack RSA --- + # --- crack RSA --- a, b = fermat_factorization(n) p = a + b q = a - b + # - second methode (sqrt(n) -> 0) - + # p = get_prime_divider(n) + # q = n // p + fi = (p - 1) * (q - 1) d = inverse_modulaire(e, fi) # get private key