2 return pow(a, (p - 1) // 2, p)
5 assert legendre(n, p) == 1, "not a square (mod p)"
12 return pow(n, (p + 1) // 4, p)
14 if p - 1 == legendre(z, p):
17 r = pow(n, (q + 1) // 2, p)
21 while (t - 1) % p != 0:
27 b = pow(c, 1 << (m - i - 1), p)
34 H = 381704527450191606347421195235742637659723827441243208291869156144963
35 factors = [1504073, 20492753, 59833457464970183, 467795120187583723534280000348743236593] # all of them are coprime
37 # The Tonelli–Shanks algorithm is used in modular arithmetic to solve for
38 # r in a congruence of the form r^2 ≡ n (mod p), where p is a prime number.
39 # Note: it can be applied only if " Euler's criterion" is fullfiled or "Legendre symbol" = 1
40 if __name__ == '__main__':
41 ttest = [(H,factors[0]),(H,factors[1]), (H,factors[2]), (H,factors[3])]
43 print("=====================================================")
44 print("Legendre symbol: ", legendre(n, p))
46 assert (r * r - n) % p == 0
47 print("n = %d p = %d" % (n, p))
48 print("\t roots : %d %d" % (r, p - r))
60 # p2 = 59833457464970183:
64 # p3 = 467795120187583723534280000348743236593:
65 # 308269479959806774875048102517512730884
66 # 159525640227776948659231897831230505709