PowerModList
Every in with — all the values can take modulo .
PowerModList!PowerModList(a, s/r, m)every in with , ascendingenumeratio_power_mod_list(a, s/r, m)SymPynthroot_mod(pow(ZZ.convert(a), S(s/r).p, ZZ.convert(m)), S(s/r).q, m, True)PowerModList(a, k, m)an integer exponent gives the single value enumeratio_power_mod_list(a, k, m)SymPynthroot_mod(pow(ZZ.convert(a), S(k).p, ZZ.convert(m)), S(k).q, m, True)PowerModList(a, -1, m)the modular inverse , or when enumeratio_power_mod_list(a, -1, m)SymPynthroot_mod(pow(ZZ.convert(a), S(-1).p, ZZ.convert(m)), S(-1).q, m, True)Typed signatures
| Type | Package | Applies |
|---|---|---|
(integer, rational, integer) -> list<integer> | compute-engine | always |
(number, number, number) -> list<number> | number-theoryreplaces residues | always |
(number, number, number) -> list<number> | residuesreplaces compute-engine | always |
Details
- The problem splits over the prime powers of by the Chinese remainder theorem: a root mod is one root per channel , every combination, so the count is the product of the channel counts.
- Mod a prime the units are cyclic of order , so has exactly roots or none. One root is built Sylow subgroup by Sylow subgroup — only the primes dividing need a discrete log — so is never factored and a 30-digit prime costs a millisecond.
- Roots are Hensel-lifted up each prime power: a root with lifts uniquely; a singular one (the 2-adic channel of a square root, or ) lifts to all of its lifts or to none.
- The modulus has to be factored, by trial division and Pollard's rho under a step budget. A product of two large primes is out of reach, and the call stays unevaluated — which is the whole security of the Rabin cryptosystem.
- At most 100 000 roots are listed; past that the call stays unevaluated rather than build the list.
- Beyond Wolfram, a rational with is read in as , the image of ; a denominator sharing a factor with has no image, and the list is empty. See RationalReconstruction for the way back.
- Threads over lists in any argument.
- Over the Gaussian integers — beyond Wolfram, whose PowerModList takes integers only — factors into Gaussian prime powers: a split prime maps onto by , an inert has residue field and lifts by Hensel, and lifts by testing both residues.
Examples
7 more kept as data, checked against the oraclesBasic #
Scope #
the square roots of 1 modulo the product of the first 16 primes: one per sign over the 15 odd channels,
live ↗Applications #
Rabin decryption: knowing the factors of , the four square roots of the ciphertext include the message
live ↗Properties #
Possible issues #
a product of two 21-digit primes cannot be factored in budget, so even stays unevaluated — finding the other two roots is as hard as factoring
live ↗Neat examples #
the moduli with four or more square roots of 1 come in patterns: mod 24 every unit is one, since
live ↗About
| Examples | 37 |
|---|---|
| Checked against | Wolfram Language 26 agree10 differ1 errorSageMath 25 agree1 differ9 errorSymPy 26 agree1 differ9 errormathlib4 1 agreeOscar 1 agreeJulia 1 agreeRust 1 agree |
| Crosswalk | Wolfram LanguageSageMathSymPy |
Implementation
wolframpackages/oracle/src/mappings.tsSage reaches this through Zmod(m)(a).nth_root(b, all=True) (run.ts's SAGE_PREAMBLE); no one-liner in SymPy.
sagepackages/oracle/src/mappings.tsSage reaches this through Zmod(m)(a).nth_root(b, all=True) (run.ts's SAGE_PREAMBLE); no one-liner in SymPy.
sympypackages/oracle/src/mappings.tsx^r = a^s (mod m) is nthroot_mod's x^n = a (mod p) with n = r and a = pow(a, s, m) over ZZ, which takes a negative s through the modular inverse. SymPy takes integer residues, so a rational or Gaussian base is an error there. A list threads over the base only.
See also: PowerMod, ModularInverse, MultiplicativeOrder, PrimitiveRootList, RationalReconstruction