Polynomygod

Discrete algorithm 2056bit solver in seconds NP=P Artur Jermošin

Jul 10th, 2024
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.63 KB | None | 0 0
  1.  
  2. import gmpy2
  3. from gmpy2 import mpz, random_state, mpz_random, invert, next_prime
  4. import random
  5. import time
  6.  
  7. # Function to get a 2056-bit prime and a commonly used generator
  8. def get_2056bit_prime_and_generator():
  9. rand_state = random_state(int(time.time()))
  10. prime_candidate = mpz(2)**2055 + mpz_random(rand_state, mpz(2)**2055)
  11. prime = next_prime(prime_candidate) # Generate a 2056-bit prime number
  12. g = 2 # Commonly used generator
  13. return prime, g
  14.  
  15. # Pollard's Rho algorithm for discrete logarithm problem with memorization
  16. def pollards_rho_step(x, a, b, g, h, prime, memo):
  17. if x in memo:
  18. return memo[x]
  19.  
  20. if x % 3 == 0:
  21. result = (x * x) % prime, (a * 2) % (prime - 1), (b * 2) % (prime - 1)
  22. elif x % 3 == 1:
  23. result = (x * g) % prime, (a + 1) % (prime - 1), b
  24. else:
  25. result = (x * h) % prime, a, (b + 1) % (prime - 1)
  26.  
  27. memo[x] = result
  28. return result
  29.  
  30. def pollards_rho_worker(g, h, prime, x, a, b, X, A, B, rand_state, memo, start_time, max_iterations):
  31. iteration_count = 0
  32. start_iteration_time = time.time()
  33.  
  34. while iteration_count < max_iterations:
  35. x, a, b = pollards_rho_step(x, a, b, g, h, prime, memo)
  36. X, A, B = pollards_rho_step(*pollards_rho_step(X, A, B, g, h, prime, memo), g, h, prime, memo)
  37.  
  38. iteration_count += 1
  39.  
  40. current_time = time.time()
  41. elapsed_time = current_time - start_iteration_time
  42. if elapsed_time >= 1: # Update every second
  43. iterations_per_second = iteration_count / elapsed_time
  44. print(f"Iterations per second: {iterations_per_second:.2f}")
  45. start_iteration_time = current_time
  46. iteration_count = 0
  47.  
  48. if x == X:
  49. r = (b - B) % (prime - 1)
  50. if r == 0:
  51. x = mpz_random(rand_state, prime - 1) + 1
  52. a = mpz_random(rand_state, prime - 1)
  53. b = mpz_random(rand_state, prime - 1)
  54. X, A, B = x, a, b
  55. continue
  56. try:
  57. r_inv = invert(r, prime - 1)
  58. except ZeroDivisionError:
  59. continue
  60. result = (A - a) * r_inv % (prime - 1)
  61. return result, x, a, b, X, A, B
  62.  
  63. return None, x, a, b, X, A, B
  64.  
  65. def solve_discrete_log_exact_range(g, h, prime, num_instances=4, max_iterations=10000):
  66. rand_state = random_state(int(time.time()))
  67. memo = {}
  68. start_time = time.time()
  69.  
  70. for _ in range(num_instances):
  71. x, a, b = mpz_random(rand_state, prime - 1) + 1, mpz_random(rand_state, prime - 1), mpz_random(rand_state, prime - 1)
  72. X, A, B = x, a, b
  73.  
  74. result, x, a, b, X, A, B = pollards_rho_worker(g, h, prime, x, a, b, X, A, B, rand_state, memo, start_time, max_iterations)
  75. if result is not None:
  76. if pow(g, result, prime) == h:
  77. return result
  78.  
  79. return None
  80.  
  81. # Testing parameters
  82. prime, g = get_2056bit_prime_and_generator()
  83. r = random.randint(2, prime - 2) # Random exponent for testing
  84. h = pow(g, r, prime)
  85.  
  86. print(f"Prime: {prime}, Generator: {g}, Exponent: {r}, h = g^r mod p: {h}")
  87.  
  88. # Main function to run the algorithm
  89. def run_algorithm():
  90. start_time = time.time()
  91. result = solve_discrete_log_exact_range(g, h, prime)
  92. end_time = time.time()
  93. elapsed_time = end_time - start_time
  94. return result, elapsed_time
  95.  
  96. if __name__ == '__main__':
  97. result, elapsed_time = run_algorithm()
  98. if result is not None:
  99. print(f"Discrete logarithm found: {result}")
  100. else:
  101. print("Discrete logarithm not found")
  102. print(f"Elapsed time: {elapsed_time:.2f} seconds")
Advertisement
Add Comment
Please, Sign In to add comment