def quadratic_congruence(a, b, c, p): """ Find the solutions to ``a x**2 + b x + c = 0 mod p a : integer b : integer c : integer p : positive integer """ from sympy.polys.galoistools import linear_congruence a = as_int(a) b = as_int(b) c = as_int(c) p = as_int(p) a = a % p b = b % p c = c % p if a == 0: return linear_congruence(b, -c, p) if p == 2: roots = [] if c % 2 == 0: roots.append(0) if (a + b + c) % 2 == 0: roots.append(1) return roots if isprime(p): inv_a = mod_inverse(a, p) b *= inv_a c *= inv_a if b % 2 == 1: b = b + p d = ((b * b) // 4 - c) % p y = sqrt_mod(d, p, all_roots=True) res = set() for i in y: res.add((i - b // 2) % p) return sorted(res) y = sqrt_mod(b * b - 4 * a * c, 4 * a * p, all_roots=True) res = set() for i in y: root = linear_congruence(2 * a, i - b, 4 * a * p) for j in root: res.add(j % p) return sorted(res)
def test_gf_csolve(): assert gf_value([1, 7, 2, 4], 11) == 2204 assert linear_congruence(4, 3, 5) == [2] assert linear_congruence(0, 3, 5) == [] assert linear_congruence(6, 1, 4) == [] assert linear_congruence(0, 5, 5) == [0, 1, 2, 3, 4] assert linear_congruence(3, 12, 15) == [4, 9, 14] assert linear_congruence(6, 0, 18) == [0, 3, 6, 9, 12, 15] # with power = 1 assert csolve_prime([1, 3, 2, 17], 7) == [3] assert csolve_prime([1, 3, 1, 5], 5) == [0, 1] assert csolve_prime([3, 6, 9, 3], 3) == [0, 1, 2] # with power > 1 assert csolve_prime([1, 1, 223], 3, 4) == [4, 13, 22, 31, 40, 49, 58, 67, 76] assert csolve_prime([3, 5, 2, 25], 5, 3) == [16, 50, 99] assert csolve_prime([3, 2, 2, 49], 7, 3) == [147, 190, 234] assert gf_csolve([1, 1, 7], 189) == [13, 49, 76, 112, 139, 175] assert gf_csolve([1, 3, 4, 1, 30], 60) == [10, 30] assert gf_csolve([1, 1, 7], 15) == []