congruence-solver
Version:
Single variable linear and quadratic congruence solver
1 lines • 20.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/factor.ts","../src/gcd.ts","../src/inverse_mod.ts","../src/residues.ts","../src/linear_congruence.ts","../src/pow_mod.ts","../src/sqrt_mod.ts","../src/quadratic_congruence.ts"],"sourcesContent":["export {factor} from './factor';\nexport {gcd} from './gcd';\nexport {inverseMod} from './inverse_mod';\nexport {solveLinearCongruence} from './linear_congruence';\nexport {powMod} from './pow_mod';\nexport {solveQuadraticCongruence} from './quadratic_congruence';\nexport {ALL_RESIDUES, intersectResidues, NO_RESIDUES} from './residues';\nexport type {ResidueClasses} from './residues';\nexport {sqrtModPrime} from './sqrt_mod';\n","import assert from 'minimalistic-assert';\n\n/**\n * Returns the prime factors of the given positive integer in increasing order.\n */\nexport function factor(n: number): number[] {\n assert(n > 0 && n % 1 === 0);\n const factors: number[] = [];\n while (n % 2 === 0) {\n factors.push(2);\n n /= 2;\n }\n while (n % 3 === 0) {\n factors.push(3);\n n /= 3;\n }\n for (let i = 5; i * i <= n;) {\n while (n % i === 0) {\n factors.push(i);\n n /= i;\n }\n i += 2;\n while (n % i === 0) {\n factors.push(i);\n n /= i;\n }\n i += 4;\n }\n if (n > 1) factors.push(n);\n return factors;\n}\n","/**\n * Returns the greatest common divisor of a and b, or 0 if a = b = 0.\n */\nexport function gcd(a: number, b: number): number {\n while (b !== 0) {\n const t = b;\n b = a % b;\n a = t;\n }\n return Math.abs(a);\n}\n","/**\n * Computes a⁻¹ (mod m) with the extended Euclidean algorithm.\n * Returns a number between 0 and m - 1, or NaN if the inverse doesn't exist.\n *\n * In case strict = false, returns the smallest non-negative solution to the\n * a·x = gcd(a, m) (mod m) congruence. The result will be in the\n * [0, m / gcd(a, m) - 1] range.\n *\n * The inverse of each integer is 0 (mod 1), because a * 0 = 0 ≡ 1 (mod 1).\n */\nexport function inverseMod(a: number, m: number, strict = true): number {\n // a and m must be non-negative in order to the result to be correct\n if (m < 0) m = -m;\n if (a < 0) a = a % m + m;\n\n let x = 1, y = 0;\n while (m !== 0) {\n const r = a % m;\n const q = (a - r) / m;\n const t = x;\n\n a = m;\n m = r;\n x = y;\n y = t - q * y;\n }\n\n // After the loop\n // a = gcd(a₀, m₀)\n // m = 0\n // y = m₀ / gcd(a₀, m₀)\n // x = an inverse of a₀ (mod m₀), in the (-y, y) open interval\n // x + k·y is also solution for every k ∈ ℤ\n\n if (a !== 1 && strict) return NaN;\n return x >= 0 ? x : x + y;\n}\n","import {gcd} from './gcd';\nimport {inverseMod} from './inverse_mod';\n\n/**\n * Represents a set of residue classes with a common modulus.\n * Each residue is an integer in the range [0, mod - 1], inclusive.\n * The residue list is sorted in ascending order.\n *\n * For example, {res: [1, 2], mod: 5} denotes the set of integers n\n * such that n ≡ 1 (mod 5) or n ≡ 2 (mod 5).\n */\nexport interface ResidueClasses {\n readonly res: readonly number[];\n readonly mod: number;\n}\n\n/**\n * Empty residue class set.\n */\nexport const NO_RESIDUES: ResidueClasses = {\n res: [],\n mod: 1\n};\n\n/**\n * Residue classes representing all integers.\n */\nexport const ALL_RESIDUES: ResidueClasses = {\n res: [0],\n mod: 1\n};\n\n/**\n * Computes the intersection of multiple residue class sets.\n *\n * The result is a new residue class set that satisfies all the constraints of\n * the input residue classes. This corresponds to finding the minimal modulus\n * and the associated residues such that:\n * For each input rc[i],\n * x ≡ any element of rc[i].res (mod rc[i].mod)\n *\n * If no intersection exists (i.e., the constraints are incompatible),\n * the function returns an empty residue class.\n */\nexport function intersectResidues(...rc: ResidueClasses[]): ResidueClasses {\n let lastRes = [0], lastMod = 1;\n for (let {res, mod} of rc) {\n if (mod === 0) return NO_RESIDUES;\n if (mod < 0) mod = -mod;\n\n const g = gcd(lastMod, mod);\n const c = inverseMod(lastMod / g, mod / g) * lastMod / g;\n const newMod = lastMod * mod / g;\n const newRes = [];\n for (const r0 of lastRes) {\n for (const r1 of res) {\n const d = r1 - r0;\n if (d % g !== 0) continue;\n const r = (r0 + d * c) % newMod;\n newRes.push(r >= 0 ? r : r + newMod);\n }\n }\n lastRes = newRes;\n lastMod = newMod;\n }\n if (lastRes.length === 0) return NO_RESIDUES;\n return {res: lastRes.sort((a, b) => a - b), mod: lastMod};\n}\n","import {gcd} from './gcd';\nimport {inverseMod} from './inverse_mod';\nimport {NO_RESIDUES, ResidueClasses} from './residues';\n\n/**\n * Solves the congruence equation ax + b ≡ 0 (mod m).\n *\n * If the equation is solvable, returns a residue r and modulus m' such that\n * the complete solution set is given by x ≡ r (mod m'). If the equation has no\n * solution, returns an empty list for residues and sets m' to 1.\n */\nexport function solveLinearCongruence(\n a: number, b: number, m: number): ResidueClasses {\n if (m === 0) return NO_RESIDUES;\n const g = gcd(a, m);\n if (b % g !== 0) return NO_RESIDUES;\n m = Math.abs(m);\n const m1 = m / g;\n const x = ((m - b % m) / g * inverseMod(a / g, m1)) % m1;\n return {res: [x], mod: m1};\n}\n","/**\n * Computes (base ** exp) % mod. Returns an integer between 0 and mod - 1.\n *\n * Preconditions:\n * base, exp, mod ∈ ℤ\n * base² < 2**53\n * 0 ≤ exp < 2**31\n * 0 < mod² < 2**53\n */\nexport function powMod(base: number, exp: number, mod: number): number {\n let result = 1;\n while (exp > 0) {\n if (exp % 2) result = (result * base) % mod;\n base = (base * base) % mod;\n exp >>= 1;\n }\n return result < 0 ? result + mod : result;\n}\n","import assert from 'minimalistic-assert';\n\nimport {powMod} from './pow_mod';\n\n/**\n * Computes the square root of a modulo p using the Tonelli-Shanks algorithm.\n * Solves the congruence x² ≡ a (mod p) and returns the smallest non-negative\n * solution, or NaN if no solution exists.\n *\n * If the equation has solutions, they are symmetric modulo p. Specifically,\n * if x is a solution, then -x (or equivalently p-x) is also a solution.\n *\n * Preconditions:\n * - p must be a prime number.\n * - p ≤ 94906249 (to ensure that p² ≤ Number.MAX_SAFE_INTEGER, avoiding\n * incorrect results or infinite loops caused by floating-point rounding\n * errors).\n */\nexport function sqrtModPrime(a: number, p: number): number {\n p = Math.abs(p);\n assert(p <= 94906249);\n a %= p;\n if (a === 0) return 0;\n if (a < 0) a += p;\n if (p === 2 || a === 1) return 1;\n if (powMod(a, (p - 1) / 2, p) !== 1) return NaN;\n let q = p - 1;\n let s = 0;\n for (; q % 2 === 0; q /= 2) s++;\n // The solution is straightforward when s = 1, i.e. p ≡ 3 (mod 4)\n if (s === 1) {\n const x = powMod(a, (p + 1) / 4, p);\n return Math.min(x, p - x);\n }\n let nonResidue = 2;\n while (powMod(nonResidue, (p - 1) / 2, p) === 1) nonResidue++;\n let c = powMod(nonResidue, q, p);\n const f = powMod(a, (q - 1) / 2, p);\n let x = (f * a) % p;\n let t = (f * x) % p;\n while (t !== 1) {\n let i = 1;\n for (let n = (t * t) % p; n !== 1; n = (n * n) % p) i++;\n while (--s > i) c = (c * c) % p;\n x = (x * c) % p;\n c = (c * c) % p;\n t = (t * c) % p;\n }\n return Math.min(x, p - x);\n}\n","import {factor} from './factor';\nimport {inverseMod} from './inverse_mod';\nimport {solveLinearCongruence} from './linear_congruence';\nimport {ALL_RESIDUES, NO_RESIDUES, ResidueClasses} from './residues';\nimport {sqrtModPrime} from './sqrt_mod';\n\n/**\n * Solves ax² + bx + c ≡ 0 (mod p) where p is a prime.\n * Returns up to two residue classes.\n */\nexport function solveQuadraticCongruenceModPrime(\n a: number, b: number, c: number, p: number): ResidueClasses {\n a %= p;\n if (a === 0) return solveLinearCongruence(b, c, p);\n if (p < 0) p = -p;\n const inv = inverseMod(a + p, p);\n b = (b * inv) % p;\n c = (c * inv) % p;\n // p = 2 is a special case\n if (p === 2) {\n if (b === 0) return {res: [c], mod: 2};\n return c === 0 ? ALL_RESIDUES : NO_RESIDUES;\n }\n // x² + bx + c ≡ 0 (mod p) is equivalent to (x + b/2)² ≡ b²/4 - c (mod p)\n const bHalf = (b % 2 !== 0 ? b - p : b) / 2;\n const y = sqrtModPrime(bHalf * bHalf - c, p);\n if (y !== y) return NO_RESIDUES;\n if (y === 0) return {res: [(p - bHalf) % p], mod: p};\n const x1 = (p + y - bHalf) % p;\n const x2 = (p - y - bHalf) % p;\n return {res: x1 < x2 ? [x1, x2] : [x2, x1], mod: p};\n}\n\n/**\n * Solves the quadratic congruence equation ax² + bx + c ≡ 0 (mod pᵏ) where p is\n * a prime and k ∈ ℕ. Returns up to two residue classes. The modulus of the\n * return value is a power of p that may be less than pᵏ.\n *\n * The algorithm is based on Hensel lifting explained at\n * https://sites.millersville.edu/bikenaga/number-theory/prime-power-congruences/prime-power-congruences.html\n */\nexport function solveQuadraticCongruenceModPrimePower(\n a: number, b: number, c: number, p: number, k: number): ResidueClasses {\n // Step 0: handle the k = 0 case\n if (k === 0) return ALL_RESIDUES;\n\n // Step 1: solve the congruence (mod p)\n const solutionModP = solveQuadraticCongruenceModPrime(a, b, c, p);\n if (k === 1) return solutionModP;\n let {res: r, mod} = solutionModP;\n if (r.length === 0) return NO_RESIDUES;\n let res = r.concat() as number[];\n if (p < 0) p = -p;\n\n // If all integers are solutions modulo 2, Hensel lifting needs to be done for\n // x ≡ 0 (mod 2) and x ≡ 1 (mod 2) separately.\n if (mod === 1 && p === 2) [res, mod] = [[0, 1], 2];\n\n // Step 2\n //\n // For each solution x (mod p ** exp)\n // While p | 2ax + b, apply the corresponding case of the Hensel lifting\n // algorithm to calculate the lifted solution (mod p ** (exp + 1)).\n //\n // There is an 1:1 relationship between the original and the lifted solutions.\n let exp = 1;\n let pp = p;\n if (mod > 1) {\n for (let j = 0; j < res.length; j++) {\n let deriv: number;\n let x = res[j];\n pp = p;\n // The derivative is ≠0 up to the same exponent for each residue.\n for (exp = 1; exp < k && (deriv = (2 * a * x + b) % p) !== 0; exp++) {\n const value = (a * x + b) * x + c;\n x += pp * ((inverseMod(p - deriv, p) * (value / pp)) % p);\n pp *= p;\n x %= pp;\n }\n res[j] = x < 0 ? x + pp : x;\n }\n res.sort((a, b) => a - b);\n mod = pp;\n }\n\n // Step 3\n //\n // From now on p ∤ 2ax + b.\n //\n // Apply the corresponding case of the Hensel lifting algorithm case to get\n // the solutions for the next power of p until reaching pᵏ. While there is an\n // 1:n relationship between the original and the lifted solutions, the total\n // number of the latter won't exceed two modulo a suitable power of p. It's\n // enough to find 3 solutions to determine the new modulus.\n for (; exp < k; exp++) {\n const newRes: number[] = [];\n const nextPp = pp * p;\n outerloop: for (let i = 0; i < pp; i += mod) {\n for (let x of res) {\n x += i;\n if (((a * x + b) * x + c) % nextPp === 0) {\n if (newRes.push(x) > 2) break outerloop;\n }\n }\n }\n res = newRes;\n\n // Normalize the result. Find the appropriate modulus for which there are at\n // most 2 residues.\n if (res.length === 0) return NO_RESIDUES;\n if (res.length === 2 && pp === 2) {\n mod = 1;\n res.length = 1;\n } else if (res.length <= 2) {\n mod = pp;\n } else if (res[1] - res[0] === res[2] - res[1]) {\n mod = res[1] - res[0];\n res.length = 1;\n } else {\n mod = res[2] - res[0];\n res.length = 2;\n }\n pp = nextPp;\n }\n\n return {res, mod};\n}\n\n/**\n * Solves the quadratic congruence equation ax² + bx + c ≡ 0 (mod m).\n *\n * The modulus can be specified either as a number or a list of monotonously\n * growing positive prime factors.\n *\n * Number of results ≤ 2 ** (number of distinct prime factors).\n */\nexport function solveQuadraticCongruence(\n a: number, b: number, c: number, m: number|number[]): ResidueClasses {\n if (m === 0) return NO_RESIDUES;\n const modFactors = Array.isArray(m) ? m : factor(m);\n let res = [0];\n let mod = 1;\n // Step 1: Split the modulus to the product of prime factors.\n let p = modFactors[0];\n let k = 1;\n for (let i = 1; i <= modFactors.length; i++) {\n if (modFactors[i] !== p) {\n // Step 2: Solve the congruence (mod pᵏ)\n const {res: fRes, mod: fMod} =\n solveQuadraticCongruenceModPrimePower(a, b, c, p, k);\n // Step 3: Combine the solutions using the Chinese remainder theorem.\n if (fRes.length === 0) return NO_RESIDUES;\n if (fMod > 1) {\n const coeff = (inverseMod(mod, fMod) + fMod) * mod;\n mod *= fMod;\n const newRes: number[] = [];\n for (const x of res) {\n const c = x + (mod - x) * coeff;\n for (const y of fRes) {\n newRes.push((c + y * coeff) % mod);\n }\n }\n res = newRes;\n }\n p = modFactors[i];\n k = 1;\n } else {\n k++;\n }\n }\n return {res: res.sort((a, b) => a - b), mod};\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,EAAA,gBAAAC,EAAA,WAAAC,EAAA,QAAAC,EAAA,sBAAAC,EAAA,eAAAC,EAAA,WAAAC,EAAA,0BAAAC,EAAA,6BAAAC,EAAA,iBAAAC,IAAA,eAAAC,EAAAZ,GCAA,IAAAa,EAAmB,oCAKZ,SAASC,EAAOC,EAAqB,IAC1C,EAAAC,SAAOD,EAAI,GAAKA,EAAI,IAAM,CAAC,EAC3B,IAAME,EAAoB,CAAC,EAC3B,KAAOF,EAAI,IAAM,GACfE,EAAQ,KAAK,CAAC,EACdF,GAAK,EAEP,KAAOA,EAAI,IAAM,GACfE,EAAQ,KAAK,CAAC,EACdF,GAAK,EAEP,QAASG,EAAI,EAAGA,EAAIA,GAAKH,GAAI,CAC3B,KAAOA,EAAIG,IAAM,GACfD,EAAQ,KAAKC,CAAC,EACdH,GAAKG,EAGP,IADAA,GAAK,EACEH,EAAIG,IAAM,GACfD,EAAQ,KAAKC,CAAC,EACdH,GAAKG,EAEPA,GAAK,CACP,CACA,OAAIH,EAAI,GAAGE,EAAQ,KAAKF,CAAC,EAClBE,CACT,CC3BO,SAASE,EAAIC,EAAWC,EAAmB,CAChD,KAAOA,IAAM,GAAG,CACd,IAAMC,EAAID,EACVA,EAAID,EAAIC,EACRD,EAAIE,CACN,CACA,OAAO,KAAK,IAAIF,CAAC,CACnB,CCAO,SAASG,EAAWC,EAAWC,EAAWC,EAAS,GAAc,CAElED,EAAI,IAAGA,EAAI,CAACA,GACZD,EAAI,IAAGA,EAAIA,EAAIC,EAAIA,GAEvB,IAAIE,EAAI,EAAGC,EAAI,EACf,KAAOH,IAAM,GAAG,CACd,IAAMI,EAAIL,EAAIC,EACRK,GAAKN,EAAIK,GAAKJ,EACdM,EAAIJ,EAEVH,EAAIC,EACJA,EAAII,EACJF,EAAIC,EACJA,EAAIG,EAAID,EAAIF,CACd,CASA,OAAIJ,IAAM,GAAKE,EAAe,IACvBC,GAAK,EAAIA,EAAIA,EAAIC,CAC1B,CCjBO,IAAMI,EAA8B,CACzC,IAAK,CAAC,EACN,IAAK,CACP,EAKaC,EAA+B,CAC1C,IAAK,CAAC,CAAC,EACP,IAAK,CACP,EAcO,SAASC,KAAqBC,EAAsC,CACzE,IAAIC,EAAU,CAAC,CAAC,EAAGC,EAAU,EAC7B,OAAS,CAAC,IAAAC,EAAK,IAAAC,CAAG,IAAKJ,EAAI,CACzB,GAAII,IAAQ,EAAG,OAAOP,EAClBO,EAAM,IAAGA,EAAM,CAACA,GAEpB,IAAMC,EAAIC,EAAIJ,EAASE,CAAG,EACpBG,EAAIC,EAAWN,EAAUG,EAAGD,EAAMC,CAAC,EAAIH,EAAUG,EACjDI,EAASP,EAAUE,EAAMC,EACzBK,EAAS,CAAC,EAChB,QAAWC,KAAMV,EACf,QAAWW,KAAMT,EAAK,CACpB,IAAMU,EAAID,EAAKD,EACf,GAAIE,EAAIR,IAAM,EAAG,SACjB,IAAMS,GAAKH,EAAKE,EAAIN,GAAKE,EACzBC,EAAO,KAAKI,GAAK,EAAIA,EAAIA,EAAIL,CAAM,CACrC,CAEFR,EAAUS,EACVR,EAAUO,CACZ,CACA,OAAIR,EAAQ,SAAW,EAAUJ,EAC1B,CAAC,IAAKI,EAAQ,KAAK,CAACc,EAAGC,IAAMD,EAAIC,CAAC,EAAG,IAAKd,CAAO,CAC1D,CCxDO,SAASe,EACZC,EAAWC,EAAWC,EAA2B,CACnD,GAAIA,IAAM,EAAG,OAAOC,EACpB,IAAMC,EAAIC,EAAIL,EAAGE,CAAC,EAClB,GAAID,EAAIG,IAAM,EAAG,OAAOD,EACxBD,EAAI,KAAK,IAAIA,CAAC,EACd,IAAMI,EAAKJ,EAAIE,EAEf,MAAO,CAAC,IAAK,EADDF,EAAID,EAAIC,GAAKE,EAAIG,EAAWP,EAAII,EAAGE,CAAE,EAAKA,CACvC,EAAG,IAAKA,CAAE,CAC3B,CCXO,SAASE,EAAOC,EAAcC,EAAaC,EAAqB,CACrE,IAAIC,EAAS,EACb,KAAOF,EAAM,GACPA,EAAM,IAAGE,EAAUA,EAASH,EAAQE,GACxCF,EAAQA,EAAOA,EAAQE,EACvBD,IAAQ,EAEV,OAAOE,EAAS,EAAIA,EAASD,EAAMC,CACrC,CCjBA,IAAAC,EAAmB,oCAkBZ,SAASC,EAAaC,EAAWC,EAAmB,CAIzD,GAHAA,EAAI,KAAK,IAAIA,CAAC,KACd,EAAAC,SAAOD,GAAK,QAAQ,EACpBD,GAAKC,EACDD,IAAM,EAAG,MAAO,GAEpB,GADIA,EAAI,IAAGA,GAAKC,GACZA,IAAM,GAAKD,IAAM,EAAG,MAAO,GAC/B,GAAIG,EAAOH,GAAIC,EAAI,GAAK,EAAGA,CAAC,IAAM,EAAG,MAAO,KAC5C,IAAIG,EAAIH,EAAI,EACRI,EAAI,EACR,KAAOD,EAAI,IAAM,EAAGA,GAAK,EAAGC,IAE5B,GAAIA,IAAM,EAAG,CACX,IAAMC,EAAIH,EAAOH,GAAIC,EAAI,GAAK,EAAGA,CAAC,EAClC,OAAO,KAAK,IAAIK,EAAGL,EAAIK,CAAC,CAC1B,CACA,IAAIC,EAAa,EACjB,KAAOJ,EAAOI,GAAaN,EAAI,GAAK,EAAGA,CAAC,IAAM,GAAGM,IACjD,IAAIC,EAAIL,EAAOI,EAAYH,EAAGH,CAAC,EACzBQ,EAAIN,EAAOH,GAAII,EAAI,GAAK,EAAGH,CAAC,EAC9BK,EAAKG,EAAIT,EAAKC,EACdS,EAAKD,EAAIH,EAAKL,EAClB,KAAOS,IAAM,GAAG,CACd,IAAIC,EAAI,EACR,QAASC,EAAKF,EAAIA,EAAKT,EAAGW,IAAM,EAAGA,EAAKA,EAAIA,EAAKX,EAAGU,IACpD,KAAO,EAAEN,EAAIM,GAAGH,EAAKA,EAAIA,EAAKP,EAC9BK,EAAKA,EAAIE,EAAKP,EACdO,EAAKA,EAAIA,EAAKP,EACdS,EAAKA,EAAIF,EAAKP,CAChB,CACA,OAAO,KAAK,IAAIK,EAAGL,EAAIK,CAAC,CAC1B,CCvCO,SAASO,EACZC,EAAWC,EAAWC,EAAWC,EAA2B,CAE9D,GADAH,GAAKG,EACDH,IAAM,EAAG,OAAOI,EAAsBH,EAAGC,EAAGC,CAAC,EAC7CA,EAAI,IAAGA,EAAI,CAACA,GAChB,IAAME,EAAMC,EAAWN,EAAIG,EAAGA,CAAC,EAI/B,GAHAF,EAAKA,EAAII,EAAOF,EAChBD,EAAKA,EAAIG,EAAOF,EAEZA,IAAM,EACR,OAAIF,IAAM,EAAU,CAAC,IAAK,CAACC,CAAC,EAAG,IAAK,CAAC,EAC9BA,IAAM,EAAIK,EAAeC,EAGlC,IAAMC,GAASR,EAAI,IAAM,EAAIA,EAAIE,EAAIF,GAAK,EACpCS,EAAIC,EAAaF,EAAQA,EAAQP,EAAGC,CAAC,EAC3C,GAAIO,IAAMA,EAAG,OAAOF,EACpB,GAAIE,IAAM,EAAG,MAAO,CAAC,IAAK,EAAEP,EAAIM,GAASN,CAAC,EAAG,IAAKA,CAAC,EACnD,IAAMS,GAAMT,EAAIO,EAAID,GAASN,EACvBU,GAAMV,EAAIO,EAAID,GAASN,EAC7B,MAAO,CAAC,IAAKS,EAAKC,EAAK,CAACD,EAAIC,CAAE,EAAI,CAACA,EAAID,CAAE,EAAG,IAAKT,CAAC,CACpD,CAUO,SAASW,EACZd,EAAWC,EAAWC,EAAWC,EAAWY,EAA2B,CAEzE,GAAIA,IAAM,EAAG,OAAOR,EAGpB,IAAMS,EAAejB,EAAiCC,EAAGC,EAAGC,EAAGC,CAAC,EAChE,GAAIY,IAAM,EAAG,OAAOC,EACpB,GAAI,CAAC,IAAKC,EAAG,IAAAC,CAAG,EAAIF,EACpB,GAAIC,EAAE,SAAW,EAAG,OAAOT,EAC3B,IAAIW,EAAMF,EAAE,OAAO,EACfd,EAAI,IAAGA,EAAI,CAACA,GAIZe,IAAQ,GAAKf,IAAM,IAAG,CAACgB,EAAKD,CAAG,EAAI,CAAC,CAAC,EAAG,CAAC,EAAG,CAAC,GASjD,IAAIE,EAAM,EACNC,EAAKlB,EACT,GAAIe,EAAM,EAAG,CACX,QAASI,EAAI,EAAGA,EAAIH,EAAI,OAAQG,IAAK,CACnC,IAAIC,EACAC,EAAIL,EAAIG,CAAC,EAGb,IAFAD,EAAKlB,EAEAiB,EAAM,EAAGA,EAAML,IAAMQ,GAAS,EAAIvB,EAAIwB,EAAIvB,GAAKE,KAAO,EAAGiB,IAAO,CACnE,IAAMK,GAASzB,EAAIwB,EAAIvB,GAAKuB,EAAItB,EAChCsB,GAAKH,GAAOf,EAAWH,EAAIoB,EAAOpB,CAAC,GAAKsB,EAAQJ,GAAOlB,GACvDkB,GAAMlB,EACNqB,GAAKH,CACP,CACAF,EAAIG,CAAC,EAAIE,EAAI,EAAIA,EAAIH,EAAKG,CAC5B,CACAL,EAAI,KAAK,CAACnB,EAAGC,IAAMD,EAAIC,CAAC,EACxBiB,EAAMG,CACR,CAWA,KAAOD,EAAML,EAAGK,IAAO,CACrB,IAAMM,EAAmB,CAAC,EACpBC,EAASN,EAAKlB,EACpByB,EAAW,QAASC,EAAI,EAAGA,EAAIR,EAAIQ,GAAKX,EACtC,QAASM,KAAKL,EAEZ,GADAK,GAAKK,IACC7B,EAAIwB,EAAIvB,GAAKuB,EAAItB,GAAKyB,IAAW,GACjCD,EAAO,KAAKF,CAAC,EAAI,EAAG,MAAMI,EAQpC,GAJAT,EAAMO,EAIFP,EAAI,SAAW,EAAG,OAAOX,EACzBW,EAAI,SAAW,GAAKE,IAAO,GAC7BH,EAAM,EACNC,EAAI,OAAS,GACJA,EAAI,QAAU,EACvBD,EAAMG,EACGF,EAAI,CAAC,EAAIA,EAAI,CAAC,IAAMA,EAAI,CAAC,EAAIA,EAAI,CAAC,GAC3CD,EAAMC,EAAI,CAAC,EAAIA,EAAI,CAAC,EACpBA,EAAI,OAAS,IAEbD,EAAMC,EAAI,CAAC,EAAIA,EAAI,CAAC,EACpBA,EAAI,OAAS,GAEfE,EAAKM,CACP,CAEA,MAAO,CAAC,IAAAR,EAAK,IAAAD,CAAG,CAClB,CAUO,SAASY,EACZ9B,EAAWC,EAAWC,EAAW6B,EAAoC,CACvE,GAAIA,IAAM,EAAG,OAAOvB,EACpB,IAAMwB,EAAa,MAAM,QAAQD,CAAC,EAAIA,EAAIE,EAAOF,CAAC,EAC9CZ,EAAM,CAAC,CAAC,EACRD,EAAM,EAENf,EAAI6B,EAAW,CAAC,EAChBjB,EAAI,EACR,QAASc,EAAI,EAAGA,GAAKG,EAAW,OAAQH,IACtC,GAAIG,EAAWH,CAAC,IAAM1B,EAAG,CAEvB,GAAM,CAAC,IAAK+B,EAAM,IAAKC,CAAI,EACvBrB,EAAsCd,EAAGC,EAAGC,EAAGC,EAAGY,CAAC,EAEvD,GAAImB,EAAK,SAAW,EAAG,OAAO1B,EAC9B,GAAI2B,EAAO,EAAG,CACZ,IAAMC,GAAS9B,EAAWY,EAAKiB,CAAI,EAAIA,GAAQjB,EAC/CA,GAAOiB,EACP,IAAMT,EAAmB,CAAC,EAC1B,QAAWF,KAAKL,EAAK,CACnB,IAAMjB,EAAIsB,GAAKN,EAAMM,GAAKY,EAC1B,QAAW1B,KAAKwB,EACdR,EAAO,MAAMxB,EAAIQ,EAAI0B,GAASlB,CAAG,CAErC,CACAC,EAAMO,CACR,CACAvB,EAAI6B,EAAWH,CAAC,EAChBd,EAAI,CACN,MACEA,IAGJ,MAAO,CAAC,IAAKI,EAAI,KAAK,CAACnB,EAAGC,IAAMD,EAAIC,CAAC,EAAG,IAAAiB,CAAG,CAC7C","names":["index_exports","__export","ALL_RESIDUES","NO_RESIDUES","factor","gcd","intersectResidues","inverseMod","powMod","solveLinearCongruence","solveQuadraticCongruence","sqrtModPrime","__toCommonJS","import_minimalistic_assert","factor","n","assert","factors","i","gcd","a","b","t","inverseMod","a","m","strict","x","y","r","q","t","NO_RESIDUES","ALL_RESIDUES","intersectResidues","rc","lastRes","lastMod","res","mod","g","gcd","c","inverseMod","newMod","newRes","r0","r1","d","r","a","b","solveLinearCongruence","a","b","m","NO_RESIDUES","g","gcd","m1","inverseMod","powMod","base","exp","mod","result","import_minimalistic_assert","sqrtModPrime","a","p","assert","powMod","q","s","x","nonResidue","c","f","t","i","n","solveQuadraticCongruenceModPrime","a","b","c","p","solveLinearCongruence","inv","inverseMod","ALL_RESIDUES","NO_RESIDUES","bHalf","y","sqrtModPrime","x1","x2","solveQuadraticCongruenceModPrimePower","k","solutionModP","r","mod","res","exp","pp","j","deriv","x","value","newRes","nextPp","outerloop","i","solveQuadraticCongruence","m","modFactors","factor","fRes","fMod","coeff"]}