def rsa_recovery(dp, dq, ciphertext, keysize=1024, start=3): ''' This extensive process loops through all unknown e, typically between 3..65537 and given the dP and dQ will search for primes p and q, then attempt to decrypt the ciphertext that is known to have been encrypted with them. ''' # init counters r, p, q, d, count, count2, count3 = (0L, 0L, 0L, 0L, 0, 0, 0) # start generalised loop for an unknown e for j in range(start, 65538, 2): dp1 = long(gmpy2.mul(dp, j) - 1) for k in range(3, j): d = long(k) a, r = gmpy2.t_divmod(dp1, d) assert(dp1 == (k * a) + r) if r == 0: count += 1 p = long(a + 1) if gmpy2.is_odd(p) and gmpy2.is_strong_prp(p, 10): count2 += 1 dq1 = long(gmpy2.mul(dq, j) - 1) for l in range(3, j): d = long(l) a, r = gmpy2.t_divmod(dq1, d) assert(dq1 == (l * a) + r) if r == 0: q = long(a + 1) if gmpy2.is_odd(q) and gmpy2.is_strong_prp(q, 10): count3 += 1 # just some basic progress on the console if count3 % 10 == 0: sys.stdout.write('.') sys.stdout.flush() # only attempt the decrypt if p,q are expected bitlength if p.bit_length() + q.bit_length() == keysize: try: result = rsa_decrypt(p, q, ciphertext, j) if len(result) == 0 or result == "None": # indicates a failed decryption attempt sys.stdout.write('x') else: # SUCCESS! This is your decrypted message, sir... print "\n:: DECRYPTED::\n message = %s" % result # show all the p, q candidates just in case print "\np = %X\nq = %X\n" % (p, q) except Exception as e: print "ERROR: ", e # if cipher text length wrong, change decryption padding etc. pass # do nothing # finish with a counter summary print "count: %d count2: %d count3: %d\n\n" % (count, count2, count3)
def miller_rabin(n: int, iterations: int) -> bool: """Does Miller-Rabin checks on n with random bases.""" for i in range(iterations): base = _sys_rand.randrange(n) # gmpy2.is_strong_prp is the Miller-Rabin test if not is_strong_prp(n, base): return False return True
def isprime(n): """ Test if n is a prime number (True) or not (False). For n < 2^64 the answer is definitive; larger n values have a small probability of actually being pseudoprimes. Negative numbers (e.g. -2) are not considered prime. The first step is looking for trivial factors, which if found enables a quick return. Next, if the sieve is large enough, use bisection search on the sieve. For small numbers, a set of deterministic Miller-Rabin tests are performed with bases that are known to have no counterexamples in their range. Finally if the number is larger than 2^64, a strong BPSW test is performed. While this is a probable prime test and we believe counterexamples exist, there are no known counterexamples. Examples ======== >>> from sympy.ntheory import isprime >>> isprime(13) True >>> isprime(15) False See Also ======== sympy.ntheory.generate.primerange : Generates all primes in a given range sympy.ntheory.generate.primepi : Return the number of primes less than or equal to n sympy.ntheory.generate.prime : Return the nth prime References ========== - http://en.wikipedia.org/wiki/Strong_pseudoprime - "Lucas Pseudoprimes", Baillie and Wagstaff, 1980. http://mpqs.free.fr/LucasPseudoprimes.pdf - https://en.wikipedia.org/wiki/Baillie-PSW_primality_test """ if isinstance(n, (Float, float)): return False n = int(n) # Step 1, do quick composite testing via trial division. The individual # modulo tests benchmark faster than one or two primorial igcds for me. # The point here is just to speedily handle small numbers and many # composites. Step 2 only requires that n <= 2 get handled here. if n in [2, 3, 5]: return True if n < 2 or (n % 2) == 0 or (n % 3) == 0 or (n % 5) == 0: return False if n < 49: return True if (n % 7) == 0 or (n % 11) == 0 or (n % 13) == 0 or (n % 17) == 0 or \ (n % 19) == 0 or (n % 23) == 0 or (n % 29) == 0 or (n % 31) == 0 or \ (n % 37) == 0 or (n % 41) == 0 or (n % 43) == 0 or (n % 47) == 0: return False if n < 2809: return True if n <= 23001: return pow(2, n, n) == 2 and n not in [ 341, 561, 645, 1105, 1387, 1729, 1905, 2047, 2465, 2701, 2821, 3277, 4033, 4369, 4371, 4681, 5461, 6601, 7957, 8321, 8481, 8911, 10261, 10585, 11305, 12801, 13741, 13747, 13981, 14491, 15709, 15841, 16705, 18705, 18721, 19951, 23001 ] # bisection search on the sieve if the sieve is large enough from sympy.ntheory.generate import sieve as s if n <= s._list[-1]: l, u = s.search(n) return l == u # If we have GMPY2, skip straight to step 3 and do a strong BPSW test. # This should be a bit faster than our step 2, and for large values will # be a lot faster than our step 3 (C+GMP vs. Python). from sympy.core.compatibility import HAS_GMPY if HAS_GMPY == 2: from gmpy2 import is_strong_prp, is_strong_selfridge_prp return is_strong_prp(n, 2) and is_strong_selfridge_prp(n) # Step 2: deterministic Miller-Rabin testing for numbers < 2^64. See: # https://miller-rabin.appspot.com/ # for lists. We have made sure the M-R routine will successfully handle # bases larger than n, so we can use the minimal set. if n < 341531: return mr(n, [9345883071009581737]) if n < 885594169: return mr(n, [725270293939359937, 3569819667048198375]) if n < 350269456337: return mr( n, [4230279247111683200, 14694767155120705706, 16641139526367750375]) if n < 55245642489451: return mr( n, [2, 141889084524735, 1199124725622454117, 11096072698276303650]) if n < 7999252175582851: return mr(n, [ 2, 4130806001517, 149795463772692060, 186635894390467037, 3967304179347715805 ]) if n < 585226005592931977: return mr(n, [ 2, 123635709730000, 9233062284813009, 43835965440333360, 761179012939631437, 1263739024124850375 ]) if n < 18446744073709551616: return mr(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022]) # We could do this instead at any point: #if n < 18446744073709551616: # return mr(n, [2]) and is_extra_strong_lucas_prp(n) # Here are tests that are safe for MR routines that don't understand # large bases. #if n < 9080191: # return mr(n, [31, 73]) #if n < 19471033: # return mr(n, [2, 299417]) #if n < 38010307: # return mr(n, [2, 9332593]) #if n < 316349281: # return mr(n, [11000544, 31481107]) #if n < 4759123141: # return mr(n, [2, 7, 61]) #if n < 105936894253: # return mr(n, [2, 1005905886, 1340600841]) #if n < 31858317218647: # return mr(n, [2, 642735, 553174392, 3046413974]) #if n < 3071837692357849: # return mr(n, [2, 75088, 642735, 203659041, 3613982119]) #if n < 18446744073709551616: # return mr(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022]) # Step 3: BPSW. # # Time for isprime(10**2000 + 4561), no gmpy or gmpy2 installed # 44.0s old isprime using 46 bases # 5.3s strong BPSW + one random base # 4.3s extra strong BPSW + one random base # 4.1s strong BPSW # 3.2s extra strong BPSW # Classic BPSW from page 1401 of the paper. See alternate ideas below. return mr(n, [2]) and is_strong_lucas_prp(n)
def isprime(n): """ Test if n is a prime number (True) or not (False). For n < 2^64 the answer is definitive; larger n values have a small probability of actually being pseudoprimes. Negative numbers (e.g. -2) are not considered prime. The first step is looking for trivial factors, which if found enables a quick return. Next, if the sieve is large enough, use bisection search on the sieve. For small numbers, a set of deterministic Miller-Rabin tests are performed with bases that are known to have no counterexamples in their range. Finally if the number is larger than 2^64, a strong BPSW test is performed. While this is a probable prime test and we believe counterexamples exist, there are no known counterexamples. Examples ======== >>> from sympy.ntheory import isprime >>> isprime(13) True >>> isprime(13.0) # limited precision False >>> isprime(15) False Notes ===== This routine is intended only for integer input, not numerical expressions which may represent numbers. Floats are also rejected as input because they represent numbers of limited precision. While it is tempting to permit 7.0 to represent an integer there are errors that may "pass silently" if this is allowed: >>> from sympy import Float, S >>> int(1e3) == 1e3 == 10**3 True >>> int(1e23) == 1e23 True >>> int(1e23) == 10**23 False >>> near_int = 1 + S(1)/10**19 >>> near_int == int(near_int) False >>> n = Float(near_int, 10) # truncated by precision >>> n == int(n) True >>> n = Float(near_int, 20) >>> n == int(n) False See Also ======== sympy.ntheory.generate.primerange : Generates all primes in a given range sympy.ntheory.generate.primepi : Return the number of primes less than or equal to n sympy.ntheory.generate.prime : Return the nth prime References ========== - https://en.wikipedia.org/wiki/Strong_pseudoprime - "Lucas Pseudoprimes", Baillie and Wagstaff, 1980. http://mpqs.free.fr/LucasPseudoprimes.pdf - https://en.wikipedia.org/wiki/Baillie-PSW_primality_test """ try: n = as_int(n) except ValueError: return False # Step 1, do quick composite testing via trial division. The individual # modulo tests benchmark faster than one or two primorial igcds for me. # The point here is just to speedily handle small numbers and many # composites. Step 2 only requires that n <= 2 get handled here. if n in [2, 3, 5]: return True if n < 2 or (n % 2) == 0 or (n % 3) == 0 or (n % 5) == 0: return False if n < 49: return True if (n % 7) == 0 or (n % 11) == 0 or (n % 13) == 0 or (n % 17) == 0 or \ (n % 19) == 0 or (n % 23) == 0 or (n % 29) == 0 or (n % 31) == 0 or \ (n % 37) == 0 or (n % 41) == 0 or (n % 43) == 0 or (n % 47) == 0: return False if n < 2809: return True if n <= 23001: return pow(2, n, n) == 2 and n not in [7957, 8321, 13747, 18721, 19951] # bisection search on the sieve if the sieve is large enough from sympy.ntheory.generate import sieve as s if n <= s._list[-1]: l, u = s.search(n) return l == u # If we have GMPY2, skip straight to step 3 and do a strong BPSW test. # This should be a bit faster than our step 2, and for large values will # be a lot faster than our step 3 (C+GMP vs. Python). from sympy.core.compatibility import HAS_GMPY if HAS_GMPY == 2: from gmpy2 import is_strong_prp, is_strong_selfridge_prp return is_strong_prp(n, 2) and is_strong_selfridge_prp(n) # Step 2: deterministic Miller-Rabin testing for numbers < 2^64. See: # https://miller-rabin.appspot.com/ # for lists. We have made sure the M-R routine will successfully handle # bases larger than n, so we can use the minimal set. if n < 341531: return mr(n, [9345883071009581737]) if n < 885594169: return mr(n, [725270293939359937, 3569819667048198375]) if n < 350269456337: return mr(n, [4230279247111683200, 14694767155120705706, 16641139526367750375]) if n < 55245642489451: return mr(n, [2, 141889084524735, 1199124725622454117, 11096072698276303650]) if n < 7999252175582851: return mr(n, [2, 4130806001517, 149795463772692060, 186635894390467037, 3967304179347715805]) if n < 585226005592931977: return mr(n, [2, 123635709730000, 9233062284813009, 43835965440333360, 761179012939631437, 1263739024124850375]) if n < 18446744073709551616: return mr(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022]) # We could do this instead at any point: #if n < 18446744073709551616: # return mr(n, [2]) and is_extra_strong_lucas_prp(n) # Here are tests that are safe for MR routines that don't understand # large bases. #if n < 9080191: # return mr(n, [31, 73]) #if n < 19471033: # return mr(n, [2, 299417]) #if n < 38010307: # return mr(n, [2, 9332593]) #if n < 316349281: # return mr(n, [11000544, 31481107]) #if n < 4759123141: # return mr(n, [2, 7, 61]) #if n < 105936894253: # return mr(n, [2, 1005905886, 1340600841]) #if n < 31858317218647: # return mr(n, [2, 642735, 553174392, 3046413974]) #if n < 3071837692357849: # return mr(n, [2, 75088, 642735, 203659041, 3613982119]) #if n < 18446744073709551616: # return mr(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022]) # Step 3: BPSW. # # Time for isprime(10**2000 + 4561), no gmpy or gmpy2 installed # 44.0s old isprime using 46 bases # 5.3s strong BPSW + one random base # 4.3s extra strong BPSW + one random base # 4.1s strong BPSW # 3.2s extra strong BPSW # Classic BPSW from page 1401 of the paper. See alternate ideas below. return mr(n, [2]) and is_strong_lucas_prp(n)
def sprp(n, a, s=None, d=None): return is_strong_prp(n, a) def jacobi(a, p):
def is_probable_prime(p): return is_strong_prp(p, 2)
def crypto_prime(num): i = 2 for x in range(64): # 2^(-128) false if not gmpy2.is_strong_prp(num, i): return False i = gmpy2.next_prime(i) return True