residue_ntheory.py 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963
  1. from __future__ import annotations
  2. from sympy.external.gmpy import (gcd, lcm, invert, sqrt, jacobi,
  3. bit_scan1, remove)
  4. from sympy.polys import Poly
  5. from sympy.polys.domains import ZZ
  6. from sympy.polys.galoistools import gf_crt1, gf_crt2, linear_congruence, gf_csolve
  7. from .primetest import isprime
  8. from .generate import primerange
  9. from .factor_ import factorint, _perfect_power
  10. from .modular import crt
  11. from sympy.utilities.decorator import deprecated
  12. from sympy.utilities.memoization import recurrence_memo
  13. from sympy.utilities.misc import as_int
  14. from sympy.utilities.iterables import iproduct
  15. from sympy.core.random import _randint, randint
  16. from itertools import product
  17. def n_order(a, n):
  18. r""" Returns the order of ``a`` modulo ``n``.
  19. Explanation
  20. ===========
  21. The order of ``a`` modulo ``n`` is the smallest integer
  22. ``k`` such that `a^k` leaves a remainder of 1 with ``n``.
  23. Parameters
  24. ==========
  25. a : integer
  26. n : integer, n > 1. a and n should be relatively prime
  27. Returns
  28. =======
  29. int : the order of ``a`` modulo ``n``
  30. Raises
  31. ======
  32. ValueError
  33. If `n \le 1` or `\gcd(a, n) \neq 1`.
  34. If ``a`` or ``n`` is not an integer.
  35. Examples
  36. ========
  37. >>> from sympy.ntheory import n_order
  38. >>> n_order(3, 7)
  39. 6
  40. >>> n_order(4, 7)
  41. 3
  42. See Also
  43. ========
  44. is_primitive_root
  45. We say that ``a`` is a primitive root of ``n``
  46. when the order of ``a`` modulo ``n`` equals ``totient(n)``
  47. """
  48. a, n = as_int(a), as_int(n)
  49. if n <= 1:
  50. raise ValueError("n should be an integer greater than 1")
  51. a = a % n
  52. # Trivial
  53. if a == 1:
  54. return 1
  55. if gcd(a, n) != 1:
  56. raise ValueError("The two numbers should be relatively prime")
  57. a_order = 1
  58. for p, e in factorint(n).items():
  59. pe = p**e
  60. pe_order = (p - 1) * p**(e - 1)
  61. factors = factorint(p - 1)
  62. if e > 1:
  63. factors[p] = e - 1
  64. order = 1
  65. for px, ex in factors.items():
  66. x = pow(a, pe_order // px**ex, pe)
  67. while x != 1:
  68. x = pow(x, px, pe)
  69. order *= px
  70. a_order = lcm(a_order, order)
  71. return int(a_order)
  72. def _primitive_root_prime_iter(p):
  73. r""" Generates the primitive roots for a prime ``p``.
  74. Explanation
  75. ===========
  76. The primitive roots generated are not necessarily sorted.
  77. However, the first one is the smallest primitive root.
  78. Find the element whose order is ``p-1`` from the smaller one.
  79. If we can find the first primitive root ``g``, we can use the following theorem.
  80. .. math ::
  81. \operatorname{ord}(g^k) = \frac{\operatorname{ord}(g)}{\gcd(\operatorname{ord}(g), k)}
  82. From the assumption that `\operatorname{ord}(g)=p-1`,
  83. it is a necessary and sufficient condition for
  84. `\operatorname{ord}(g^k)=p-1` that `\gcd(p-1, k)=1`.
  85. Parameters
  86. ==========
  87. p : odd prime
  88. Yields
  89. ======
  90. int
  91. the primitive roots of ``p``
  92. Examples
  93. ========
  94. >>> from sympy.ntheory.residue_ntheory import _primitive_root_prime_iter
  95. >>> sorted(_primitive_root_prime_iter(19))
  96. [2, 3, 10, 13, 14, 15]
  97. References
  98. ==========
  99. .. [1] W. Stein "Elementary Number Theory" (2011), page 44
  100. """
  101. if p == 3:
  102. yield 2
  103. return
  104. # Let p = +-1 (mod 4a). Legendre symbol (a/p) = 1, so `a` is not the primitive root.
  105. # Corollary : If p = +-1 (mod 8), then 2 is not the primitive root of p.
  106. g_min = 3 if p % 8 in [1, 7] else 2
  107. if p < 41:
  108. # small case
  109. g = 5 if p == 23 else g_min
  110. else:
  111. v = [(p - 1) // i for i in factorint(p - 1).keys()]
  112. for g in range(g_min, p):
  113. if all(pow(g, pw, p) != 1 for pw in v):
  114. break
  115. yield g
  116. # g**k is the primitive root of p iff gcd(p - 1, k) = 1
  117. for k in range(3, p, 2):
  118. if gcd(p - 1, k) == 1:
  119. yield pow(g, k, p)
  120. def _primitive_root_prime_power_iter(p, e):
  121. r""" Generates the primitive roots of `p^e`.
  122. Explanation
  123. ===========
  124. Let ``g`` be the primitive root of ``p``.
  125. If `g^{p-1} \not\equiv 1 \pmod{p^2}`, then ``g`` is primitive root of `p^e`.
  126. Thus, if we find a primitive root ``g`` of ``p``,
  127. then `g, g+p, g+2p, \ldots, g+(p-1)p` are primitive roots of `p^2` except one.
  128. That one satisfies `\hat{g}^{p-1} \equiv 1 \pmod{p^2}`.
  129. If ``h`` is the primitive root of `p^2`,
  130. then `h, h+p^2, h+2p^2, \ldots, h+(p^{e-2}-1)p^e` are primitive roots of `p^e`.
  131. Parameters
  132. ==========
  133. p : odd prime
  134. e : positive integer
  135. Yields
  136. ======
  137. int
  138. the primitive roots of `p^e`
  139. Examples
  140. ========
  141. >>> from sympy.ntheory.residue_ntheory import _primitive_root_prime_power_iter
  142. >>> sorted(_primitive_root_prime_power_iter(5, 2))
  143. [2, 3, 8, 12, 13, 17, 22, 23]
  144. """
  145. if e == 1:
  146. yield from _primitive_root_prime_iter(p)
  147. else:
  148. p2 = p**2
  149. for g in _primitive_root_prime_iter(p):
  150. t = (g - pow(g, 2 - p, p2)) % p2
  151. for k in range(0, p2, p):
  152. if k != t:
  153. yield from (g + k + m for m in range(0, p**e, p2))
  154. def _primitive_root_prime_power2_iter(p, e):
  155. r""" Generates the primitive roots of `2p^e`.
  156. Explanation
  157. ===========
  158. If ``g`` is the primitive root of ``p**e``,
  159. then the odd one of ``g`` and ``g+p**e`` is the primitive root of ``2*p**e``.
  160. Parameters
  161. ==========
  162. p : odd prime
  163. e : positive integer
  164. Yields
  165. ======
  166. int
  167. the primitive roots of `2p^e`
  168. Examples
  169. ========
  170. >>> from sympy.ntheory.residue_ntheory import _primitive_root_prime_power2_iter
  171. >>> sorted(_primitive_root_prime_power2_iter(5, 2))
  172. [3, 13, 17, 23, 27, 33, 37, 47]
  173. """
  174. for g in _primitive_root_prime_power_iter(p, e):
  175. if g % 2 == 1:
  176. yield g
  177. else:
  178. yield g + p**e
  179. def primitive_root(p, smallest=True):
  180. r""" Returns a primitive root of ``p`` or None.
  181. Explanation
  182. ===========
  183. For the definition of primitive root,
  184. see the explanation of ``is_primitive_root``.
  185. The primitive root of ``p`` exist only for
  186. `p = 2, 4, q^e, 2q^e` (``q`` is an odd prime).
  187. Now, if we know the primitive root of ``q``,
  188. we can calculate the primitive root of `q^e`,
  189. and if we know the primitive root of `q^e`,
  190. we can calculate the primitive root of `2q^e`.
  191. When there is no need to find the smallest primitive root,
  192. this property can be used to obtain a fast primitive root.
  193. On the other hand, when we want the smallest primitive root,
  194. we naively determine whether it is a primitive root or not.
  195. Parameters
  196. ==========
  197. p : integer, p > 1
  198. smallest : if True the smallest primitive root is returned or None
  199. Returns
  200. =======
  201. int | None :
  202. If the primitive root exists, return the primitive root of ``p``.
  203. If not, return None.
  204. Raises
  205. ======
  206. ValueError
  207. If `p \le 1` or ``p`` is not an integer.
  208. Examples
  209. ========
  210. >>> from sympy.ntheory.residue_ntheory import primitive_root
  211. >>> primitive_root(19)
  212. 2
  213. >>> primitive_root(21) is None
  214. True
  215. >>> primitive_root(50, smallest=False)
  216. 27
  217. See Also
  218. ========
  219. is_primitive_root
  220. References
  221. ==========
  222. .. [1] W. Stein "Elementary Number Theory" (2011), page 44
  223. .. [2] P. Hackman "Elementary Number Theory" (2009), Chapter C
  224. """
  225. p = as_int(p)
  226. if p <= 1:
  227. raise ValueError("p should be an integer greater than 1")
  228. if p <= 4:
  229. return p - 1
  230. p_even = p % 2 == 0
  231. if not p_even:
  232. q = p # p is odd
  233. elif p % 4:
  234. q = p//2 # p had 1 factor of 2
  235. else:
  236. return None # p had more than one factor of 2
  237. if isprime(q):
  238. e = 1
  239. else:
  240. m = _perfect_power(q, 3)
  241. if not m:
  242. return None
  243. q, e = m
  244. if not isprime(q):
  245. return None
  246. if not smallest:
  247. if p_even:
  248. return next(_primitive_root_prime_power2_iter(q, e))
  249. return next(_primitive_root_prime_power_iter(q, e))
  250. if p_even:
  251. for i in range(3, p, 2):
  252. if i % q and is_primitive_root(i, p):
  253. return i
  254. g = next(_primitive_root_prime_iter(q))
  255. if e == 1 or pow(g, q - 1, q**2) != 1:
  256. return g
  257. for i in range(g + 1, p):
  258. if i % q and is_primitive_root(i, p):
  259. return i
  260. def is_primitive_root(a, p):
  261. r""" Returns True if ``a`` is a primitive root of ``p``.
  262. Explanation
  263. ===========
  264. ``a`` is said to be the primitive root of ``p`` if `\gcd(a, p) = 1` and
  265. `\phi(p)` is the smallest positive number s.t.
  266. `a^{\phi(p)} \equiv 1 \pmod{p}`.
  267. where `\phi(p)` is Euler's totient function.
  268. The primitive root of ``p`` exist only for
  269. `p = 2, 4, q^e, 2q^e` (``q`` is an odd prime).
  270. Hence, if it is not such a ``p``, it returns False.
  271. To determine the primitive root, we need to know
  272. the prime factorization of ``q-1``.
  273. The hardness of the determination depends on this complexity.
  274. Parameters
  275. ==========
  276. a : integer
  277. p : integer, ``p`` > 1. ``a`` and ``p`` should be relatively prime
  278. Returns
  279. =======
  280. bool : If True, ``a`` is the primitive root of ``p``.
  281. Raises
  282. ======
  283. ValueError
  284. If `p \le 1` or `\gcd(a, p) \neq 1`.
  285. If ``a`` or ``p`` is not an integer.
  286. Examples
  287. ========
  288. >>> from sympy.functions.combinatorial.numbers import totient
  289. >>> from sympy.ntheory import is_primitive_root, n_order
  290. >>> is_primitive_root(3, 10)
  291. True
  292. >>> is_primitive_root(9, 10)
  293. False
  294. >>> n_order(3, 10) == totient(10)
  295. True
  296. >>> n_order(9, 10) == totient(10)
  297. False
  298. See Also
  299. ========
  300. primitive_root
  301. """
  302. a, p = as_int(a), as_int(p)
  303. if p <= 1:
  304. raise ValueError("p should be an integer greater than 1")
  305. a = a % p
  306. if gcd(a, p) != 1:
  307. raise ValueError("The two numbers should be relatively prime")
  308. # Primitive root of p exist only for
  309. # p = 2, 4, q**e, 2*q**e (q is odd prime)
  310. if p <= 4:
  311. # The primitive root is only p-1.
  312. return a == p - 1
  313. if p % 2:
  314. q = p # p is odd
  315. elif p % 4:
  316. q = p//2 # p had 1 factor of 2
  317. else:
  318. return False # p had more than one factor of 2
  319. if isprime(q):
  320. group_order = q - 1
  321. factors = factorint(q - 1).keys()
  322. else:
  323. m = _perfect_power(q, 3)
  324. if not m:
  325. return False
  326. q, e = m
  327. if not isprime(q):
  328. return False
  329. group_order = q**(e - 1)*(q - 1)
  330. factors = set(factorint(q - 1).keys())
  331. factors.add(q)
  332. return all(pow(a, group_order // prime, p) != 1 for prime in factors)
  333. def _sqrt_mod_tonelli_shanks(a, p):
  334. """
  335. Returns the square root in the case of ``p`` prime with ``p == 1 (mod 8)``
  336. Assume that the root exists.
  337. Parameters
  338. ==========
  339. a : int
  340. p : int
  341. prime number. should be ``p % 8 == 1``
  342. Returns
  343. =======
  344. int : Generally, there are two roots, but only one is returned.
  345. Which one is returned is random.
  346. Examples
  347. ========
  348. >>> from sympy.ntheory.residue_ntheory import _sqrt_mod_tonelli_shanks
  349. >>> _sqrt_mod_tonelli_shanks(2, 17) in [6, 11]
  350. True
  351. References
  352. ==========
  353. .. [1] Carl Pomerance, Richard Crandall, Prime Numbers: A Computational Perspective,
  354. 2nd Edition (2005), page 101, ISBN:978-0387252827
  355. """
  356. s = bit_scan1(p - 1)
  357. t = p >> s
  358. # find a non-quadratic residue
  359. if p % 12 == 5:
  360. # Legendre symbol (3/p) == -1 if p % 12 in [5, 7]
  361. d = 3
  362. elif p % 5 in [2, 3]:
  363. # Legendre symbol (5/p) == -1 if p % 5 in [2, 3]
  364. d = 5
  365. else:
  366. while 1:
  367. d = randint(6, p - 1)
  368. if jacobi(d, p) == -1:
  369. break
  370. #assert legendre_symbol(d, p) == -1
  371. A = pow(a, t, p)
  372. D = pow(d, t, p)
  373. m = 0
  374. for i in range(s):
  375. adm = A*pow(D, m, p) % p
  376. adm = pow(adm, 2**(s - 1 - i), p)
  377. if adm % p == p - 1:
  378. m += 2**i
  379. #assert A*pow(D, m, p) % p == 1
  380. x = pow(a, (t + 1)//2, p)*pow(D, m//2, p) % p
  381. return x
  382. def sqrt_mod(a, p, all_roots=False):
  383. """
  384. Find a root of ``x**2 = a mod p``.
  385. Parameters
  386. ==========
  387. a : integer
  388. p : positive integer
  389. all_roots : if True the list of roots is returned or None
  390. Notes
  391. =====
  392. If there is no root it is returned None; else the returned root
  393. is less or equal to ``p // 2``; in general is not the smallest one.
  394. It is returned ``p // 2`` only if it is the only root.
  395. Use ``all_roots`` only when it is expected that all the roots fit
  396. in memory; otherwise use ``sqrt_mod_iter``.
  397. Examples
  398. ========
  399. >>> from sympy.ntheory import sqrt_mod
  400. >>> sqrt_mod(11, 43)
  401. 21
  402. >>> sqrt_mod(17, 32, True)
  403. [7, 9, 23, 25]
  404. """
  405. if all_roots:
  406. return sorted(sqrt_mod_iter(a, p))
  407. p = abs(as_int(p))
  408. halfp = p // 2
  409. x = None
  410. for r in sqrt_mod_iter(a, p):
  411. if r < halfp:
  412. return r
  413. elif r > halfp:
  414. return p - r
  415. else:
  416. x = r
  417. return x
  418. def sqrt_mod_iter(a, p, domain=int):
  419. """
  420. Iterate over solutions to ``x**2 = a mod p``.
  421. Parameters
  422. ==========
  423. a : integer
  424. p : positive integer
  425. domain : integer domain, ``int``, ``ZZ`` or ``Integer``
  426. Examples
  427. ========
  428. >>> from sympy.ntheory.residue_ntheory import sqrt_mod_iter
  429. >>> list(sqrt_mod_iter(11, 43))
  430. [21, 22]
  431. See Also
  432. ========
  433. sqrt_mod : Same functionality, but you want a sorted list or only one solution.
  434. """
  435. a, p = as_int(a), abs(as_int(p))
  436. v = []
  437. pv = []
  438. _product = product
  439. for px, ex in factorint(p).items():
  440. if a % px:
  441. # `len(rx)` is at most 4
  442. rx = _sqrt_mod_prime_power(a, px, ex)
  443. else:
  444. # `len(list(rx))` can be assumed to be large.
  445. # The `itertools.product` is disadvantageous in terms of memory usage.
  446. # It is also inferior to iproduct in speed if not all Cartesian products are needed.
  447. rx = _sqrt_mod1(a, px, ex)
  448. _product = iproduct
  449. if not rx:
  450. return
  451. v.append(rx)
  452. pv.append(px**ex)
  453. if len(v) == 1:
  454. yield from map(domain, v[0])
  455. else:
  456. mm, e, s = gf_crt1(pv, ZZ)
  457. for vx in _product(*v):
  458. yield domain(gf_crt2(vx, pv, mm, e, s, ZZ))
  459. def _sqrt_mod_prime_power(a, p, k):
  460. """
  461. Find the solutions to ``x**2 = a mod p**k`` when ``a % p != 0``.
  462. If no solution exists, return ``None``.
  463. Solutions are returned in an ascending list.
  464. Parameters
  465. ==========
  466. a : integer
  467. p : prime number
  468. k : positive integer
  469. Examples
  470. ========
  471. >>> from sympy.ntheory.residue_ntheory import _sqrt_mod_prime_power
  472. >>> _sqrt_mod_prime_power(11, 43, 1)
  473. [21, 22]
  474. References
  475. ==========
  476. .. [1] P. Hackman "Elementary Number Theory" (2009), page 160
  477. .. [2] http://www.numbertheory.org/php/squareroot.html
  478. .. [3] [Gathen99]_
  479. """
  480. pk = p**k
  481. a = a % pk
  482. if p == 2:
  483. # see Ref.[2]
  484. if a % 8 != 1:
  485. return None
  486. # Trivial
  487. if k <= 3:
  488. return list(range(1, pk, 2))
  489. r = 1
  490. # r is one of the solutions to x**2 - a = 0 (mod 2**3).
  491. # Hensel lift them to solutions of x**2 - a = 0 (mod 2**k)
  492. # if r**2 - a = 0 mod 2**nx but not mod 2**(nx+1)
  493. # then r + 2**(nx - 1) is a root mod 2**(nx+1)
  494. for nx in range(3, k):
  495. if ((r**2 - a) >> nx) % 2:
  496. r += 1 << (nx - 1)
  497. # r is a solution of x**2 - a = 0 (mod 2**k), and
  498. # there exist other solutions -r, r+h, -(r+h), and these are all solutions.
  499. h = 1 << (k - 1)
  500. return sorted([r, pk - r, (r + h) % pk, -(r + h) % pk])
  501. # If the Legendre symbol (a/p) is not 1, no solution exists.
  502. if jacobi(a, p) != 1:
  503. return None
  504. if p % 4 == 3:
  505. res = pow(a, (p + 1) // 4, p)
  506. elif p % 8 == 5:
  507. res = pow(a, (p + 3) // 8, p)
  508. if pow(res, 2, p) != a % p:
  509. res = res * pow(2, (p - 1) // 4, p) % p
  510. else:
  511. res = _sqrt_mod_tonelli_shanks(a, p)
  512. if k > 1:
  513. # Hensel lifting with Newton iteration, see Ref.[3] chapter 9
  514. # with f(x) = x**2 - a; one has f'(a) != 0 (mod p) for p != 2
  515. px = p
  516. for _ in range(k.bit_length() - 1):
  517. px = px**2
  518. frinv = invert(2*res, px)
  519. res = (res - (res**2 - a)*frinv) % px
  520. if k & (k - 1): # If k is not a power of 2
  521. frinv = invert(2*res, pk)
  522. res = (res - (res**2 - a)*frinv) % pk
  523. return sorted([res, pk - res])
  524. def _sqrt_mod1(a, p, n):
  525. """
  526. Find solution to ``x**2 == a mod p**n`` when ``a % p == 0``.
  527. If no solution exists, return ``None``.
  528. Parameters
  529. ==========
  530. a : integer
  531. p : prime number, p must divide a
  532. n : positive integer
  533. References
  534. ==========
  535. .. [1] http://www.numbertheory.org/php/squareroot.html
  536. """
  537. pn = p**n
  538. a = a % pn
  539. if a == 0:
  540. # case gcd(a, p**k) = p**n
  541. return range(0, pn, p**((n + 1) // 2))
  542. # case gcd(a, p**k) = p**r, r < n
  543. a, r = remove(a, p)
  544. if r % 2 == 1:
  545. return None
  546. res = _sqrt_mod_prime_power(a, p, n - r)
  547. if res is None:
  548. return None
  549. m = r // 2
  550. return (x for rx in res for x in range(rx*p**m, pn, p**(n - m)))
  551. def is_quad_residue(a, p):
  552. """
  553. Returns True if ``a`` (mod ``p``) is in the set of squares mod ``p``,
  554. i.e a % p in set([i**2 % p for i in range(p)]).
  555. Parameters
  556. ==========
  557. a : integer
  558. p : positive integer
  559. Returns
  560. =======
  561. bool : If True, ``x**2 == a (mod p)`` has solution.
  562. Raises
  563. ======
  564. ValueError
  565. If ``a``, ``p`` is not integer.
  566. If ``p`` is not positive.
  567. Examples
  568. ========
  569. >>> from sympy.ntheory import is_quad_residue
  570. >>> is_quad_residue(21, 100)
  571. True
  572. Indeed, ``pow(39, 2, 100)`` would be 21.
  573. >>> is_quad_residue(21, 120)
  574. False
  575. That is, for any integer ``x``, ``pow(x, 2, 120)`` is not 21.
  576. If ``p`` is an odd
  577. prime, an iterative method is used to make the determination:
  578. >>> from sympy.ntheory import is_quad_residue
  579. >>> sorted(set([i**2 % 7 for i in range(7)]))
  580. [0, 1, 2, 4]
  581. >>> [j for j in range(7) if is_quad_residue(j, 7)]
  582. [0, 1, 2, 4]
  583. See Also
  584. ========
  585. legendre_symbol, jacobi_symbol, sqrt_mod
  586. """
  587. a, p = as_int(a), as_int(p)
  588. if p < 1:
  589. raise ValueError('p must be > 0')
  590. a %= p
  591. if a < 2 or p < 3:
  592. return True
  593. # Since we want to compute the Jacobi symbol,
  594. # we separate p into the odd part and the rest.
  595. t = bit_scan1(p)
  596. if t:
  597. # The existence of a solution to a power of 2 is determined
  598. # using the logic of `p==2` in `_sqrt_mod_prime_power` and `_sqrt_mod1`.
  599. a_ = a % (1 << t)
  600. if a_:
  601. r = bit_scan1(a_)
  602. if r % 2 or (a_ >> r) & 6:
  603. return False
  604. p >>= t
  605. a %= p
  606. if a < 2 or p < 3:
  607. return True
  608. # If Jacobi symbol is -1 or p is prime, can be determined by Jacobi symbol only
  609. j = jacobi(a, p)
  610. if j == -1 or isprime(p):
  611. return j == 1
  612. # Checks if `x**2 = a (mod p)` has a solution
  613. for px, ex in factorint(p).items():
  614. if a % px:
  615. if jacobi(a, px) != 1:
  616. return False
  617. else:
  618. a_ = a % px**ex
  619. if a_ == 0:
  620. continue
  621. a_, r = remove(a_, px)
  622. if r % 2 or jacobi(a_, px) != 1:
  623. return False
  624. return True
  625. def is_nthpow_residue(a, n, m):
  626. """
  627. Returns True if ``x**n == a (mod m)`` has solutions.
  628. References
  629. ==========
  630. .. [1] P. Hackman "Elementary Number Theory" (2009), page 76
  631. """
  632. a = a % m
  633. a, n, m = as_int(a), as_int(n), as_int(m)
  634. if m <= 0:
  635. raise ValueError('m must be > 0')
  636. if n < 0:
  637. raise ValueError('n must be >= 0')
  638. if n == 0:
  639. if m == 1:
  640. return False
  641. return a == 1
  642. if a == 0:
  643. return True
  644. if n == 1:
  645. return True
  646. if n == 2:
  647. return is_quad_residue(a, m)
  648. return all(_is_nthpow_residue_bign_prime_power(a, n, p, e)
  649. for p, e in factorint(m).items())
  650. def _is_nthpow_residue_bign_prime_power(a, n, p, k):
  651. r"""
  652. Returns True if `x^n = a \pmod{p^k}` has solutions for `n > 2`.
  653. Parameters
  654. ==========
  655. a : positive integer
  656. n : integer, n > 2
  657. p : prime number
  658. k : positive integer
  659. """
  660. while a % p == 0:
  661. a %= pow(p, k)
  662. if not a:
  663. return True
  664. a, mu = remove(a, p)
  665. if mu % n:
  666. return False
  667. k -= mu
  668. if p != 2:
  669. f = p**(k - 1)*(p - 1) # f = totient(p**k)
  670. return pow(a, f // gcd(f, n), pow(p, k)) == 1
  671. if n & 1:
  672. return True
  673. c = min(bit_scan1(n) + 2, k)
  674. return a % pow(2, c) == 1
  675. def _nthroot_mod1(s, q, p, all_roots):
  676. """
  677. Root of ``x**q = s mod p``, ``p`` prime and ``q`` divides ``p - 1``.
  678. Assume that the root exists.
  679. Parameters
  680. ==========
  681. s : integer
  682. q : integer, n > 2. ``q`` divides ``p - 1``.
  683. p : prime number
  684. all_roots : if False returns the smallest root, else the list of roots
  685. Returns
  686. =======
  687. list[int] | int :
  688. Root of ``x**q = s mod p``. If ``all_roots == True``,
  689. returned ascending list. otherwise, returned an int.
  690. Examples
  691. ========
  692. >>> from sympy.ntheory.residue_ntheory import _nthroot_mod1
  693. >>> _nthroot_mod1(5, 3, 13, False)
  694. 7
  695. >>> _nthroot_mod1(13, 4, 17, True)
  696. [3, 5, 12, 14]
  697. References
  698. ==========
  699. .. [1] A. M. Johnston, A Generalized qth Root Algorithm,
  700. ACM-SIAM Symposium on Discrete Algorithms (1999), pp. 929-930
  701. """
  702. g = next(_primitive_root_prime_iter(p))
  703. r = s
  704. for qx, ex in factorint(q).items():
  705. f = (p - 1) // qx**ex
  706. while f % qx == 0:
  707. f //= qx
  708. z = f*invert(-f, qx)
  709. x = (1 + z) // qx
  710. t = discrete_log(p, pow(r, f, p), pow(g, f*qx, p))
  711. for _ in range(ex):
  712. # assert t == discrete_log(p, pow(r, f, p), pow(g, f*qx, p))
  713. r = pow(r, x, p)*pow(g, -z*t % (p - 1), p) % p
  714. t //= qx
  715. res = [r]
  716. h = pow(g, (p - 1) // q, p)
  717. #assert pow(h, q, p) == 1
  718. hx = r
  719. for _ in range(q - 1):
  720. hx = (hx*h) % p
  721. res.append(hx)
  722. if all_roots:
  723. res.sort()
  724. return res
  725. return min(res)
  726. def _nthroot_mod_prime_power(a, n, p, k):
  727. """ Root of ``x**n = a mod p**k``.
  728. Parameters
  729. ==========
  730. a : integer
  731. n : integer, n > 2
  732. p : prime number
  733. k : positive integer
  734. Returns
  735. =======
  736. list[int] :
  737. Ascending list of roots of ``x**n = a mod p**k``.
  738. If no solution exists, return ``[]``.
  739. """
  740. if not _is_nthpow_residue_bign_prime_power(a, n, p, k):
  741. return []
  742. a_mod_p = a % p
  743. if a_mod_p == 0:
  744. base_roots = [0]
  745. elif (p - 1) % n == 0:
  746. base_roots = _nthroot_mod1(a_mod_p, n, p, all_roots=True)
  747. else:
  748. # The roots of ``x**n - a = 0 (mod p)`` are roots of
  749. # ``gcd(x**n - a, x**(p - 1) - 1) = 0 (mod p)``
  750. pa = n
  751. pb = p - 1
  752. b = 1
  753. if pa < pb:
  754. a_mod_p, pa, b, pb = b, pb, a_mod_p, pa
  755. # gcd(x**pa - a, x**pb - b) = gcd(x**pb - b, x**pc - c)
  756. # where pc = pa % pb; c = b**-q * a mod p
  757. while pb:
  758. q, pc = divmod(pa, pb)
  759. c = pow(b, -q, p) * a_mod_p % p
  760. pa, pb = pb, pc
  761. a_mod_p, b = b, c
  762. if pa == 1:
  763. base_roots = [a_mod_p]
  764. elif pa == 2:
  765. base_roots = sqrt_mod(a_mod_p, p, all_roots=True)
  766. else:
  767. base_roots = _nthroot_mod1(a_mod_p, pa, p, all_roots=True)
  768. if k == 1:
  769. return base_roots
  770. a %= p**k
  771. tot_roots = set()
  772. for root in base_roots:
  773. diff = pow(root, n - 1, p)*n % p
  774. new_base = p
  775. if diff != 0:
  776. m_inv = invert(diff, p)
  777. for _ in range(k - 1):
  778. new_base *= p
  779. tmp = pow(root, n, new_base) - a
  780. tmp *= m_inv
  781. root = (root - tmp) % new_base
  782. tot_roots.add(root)
  783. else:
  784. roots_in_base = {root}
  785. for _ in range(k - 1):
  786. new_base *= p
  787. new_roots = set()
  788. for k_ in roots_in_base:
  789. if pow(k_, n, new_base) != a % new_base:
  790. continue
  791. while k_ not in new_roots:
  792. new_roots.add(k_)
  793. k_ = (k_ + (new_base // p)) % new_base
  794. roots_in_base = new_roots
  795. tot_roots = tot_roots | roots_in_base
  796. return sorted(tot_roots)
  797. def nthroot_mod(a, n, p, all_roots=False):
  798. """
  799. Find the solutions to ``x**n = a mod p``.
  800. Parameters
  801. ==========
  802. a : integer
  803. n : positive integer
  804. p : positive integer
  805. all_roots : if False returns the smallest root, else the list of roots
  806. Returns
  807. =======
  808. list[int] | int | None :
  809. solutions to ``x**n = a mod p``.
  810. The table of the output type is:
  811. ========== ========== ==========
  812. all_roots has roots Returns
  813. ========== ========== ==========
  814. True Yes list[int]
  815. True No []
  816. False Yes int
  817. False No None
  818. ========== ========== ==========
  819. Raises
  820. ======
  821. ValueError
  822. If ``a``, ``n`` or ``p`` is not integer.
  823. If ``n`` or ``p`` is not positive.
  824. Examples
  825. ========
  826. >>> from sympy.ntheory.residue_ntheory import nthroot_mod
  827. >>> nthroot_mod(11, 4, 19)
  828. 8
  829. >>> nthroot_mod(11, 4, 19, True)
  830. [8, 11]
  831. >>> nthroot_mod(68, 3, 109)
  832. 23
  833. References
  834. ==========
  835. .. [1] P. Hackman "Elementary Number Theory" (2009), page 76
  836. """
  837. a = a % p
  838. a, n, p = as_int(a), as_int(n), as_int(p)
  839. if n < 1:
  840. raise ValueError("n should be positive")
  841. if p < 1:
  842. raise ValueError("p should be positive")
  843. if n == 1:
  844. return [a] if all_roots else a
  845. if n == 2:
  846. return sqrt_mod(a, p, all_roots)
  847. base = []
  848. prime_power = []
  849. for q, e in factorint(p).items():
  850. tot_roots = _nthroot_mod_prime_power(a, n, q, e)
  851. if not tot_roots:
  852. return [] if all_roots else None
  853. prime_power.append(q**e)
  854. base.append(sorted(tot_roots))
  855. P, E, S = gf_crt1(prime_power, ZZ)
  856. ret = sorted(map(int, {gf_crt2(c, prime_power, P, E, S, ZZ)
  857. for c in product(*base)}))
  858. if all_roots:
  859. return ret
  860. if ret:
  861. return ret[0]
  862. def quadratic_residues(p) -> list[int]:
  863. """
  864. Returns the list of quadratic residues.
  865. Examples
  866. ========
  867. >>> from sympy.ntheory.residue_ntheory import quadratic_residues
  868. >>> quadratic_residues(7)
  869. [0, 1, 2, 4]
  870. """
  871. p = as_int(p)
  872. r = {pow(i, 2, p) for i in range(p // 2 + 1)}
  873. return sorted(r)
  874. @deprecated("""\
  875. The `sympy.ntheory.residue_ntheory.legendre_symbol` has been moved to `sympy.functions.combinatorial.numbers.legendre_symbol`.""",
  876. deprecated_since_version="1.13",
  877. active_deprecations_target='deprecated-ntheory-symbolic-functions')
  878. def legendre_symbol(a, p):
  879. r"""
  880. Returns the Legendre symbol `(a / p)`.
  881. .. deprecated:: 1.13
  882. The ``legendre_symbol`` function is deprecated. Use :class:`sympy.functions.combinatorial.numbers.legendre_symbol`
  883. instead. See its documentation for more information. See
  884. :ref:`deprecated-ntheory-symbolic-functions` for details.
  885. For an integer ``a`` and an odd prime ``p``, the Legendre symbol is
  886. defined as
  887. .. math ::
  888. \genfrac(){}{}{a}{p} = \begin{cases}
  889. 0 & \text{if } p \text{ divides } a\\
  890. 1 & \text{if } a \text{ is a quadratic residue modulo } p\\
  891. -1 & \text{if } a \text{ is a quadratic nonresidue modulo } p
  892. \end{cases}
  893. Parameters
  894. ==========
  895. a : integer
  896. p : odd prime
  897. Examples
  898. ========
  899. >>> from sympy.functions.combinatorial.numbers import legendre_symbol
  900. >>> [legendre_symbol(i, 7) for i in range(7)]
  901. [0, 1, 1, -1, 1, -1, -1]
  902. >>> sorted(set([i**2 % 7 for i in range(7)]))
  903. [0, 1, 2, 4]
  904. See Also
  905. ========
  906. is_quad_residue, jacobi_symbol
  907. """
  908. from sympy.functions.combinatorial.numbers import legendre_symbol as _legendre_symbol
  909. return _legendre_symbol(a, p)
  910. @deprecated("""\
  911. The `sympy.ntheory.residue_ntheory.jacobi_symbol` has been moved to `sympy.functions.combinatorial.numbers.jacobi_symbol`.""",
  912. deprecated_since_version="1.13",
  913. active_deprecations_target='deprecated-ntheory-symbolic-functions')
  914. def jacobi_symbol(m, n):
  915. r"""
  916. Returns the Jacobi symbol `(m / n)`.
  917. .. deprecated:: 1.13
  918. The ``jacobi_symbol`` function is deprecated. Use :class:`sympy.functions.combinatorial.numbers.jacobi_symbol`
  919. instead. See its documentation for more information. See
  920. :ref:`deprecated-ntheory-symbolic-functions` for details.
  921. For any integer ``m`` and any positive odd integer ``n`` the Jacobi symbol
  922. is defined as the product of the Legendre symbols corresponding to the
  923. prime factors of ``n``:
  924. .. math ::
  925. \genfrac(){}{}{m}{n} =
  926. \genfrac(){}{}{m}{p^{1}}^{\alpha_1}
  927. \genfrac(){}{}{m}{p^{2}}^{\alpha_2}
  928. ...
  929. \genfrac(){}{}{m}{p^{k}}^{\alpha_k}
  930. \text{ where } n =
  931. p_1^{\alpha_1}
  932. p_2^{\alpha_2}
  933. ...
  934. p_k^{\alpha_k}
  935. Like the Legendre symbol, if the Jacobi symbol `\genfrac(){}{}{m}{n} = -1`
  936. then ``m`` is a quadratic nonresidue modulo ``n``.
  937. But, unlike the Legendre symbol, if the Jacobi symbol
  938. `\genfrac(){}{}{m}{n} = 1` then ``m`` may or may not be a quadratic residue
  939. modulo ``n``.
  940. Parameters
  941. ==========
  942. m : integer
  943. n : odd positive integer
  944. Examples
  945. ========
  946. >>> from sympy.functions.combinatorial.numbers import jacobi_symbol, legendre_symbol
  947. >>> from sympy import S
  948. >>> jacobi_symbol(45, 77)
  949. -1
  950. >>> jacobi_symbol(60, 121)
  951. 1
  952. The relationship between the ``jacobi_symbol`` and ``legendre_symbol`` can
  953. be demonstrated as follows:
  954. >>> L = legendre_symbol
  955. >>> S(45).factors()
  956. {3: 2, 5: 1}
  957. >>> jacobi_symbol(7, 45) == L(7, 3)**2 * L(7, 5)**1
  958. True
  959. See Also
  960. ========
  961. is_quad_residue, legendre_symbol
  962. """
  963. from sympy.functions.combinatorial.numbers import jacobi_symbol as _jacobi_symbol
  964. return _jacobi_symbol(m, n)
  965. @deprecated("""\
  966. The `sympy.ntheory.residue_ntheory.mobius` has been moved to `sympy.functions.combinatorial.numbers.mobius`.""",
  967. deprecated_since_version="1.13",
  968. active_deprecations_target='deprecated-ntheory-symbolic-functions')
  969. def mobius(n):
  970. """
  971. Mobius function maps natural number to {-1, 0, 1}
  972. .. deprecated:: 1.13
  973. The ``mobius`` function is deprecated. Use :class:`sympy.functions.combinatorial.numbers.mobius`
  974. instead. See its documentation for more information. See
  975. :ref:`deprecated-ntheory-symbolic-functions` for details.
  976. It is defined as follows:
  977. 1) `1` if `n = 1`.
  978. 2) `0` if `n` has a squared prime factor.
  979. 3) `(-1)^k` if `n` is a square-free positive integer with `k`
  980. number of prime factors.
  981. It is an important multiplicative function in number theory
  982. and combinatorics. It has applications in mathematical series,
  983. algebraic number theory and also physics (Fermion operator has very
  984. concrete realization with Mobius Function model).
  985. Parameters
  986. ==========
  987. n : positive integer
  988. Examples
  989. ========
  990. >>> from sympy.functions.combinatorial.numbers import mobius
  991. >>> mobius(13*7)
  992. 1
  993. >>> mobius(1)
  994. 1
  995. >>> mobius(13*7*5)
  996. -1
  997. >>> mobius(13**2)
  998. 0
  999. References
  1000. ==========
  1001. .. [1] https://en.wikipedia.org/wiki/M%C3%B6bius_function
  1002. .. [2] Thomas Koshy "Elementary Number Theory with Applications"
  1003. """
  1004. from sympy.functions.combinatorial.numbers import mobius as _mobius
  1005. return _mobius(n)
  1006. def _discrete_log_trial_mul(n, a, b, order=None):
  1007. """
  1008. Trial multiplication algorithm for computing the discrete logarithm of
  1009. ``a`` to the base ``b`` modulo ``n``.
  1010. The algorithm finds the discrete logarithm using exhaustive search. This
  1011. naive method is used as fallback algorithm of ``discrete_log`` when the
  1012. group order is very small. The value ``n`` must be greater than 1.
  1013. Examples
  1014. ========
  1015. >>> from sympy.ntheory.residue_ntheory import _discrete_log_trial_mul
  1016. >>> _discrete_log_trial_mul(41, 15, 7)
  1017. 3
  1018. See Also
  1019. ========
  1020. discrete_log
  1021. References
  1022. ==========
  1023. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1024. Vanstone, S. A. (1997).
  1025. """
  1026. a %= n
  1027. b %= n
  1028. if order is None:
  1029. order = n
  1030. x = 1
  1031. for i in range(order):
  1032. if x == a:
  1033. return i
  1034. x = x * b % n
  1035. raise ValueError("Log does not exist")
  1036. def _discrete_log_shanks_steps(n, a, b, order=None):
  1037. """
  1038. Baby-step giant-step algorithm for computing the discrete logarithm of
  1039. ``a`` to the base ``b`` modulo ``n``.
  1040. The algorithm is a time-memory trade-off of the method of exhaustive
  1041. search. It uses `O(sqrt(m))` memory, where `m` is the group order.
  1042. Examples
  1043. ========
  1044. >>> from sympy.ntheory.residue_ntheory import _discrete_log_shanks_steps
  1045. >>> _discrete_log_shanks_steps(41, 15, 7)
  1046. 3
  1047. See Also
  1048. ========
  1049. discrete_log
  1050. References
  1051. ==========
  1052. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1053. Vanstone, S. A. (1997).
  1054. """
  1055. a %= n
  1056. b %= n
  1057. if order is None:
  1058. order = n_order(b, n)
  1059. m = sqrt(order) + 1
  1060. T = {}
  1061. x = 1
  1062. for i in range(m):
  1063. T[x] = i
  1064. x = x * b % n
  1065. z = pow(b, -m, n)
  1066. x = a
  1067. for i in range(m):
  1068. if x in T:
  1069. return i * m + T[x]
  1070. x = x * z % n
  1071. raise ValueError("Log does not exist")
  1072. def _discrete_log_pollard_rho(n, a, b, order=None, retries=10, rseed=None):
  1073. """
  1074. Pollard's Rho algorithm for computing the discrete logarithm of ``a`` to
  1075. the base ``b`` modulo ``n``.
  1076. It is a randomized algorithm with the same expected running time as
  1077. ``_discrete_log_shanks_steps``, but requires a negligible amount of memory.
  1078. Examples
  1079. ========
  1080. >>> from sympy.ntheory.residue_ntheory import _discrete_log_pollard_rho
  1081. >>> _discrete_log_pollard_rho(227, 3**7, 3)
  1082. 7
  1083. See Also
  1084. ========
  1085. discrete_log
  1086. References
  1087. ==========
  1088. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1089. Vanstone, S. A. (1997).
  1090. """
  1091. a %= n
  1092. b %= n
  1093. if order is None:
  1094. order = n_order(b, n)
  1095. randint = _randint(rseed)
  1096. for i in range(retries):
  1097. aa = randint(1, order - 1)
  1098. ba = randint(1, order - 1)
  1099. xa = pow(b, aa, n) * pow(a, ba, n) % n
  1100. c = xa % 3
  1101. if c == 0:
  1102. xb = a * xa % n
  1103. ab = aa
  1104. bb = (ba + 1) % order
  1105. elif c == 1:
  1106. xb = xa * xa % n
  1107. ab = (aa + aa) % order
  1108. bb = (ba + ba) % order
  1109. else:
  1110. xb = b * xa % n
  1111. ab = (aa + 1) % order
  1112. bb = ba
  1113. for j in range(order):
  1114. c = xa % 3
  1115. if c == 0:
  1116. xa = a * xa % n
  1117. ba = (ba + 1) % order
  1118. elif c == 1:
  1119. xa = xa * xa % n
  1120. aa = (aa + aa) % order
  1121. ba = (ba + ba) % order
  1122. else:
  1123. xa = b * xa % n
  1124. aa = (aa + 1) % order
  1125. c = xb % 3
  1126. if c == 0:
  1127. xb = a * xb % n
  1128. bb = (bb + 1) % order
  1129. elif c == 1:
  1130. xb = xb * xb % n
  1131. ab = (ab + ab) % order
  1132. bb = (bb + bb) % order
  1133. else:
  1134. xb = b * xb % n
  1135. ab = (ab + 1) % order
  1136. c = xb % 3
  1137. if c == 0:
  1138. xb = a * xb % n
  1139. bb = (bb + 1) % order
  1140. elif c == 1:
  1141. xb = xb * xb % n
  1142. ab = (ab + ab) % order
  1143. bb = (bb + bb) % order
  1144. else:
  1145. xb = b * xb % n
  1146. ab = (ab + 1) % order
  1147. if xa == xb:
  1148. r = (ba - bb) % order
  1149. try:
  1150. e = invert(r, order) * (ab - aa) % order
  1151. if (pow(b, e, n) - a) % n == 0:
  1152. return e
  1153. except ZeroDivisionError:
  1154. pass
  1155. break
  1156. raise ValueError("Pollard's Rho failed to find logarithm")
  1157. def _discrete_log_is_smooth(n: int, factorbase: list):
  1158. """Try to factor n with respect to a given factorbase.
  1159. Upon success a list of exponents with respect to the factorbase is returned.
  1160. Otherwise None."""
  1161. factors = [0]*len(factorbase)
  1162. for i, p in enumerate(factorbase):
  1163. while n % p == 0: # divide by p as many times as possible
  1164. factors[i] += 1
  1165. n = n // p
  1166. if n != 1:
  1167. return None # the number factors if at the end nothing is left
  1168. return factors
  1169. def _discrete_log_index_calculus(n, a, b, order, rseed=None):
  1170. """
  1171. Index Calculus algorithm for computing the discrete logarithm of ``a`` to
  1172. the base ``b`` modulo ``n``.
  1173. The group order must be given and prime. It is not suitable for small orders
  1174. and the algorithm might fail to find a solution in such situations.
  1175. Examples
  1176. ========
  1177. >>> from sympy.ntheory.residue_ntheory import _discrete_log_index_calculus
  1178. >>> _discrete_log_index_calculus(24570203447, 23859756228, 2, 12285101723)
  1179. 4519867240
  1180. See Also
  1181. ========
  1182. discrete_log
  1183. References
  1184. ==========
  1185. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1186. Vanstone, S. A. (1997).
  1187. """
  1188. randint = _randint(rseed)
  1189. from math import sqrt, exp, log
  1190. a %= n
  1191. b %= n
  1192. # assert isprime(order), "The order of the base must be prime."
  1193. # First choose a heuristic the bound B for the factorbase.
  1194. # We have added an extra term to the asymptotic value which
  1195. # is closer to the theoretical optimum for n up to 2^70.
  1196. B = int(exp(0.5 * sqrt( log(n) * log(log(n)) )*( 1 + 1/log(log(n)) )))
  1197. max = 5 * B * B # expected number of tries to find a relation
  1198. factorbase = list(primerange(B)) # compute the factorbase
  1199. lf = len(factorbase) # length of the factorbase
  1200. ordermo = order-1
  1201. abx = a
  1202. for x in range(order):
  1203. if abx == 1:
  1204. return (order - x) % order
  1205. relationa = _discrete_log_is_smooth(abx, factorbase)
  1206. if relationa:
  1207. relationa = [r % order for r in relationa] + [x]
  1208. break
  1209. abx = abx * b % n # abx = a*pow(b, x, n) % n
  1210. else:
  1211. raise ValueError("Index Calculus failed")
  1212. relations = [None] * lf
  1213. k = 1 # number of relations found
  1214. kk = 0
  1215. while k < 3 * lf and kk < max: # find relations for all primes in our factor base
  1216. x = randint(1,ordermo)
  1217. relation = _discrete_log_is_smooth(pow(b,x,n), factorbase)
  1218. if relation is None:
  1219. kk += 1
  1220. continue
  1221. k += 1
  1222. kk = 0
  1223. relation += [ x ]
  1224. index = lf # determine the index of the first nonzero entry
  1225. for i in range(lf):
  1226. ri = relation[i] % order
  1227. if ri> 0 and relations[i] is not None: # make this entry zero if we can
  1228. for j in range(lf+1):
  1229. relation[j] = (relation[j] - ri*relations[i][j]) % order
  1230. else:
  1231. relation[i] = ri
  1232. if relation[i] > 0 and index == lf: # is this the index of the first nonzero entry?
  1233. index = i
  1234. if index == lf or relations[index] is not None: # the relation contains no new information
  1235. continue
  1236. # the relation contains new information
  1237. rinv = pow(relation[index],-1,order) # normalize the first nonzero entry
  1238. for j in range(index,lf+1):
  1239. relation[j] = rinv * relation[j] % order
  1240. relations[index] = relation
  1241. for i in range(lf): # subtract the new relation from the one for a
  1242. if relationa[i] > 0 and relations[i] is not None:
  1243. rbi = relationa[i]
  1244. for j in range(lf+1):
  1245. relationa[j] = (relationa[j] - rbi*relations[i][j]) % order
  1246. if relationa[i] > 0: # the index of the first nonzero entry
  1247. break # we do not need to reduce further at this point
  1248. else: # all unknowns are gone
  1249. #print(f"Success after {k} relations out of {lf}")
  1250. x = (order -relationa[lf]) % order
  1251. if pow(b,x,n) == a:
  1252. return x
  1253. raise ValueError("Index Calculus failed")
  1254. raise ValueError("Index Calculus failed")
  1255. def _discrete_log_pohlig_hellman(n, a, b, order=None, order_factors=None):
  1256. """
  1257. Pohlig-Hellman algorithm for computing the discrete logarithm of ``a`` to
  1258. the base ``b`` modulo ``n``.
  1259. In order to compute the discrete logarithm, the algorithm takes advantage
  1260. of the factorization of the group order. It is more efficient when the
  1261. group order factors into many small primes.
  1262. Examples
  1263. ========
  1264. >>> from sympy.ntheory.residue_ntheory import _discrete_log_pohlig_hellman
  1265. >>> _discrete_log_pohlig_hellman(251, 210, 71)
  1266. 197
  1267. See Also
  1268. ========
  1269. discrete_log
  1270. References
  1271. ==========
  1272. .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1273. Vanstone, S. A. (1997).
  1274. """
  1275. from .modular import crt
  1276. a %= n
  1277. b %= n
  1278. if order is None:
  1279. order = n_order(b, n)
  1280. if order_factors is None:
  1281. order_factors = factorint(order)
  1282. l = [0] * len(order_factors)
  1283. for i, (pi, ri) in enumerate(order_factors.items()):
  1284. for j in range(ri):
  1285. aj = pow(a * pow(b, -l[i], n), order // pi**(j + 1), n)
  1286. bj = pow(b, order // pi, n)
  1287. cj = discrete_log(n, aj, bj, pi, True)
  1288. l[i] += cj * pi**j
  1289. d, _ = crt([pi**ri for pi, ri in order_factors.items()], l)
  1290. return d
  1291. def discrete_log(n, a, b, order=None, prime_order=None):
  1292. """
  1293. Compute the discrete logarithm of ``a`` to the base ``b`` modulo ``n``.
  1294. This is a recursive function to reduce the discrete logarithm problem in
  1295. cyclic groups of composite order to the problem in cyclic groups of prime
  1296. order.
  1297. It employs different algorithms depending on the problem (subgroup order
  1298. size, prime order or not):
  1299. * Trial multiplication
  1300. * Baby-step giant-step
  1301. * Pollard's Rho
  1302. * Index Calculus
  1303. * Pohlig-Hellman
  1304. Examples
  1305. ========
  1306. >>> from sympy.ntheory import discrete_log
  1307. >>> discrete_log(41, 15, 7)
  1308. 3
  1309. References
  1310. ==========
  1311. .. [1] https://mathworld.wolfram.com/DiscreteLogarithm.html
  1312. .. [2] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
  1313. Vanstone, S. A. (1997).
  1314. """
  1315. from math import sqrt, log
  1316. n, a, b = as_int(n), as_int(a), as_int(b)
  1317. if n < 1:
  1318. raise ValueError("n should be positive")
  1319. if n == 1:
  1320. return 0
  1321. if order is None:
  1322. # Compute the order and its factoring in one pass
  1323. # order = totient(n), factors = factorint(order)
  1324. factors = {}
  1325. for px, kx in factorint(n).items():
  1326. if kx > 1:
  1327. if px in factors:
  1328. factors[px] += kx - 1
  1329. else:
  1330. factors[px] = kx - 1
  1331. for py, ky in factorint(px - 1).items():
  1332. if py in factors:
  1333. factors[py] += ky
  1334. else:
  1335. factors[py] = ky
  1336. order = 1
  1337. for px, kx in factors.items():
  1338. order *= px**kx
  1339. # Now the `order` is the order of the group and factors = factorint(order)
  1340. # The order of `b` divides the order of the group.
  1341. order_factors = {}
  1342. for p, e in factors.items():
  1343. i = 0
  1344. for _ in range(e):
  1345. if pow(b, order // p, n) == 1:
  1346. order //= p
  1347. i += 1
  1348. else:
  1349. break
  1350. if i < e:
  1351. order_factors[p] = e - i
  1352. if prime_order is None:
  1353. prime_order = isprime(order)
  1354. if order < 1000:
  1355. return _discrete_log_trial_mul(n, a, b, order)
  1356. elif prime_order:
  1357. # Shanks and Pollard rho are O(sqrt(order)) while index calculus is O(exp(2*sqrt(log(n)log(log(n)))))
  1358. # we compare the expected running times to determine the algorithm which is expected to be faster
  1359. if 4*sqrt(log(n)*log(log(n))) < log(order) - 10: # the number 10 was determined experimental
  1360. return _discrete_log_index_calculus(n, a, b, order)
  1361. elif order < 1000000000000:
  1362. # Shanks seems typically faster, but uses O(sqrt(order)) memory
  1363. return _discrete_log_shanks_steps(n, a, b, order)
  1364. return _discrete_log_pollard_rho(n, a, b, order)
  1365. return _discrete_log_pohlig_hellman(n, a, b, order, order_factors)
  1366. def quadratic_congruence(a, b, c, n):
  1367. r"""
  1368. Find the solutions to `a x^2 + b x + c \equiv 0 \pmod{n}`.
  1369. Parameters
  1370. ==========
  1371. a : int
  1372. b : int
  1373. c : int
  1374. n : int
  1375. A positive integer.
  1376. Returns
  1377. =======
  1378. list[int] :
  1379. A sorted list of solutions. If no solution exists, ``[]``.
  1380. Examples
  1381. ========
  1382. >>> from sympy.ntheory.residue_ntheory import quadratic_congruence
  1383. >>> quadratic_congruence(2, 5, 3, 7) # 2x^2 + 5x + 3 = 0 (mod 7)
  1384. [2, 6]
  1385. >>> quadratic_congruence(8, 6, 4, 15) # No solution
  1386. []
  1387. See Also
  1388. ========
  1389. polynomial_congruence : Solve the polynomial congruence
  1390. """
  1391. a = as_int(a)
  1392. b = as_int(b)
  1393. c = as_int(c)
  1394. n = as_int(n)
  1395. if n <= 1:
  1396. raise ValueError("n should be an integer greater than 1")
  1397. a %= n
  1398. b %= n
  1399. c %= n
  1400. if a == 0:
  1401. return linear_congruence(b, -c, n)
  1402. if n == 2:
  1403. # assert a == 1
  1404. roots = []
  1405. if c == 0:
  1406. roots.append(0)
  1407. if (b + c) % 2:
  1408. roots.append(1)
  1409. return roots
  1410. if gcd(2*a, n) == 1:
  1411. inv_a = invert(a, n)
  1412. b *= inv_a
  1413. c *= inv_a
  1414. if b % 2:
  1415. b += n
  1416. b >>= 1
  1417. return sorted((i - b) % n for i in sqrt_mod_iter(b**2 - c, n))
  1418. res = set()
  1419. for i in sqrt_mod_iter(b**2 - 4*a*c, 4*a*n):
  1420. q, rem = divmod(i - b, 2*a)
  1421. if rem == 0:
  1422. res.add(q % n)
  1423. return sorted(res)
  1424. def _valid_expr(expr):
  1425. """
  1426. return coefficients of expr if it is a univariate polynomial
  1427. with integer coefficients else raise a ValueError.
  1428. """
  1429. if not expr.is_polynomial():
  1430. raise ValueError("The expression should be a polynomial")
  1431. polynomial = Poly(expr)
  1432. if not polynomial.is_univariate:
  1433. raise ValueError("The expression should be univariate")
  1434. if not polynomial.domain == ZZ:
  1435. raise ValueError("The expression should should have integer coefficients")
  1436. return polynomial.all_coeffs()
  1437. def polynomial_congruence(expr, m):
  1438. """
  1439. Find the solutions to a polynomial congruence equation modulo m.
  1440. Parameters
  1441. ==========
  1442. expr : integer coefficient polynomial
  1443. m : positive integer
  1444. Examples
  1445. ========
  1446. >>> from sympy.ntheory import polynomial_congruence
  1447. >>> from sympy.abc import x
  1448. >>> expr = x**6 - 2*x**5 -35
  1449. >>> polynomial_congruence(expr, 6125)
  1450. [3257]
  1451. See Also
  1452. ========
  1453. sympy.polys.galoistools.gf_csolve : low level solving routine used by this routine
  1454. """
  1455. coefficients = _valid_expr(expr)
  1456. coefficients = [num % m for num in coefficients]
  1457. rank = len(coefficients)
  1458. if rank == 3:
  1459. return quadratic_congruence(*coefficients, m)
  1460. if rank == 2:
  1461. return quadratic_congruence(0, *coefficients, m)
  1462. if coefficients[0] == 1 and 1 + coefficients[-1] == sum(coefficients):
  1463. return nthroot_mod(-coefficients[-1], rank - 1, m, True)
  1464. return gf_csolve(coefficients, m)
  1465. def binomial_mod(n, m, k):
  1466. """Compute ``binomial(n, m) % k``.
  1467. Explanation
  1468. ===========
  1469. Returns ``binomial(n, m) % k`` using a generalization of Lucas'
  1470. Theorem for prime powers given by Granville [1]_, in conjunction with
  1471. the Chinese Remainder Theorem. The residue for each prime power
  1472. is calculated in time O(log^2(n) + q^4*log(n)log(p) + q^4*p*log^3(p)).
  1473. Parameters
  1474. ==========
  1475. n : an integer
  1476. m : an integer
  1477. k : a positive integer
  1478. Examples
  1479. ========
  1480. >>> from sympy.ntheory.residue_ntheory import binomial_mod
  1481. >>> binomial_mod(10, 2, 6) # binomial(10, 2) = 45
  1482. 3
  1483. >>> binomial_mod(17, 9, 10) # binomial(17, 9) = 24310
  1484. 0
  1485. References
  1486. ==========
  1487. .. [1] Binomial coefficients modulo prime powers, Andrew Granville,
  1488. Available: https://web.archive.org/web/20170202003812/http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf
  1489. """
  1490. if k < 1: raise ValueError('k is required to be positive')
  1491. # We decompose q into a product of prime powers and apply
  1492. # the generalization of Lucas' Theorem given by Granville
  1493. # to obtain binomial(n, k) mod p^e, and then use the Chinese
  1494. # Remainder Theorem to obtain the result mod q
  1495. if n < 0 or m < 0 or m > n: return 0
  1496. factorisation = factorint(k)
  1497. residues = [_binomial_mod_prime_power(n, m, p, e) for p, e in factorisation.items()]
  1498. return crt([p**pw for p, pw in factorisation.items()], residues, check=False)[0]
  1499. def _binomial_mod_prime_power(n, m, p, q):
  1500. """Compute ``binomial(n, m) % p**q`` for a prime ``p``.
  1501. Parameters
  1502. ==========
  1503. n : positive integer
  1504. m : a nonnegative integer
  1505. p : a prime
  1506. q : a positive integer (the prime exponent)
  1507. Examples
  1508. ========
  1509. >>> from sympy.ntheory.residue_ntheory import _binomial_mod_prime_power
  1510. >>> _binomial_mod_prime_power(10, 2, 3, 2) # binomial(10, 2) = 45
  1511. 0
  1512. >>> _binomial_mod_prime_power(17, 9, 2, 4) # binomial(17, 9) = 24310
  1513. 6
  1514. References
  1515. ==========
  1516. .. [1] Binomial coefficients modulo prime powers, Andrew Granville,
  1517. Available: https://web.archive.org/web/20170202003812/http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf
  1518. """
  1519. # Function/variable naming within this function follows Ref.[1]
  1520. # n!_p will be used to denote the product of integers <= n not divisible by
  1521. # p, with binomial(n, m)_p the same as binomial(n, m), but defined using
  1522. # n!_p in place of n!
  1523. modulo = pow(p, q)
  1524. def up_factorial(u):
  1525. """Compute (u*p)!_p modulo p^q."""
  1526. r = q // 2
  1527. fac = prod = 1
  1528. if r == 1 and p == 2 or 2*r + 1 in (p, p*p):
  1529. if q % 2 == 1: r += 1
  1530. modulo, div = pow(p, 2*r), pow(p, 2*r - q)
  1531. else:
  1532. modulo, div = pow(p, 2*r + 1), pow(p, (2*r + 1) - q)
  1533. for j in range(1, r + 1):
  1534. for mul in range((j - 1)*p + 1, j*p): # ignore jp itself
  1535. fac *= mul
  1536. fac %= modulo
  1537. bj_ = bj(u, j, r)
  1538. prod *= pow(fac, bj_, modulo)
  1539. prod %= modulo
  1540. if p == 2:
  1541. sm = u // 2
  1542. for j in range(1, r + 1): sm += j//2 * bj(u, j, r)
  1543. if sm % 2 == 1: prod *= -1
  1544. prod %= modulo//div
  1545. return prod % modulo
  1546. def bj(u, j, r):
  1547. """Compute the exponent of (j*p)!_p in the calculation of (u*p)!_p."""
  1548. prod = u
  1549. for i in range(1, r + 1):
  1550. if i != j: prod *= u*u - i*i
  1551. for i in range(1, r + 1):
  1552. if i != j: prod //= j*j - i*i
  1553. return prod // j
  1554. def up_plus_v_binom(u, v):
  1555. """Compute binomial(u*p + v, v)_p modulo p^q."""
  1556. prod = 1
  1557. div = invert(factorial(v), modulo)
  1558. for j in range(1, q):
  1559. b = div
  1560. for v_ in range(j*p + 1, j*p + v + 1):
  1561. b *= v_
  1562. b %= modulo
  1563. aj = u
  1564. for i in range(1, q):
  1565. if i != j: aj *= u - i
  1566. for i in range(1, q):
  1567. if i != j: aj //= j - i
  1568. aj //= j
  1569. prod *= pow(b, aj, modulo)
  1570. prod %= modulo
  1571. return prod
  1572. @recurrence_memo([1])
  1573. def factorial(v, prev):
  1574. """Compute v! modulo p^q."""
  1575. return v*prev[-1] % modulo
  1576. def factorial_p(n):
  1577. """Compute n!_p modulo p^q."""
  1578. u, v = divmod(n, p)
  1579. return (factorial(v) * up_factorial(u) * up_plus_v_binom(u, v)) % modulo
  1580. prod = 1
  1581. Nj, Mj, Rj = n, m, n - m
  1582. # e0 will be the p-adic valuation of binomial(n, m) at p
  1583. e0 = carry = eq_1 = j = 0
  1584. while Nj:
  1585. numerator = factorial_p(Nj % modulo)
  1586. denominator = factorial_p(Mj % modulo) * factorial_p(Rj % modulo) % modulo
  1587. Nj, (Mj, mj), (Rj, rj) = Nj//p, divmod(Mj, p), divmod(Rj, p)
  1588. carry = (mj + rj + carry) // p
  1589. e0 += carry
  1590. if j >= q - 1: eq_1 += carry
  1591. prod *= numerator * invert(denominator, modulo)
  1592. prod %= modulo
  1593. j += 1
  1594. mul = pow(1 if p == 2 and q >= 3 else -1, eq_1, modulo)
  1595. return (pow(p, e0, modulo) * mul * prod) % modulo