Primality.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. # ===================================================================
  2. #
  3. # Copyright (c) 2014, Legrandin <helderijs@gmail.com>
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. #
  10. # 1. Redistributions of source code must retain the above copyright
  11. # notice, this list of conditions and the following disclaimer.
  12. # 2. Redistributions in binary form must reproduce the above copyright
  13. # notice, this list of conditions and the following disclaimer in
  14. # the documentation and/or other materials provided with the
  15. # distribution.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  27. # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. # POSSIBILITY OF SUCH DAMAGE.
  29. # ===================================================================
  30. """Functions to create and test prime numbers.
  31. :undocumented: __package__
  32. """
  33. from Cryptodome import Random
  34. from Cryptodome.Math.Numbers import Integer
  35. from Cryptodome.Util.py3compat import iter_range
  36. COMPOSITE = 0
  37. PROBABLY_PRIME = 1
  38. def miller_rabin_test(candidate, iterations, randfunc=None):
  39. """Perform a Miller-Rabin primality test on an integer.
  40. The test is specified in Section C.3.1 of `FIPS PUB 186-4`__.
  41. :Parameters:
  42. candidate : integer
  43. The number to test for primality.
  44. iterations : integer
  45. The maximum number of iterations to perform before
  46. declaring a candidate a probable prime.
  47. randfunc : callable
  48. An RNG function where bases are taken from.
  49. :Returns:
  50. ``Primality.COMPOSITE`` or ``Primality.PROBABLY_PRIME``.
  51. .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
  52. """
  53. if not isinstance(candidate, Integer):
  54. candidate = Integer(candidate)
  55. if candidate in (1, 2, 3, 5):
  56. return PROBABLY_PRIME
  57. if candidate.is_even():
  58. return COMPOSITE
  59. one = Integer(1)
  60. minus_one = Integer(candidate - 1)
  61. if randfunc is None:
  62. randfunc = Random.new().read
  63. # Step 1 and 2
  64. m = Integer(minus_one)
  65. a = 0
  66. while m.is_even():
  67. m >>= 1
  68. a += 1
  69. # Skip step 3
  70. # Step 4
  71. for i in iter_range(iterations):
  72. # Step 4.1-2
  73. base = 1
  74. while base in (one, minus_one):
  75. base = Integer.random_range(min_inclusive=2,
  76. max_inclusive=candidate - 2,
  77. randfunc=randfunc)
  78. assert(2 <= base <= candidate - 2)
  79. # Step 4.3-4.4
  80. z = pow(base, m, candidate)
  81. if z in (one, minus_one):
  82. continue
  83. # Step 4.5
  84. for j in iter_range(1, a):
  85. z = pow(z, 2, candidate)
  86. if z == minus_one:
  87. break
  88. if z == one:
  89. return COMPOSITE
  90. else:
  91. return COMPOSITE
  92. # Step 5
  93. return PROBABLY_PRIME
  94. def lucas_test(candidate):
  95. """Perform a Lucas primality test on an integer.
  96. The test is specified in Section C.3.3 of `FIPS PUB 186-4`__.
  97. :Parameters:
  98. candidate : integer
  99. The number to test for primality.
  100. :Returns:
  101. ``Primality.COMPOSITE`` or ``Primality.PROBABLY_PRIME``.
  102. .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
  103. """
  104. if not isinstance(candidate, Integer):
  105. candidate = Integer(candidate)
  106. # Step 1
  107. if candidate in (1, 2, 3, 5):
  108. return PROBABLY_PRIME
  109. if candidate.is_even() or candidate.is_perfect_square():
  110. return COMPOSITE
  111. # Step 2
  112. def alternate():
  113. value = 5
  114. while True:
  115. yield value
  116. if value > 0:
  117. value += 2
  118. else:
  119. value -= 2
  120. value = -value
  121. for D in alternate():
  122. if candidate in (D, -D):
  123. continue
  124. js = Integer.jacobi_symbol(D, candidate)
  125. if js == 0:
  126. return COMPOSITE
  127. if js == -1:
  128. break
  129. # Found D. P=1 and Q=(1-D)/4 (note that Q is guaranteed to be an integer)
  130. # Step 3
  131. # This is \delta(n) = n - jacobi(D/n)
  132. K = candidate + 1
  133. # Step 4
  134. r = K.size_in_bits() - 1
  135. # Step 5
  136. # U_1=1 and V_1=P
  137. U_i = Integer(1)
  138. V_i = Integer(1)
  139. U_temp = Integer(0)
  140. V_temp = Integer(0)
  141. # Step 6
  142. for i in iter_range(r - 1, -1, -1):
  143. # Square
  144. # U_temp = U_i * V_i % candidate
  145. U_temp.set(U_i)
  146. U_temp *= V_i
  147. U_temp %= candidate
  148. # V_temp = (((V_i ** 2 + (U_i ** 2 * D)) * K) >> 1) % candidate
  149. V_temp.set(U_i)
  150. V_temp *= U_i
  151. V_temp *= D
  152. V_temp.multiply_accumulate(V_i, V_i)
  153. if V_temp.is_odd():
  154. V_temp += candidate
  155. V_temp >>= 1
  156. V_temp %= candidate
  157. # Multiply
  158. if K.get_bit(i):
  159. # U_i = (((U_temp + V_temp) * K) >> 1) % candidate
  160. U_i.set(U_temp)
  161. U_i += V_temp
  162. if U_i.is_odd():
  163. U_i += candidate
  164. U_i >>= 1
  165. U_i %= candidate
  166. # V_i = (((V_temp + U_temp * D) * K) >> 1) % candidate
  167. V_i.set(V_temp)
  168. V_i.multiply_accumulate(U_temp, D)
  169. if V_i.is_odd():
  170. V_i += candidate
  171. V_i >>= 1
  172. V_i %= candidate
  173. else:
  174. U_i.set(U_temp)
  175. V_i.set(V_temp)
  176. # Step 7
  177. if U_i == 0:
  178. return PROBABLY_PRIME
  179. return COMPOSITE
  180. from Cryptodome.Util.number import sieve_base as _sieve_base_large
  181. ## The optimal number of small primes to use for the sieve
  182. ## is probably dependent on the platform and the candidate size
  183. _sieve_base = set(_sieve_base_large[:100])
  184. def test_probable_prime(candidate, randfunc=None):
  185. """Test if a number is prime.
  186. A number is qualified as prime if it passes a certain
  187. number of Miller-Rabin tests (dependent on the size
  188. of the number, but such that probability of a false
  189. positive is less than 10^-30) and a single Lucas test.
  190. For instance, a 1024-bit candidate will need to pass
  191. 4 Miller-Rabin tests.
  192. :Parameters:
  193. candidate : integer
  194. The number to test for primality.
  195. randfunc : callable
  196. The routine to draw random bytes from to select Miller-Rabin bases.
  197. :Returns:
  198. ``PROBABLE_PRIME`` if the number if prime with very high probability.
  199. ``COMPOSITE`` if the number is a composite.
  200. For efficiency reasons, ``COMPOSITE`` is also returned for small primes.
  201. """
  202. if randfunc is None:
  203. randfunc = Random.new().read
  204. if not isinstance(candidate, Integer):
  205. candidate = Integer(candidate)
  206. # First, check trial division by the smallest primes
  207. if int(candidate) in _sieve_base:
  208. return PROBABLY_PRIME
  209. try:
  210. map(candidate.fail_if_divisible_by, _sieve_base)
  211. except ValueError:
  212. return COMPOSITE
  213. # These are the number of Miller-Rabin iterations s.t. p(k, t) < 1E-30,
  214. # with p(k, t) being the probability that a randomly chosen k-bit number
  215. # is composite but still survives t MR iterations.
  216. mr_ranges = ((220, 30), (280, 20), (390, 15), (512, 10),
  217. (620, 7), (740, 6), (890, 5), (1200, 4),
  218. (1700, 3), (3700, 2))
  219. bit_size = candidate.size_in_bits()
  220. try:
  221. mr_iterations = list(filter(lambda x: bit_size < x[0],
  222. mr_ranges))[0][1]
  223. except IndexError:
  224. mr_iterations = 1
  225. if miller_rabin_test(candidate, mr_iterations,
  226. randfunc=randfunc) == COMPOSITE:
  227. return COMPOSITE
  228. if lucas_test(candidate) == COMPOSITE:
  229. return COMPOSITE
  230. return PROBABLY_PRIME
  231. def generate_probable_prime(**kwargs):
  232. """Generate a random probable prime.
  233. The prime will not have any specific properties
  234. (e.g. it will not be a *strong* prime).
  235. Random numbers are evaluated for primality until one
  236. passes all tests, consisting of a certain number of
  237. Miller-Rabin tests with random bases followed by
  238. a single Lucas test.
  239. The number of Miller-Rabin iterations is chosen such that
  240. the probability that the output number is a non-prime is
  241. less than 1E-30 (roughly 2^{-100}).
  242. This approach is compliant to `FIPS PUB 186-4`__.
  243. :Keywords:
  244. exact_bits : integer
  245. The desired size in bits of the probable prime.
  246. It must be at least 160.
  247. randfunc : callable
  248. An RNG function where candidate primes are taken from.
  249. prime_filter : callable
  250. A function that takes an Integer as parameter and returns
  251. True if the number can be passed to further primality tests,
  252. False if it should be immediately discarded.
  253. :Return:
  254. A probable prime in the range 2^exact_bits > p > 2^(exact_bits-1).
  255. .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
  256. """
  257. exact_bits = kwargs.pop("exact_bits", None)
  258. randfunc = kwargs.pop("randfunc", None)
  259. prime_filter = kwargs.pop("prime_filter", lambda x: True)
  260. if kwargs:
  261. raise ValueError("Unknown parameters: " + kwargs.keys())
  262. if exact_bits is None:
  263. raise ValueError("Missing exact_bits parameter")
  264. if exact_bits < 160:
  265. raise ValueError("Prime number is not big enough.")
  266. if randfunc is None:
  267. randfunc = Random.new().read
  268. result = COMPOSITE
  269. while result == COMPOSITE:
  270. candidate = Integer.random(exact_bits=exact_bits,
  271. randfunc=randfunc) | 1
  272. if not prime_filter(candidate):
  273. continue
  274. result = test_probable_prime(candidate, randfunc)
  275. return candidate
  276. def generate_probable_safe_prime(**kwargs):
  277. """Generate a random, probable safe prime.
  278. Note this operation is much slower than generating a simple prime.
  279. :Keywords:
  280. exact_bits : integer
  281. The desired size in bits of the probable safe prime.
  282. randfunc : callable
  283. An RNG function where candidate primes are taken from.
  284. :Return:
  285. A probable safe prime in the range
  286. 2^exact_bits > p > 2^(exact_bits-1).
  287. """
  288. exact_bits = kwargs.pop("exact_bits", None)
  289. randfunc = kwargs.pop("randfunc", None)
  290. if kwargs:
  291. raise ValueError("Unknown parameters: " + kwargs.keys())
  292. if randfunc is None:
  293. randfunc = Random.new().read
  294. result = COMPOSITE
  295. while result == COMPOSITE:
  296. q = generate_probable_prime(exact_bits=exact_bits - 1, randfunc=randfunc)
  297. candidate = q * 2 + 1
  298. if candidate.size_in_bits() != exact_bits:
  299. continue
  300. result = test_probable_prime(candidate, randfunc=randfunc)
  301. return candidate