1 # derived from: http://eli.thegreenplace.net/2009/03/07/computing-square-roots-in-python
3 # Compute the Legendre symbol a|p using Euler's criterion.
4 # p is a prime, a is relatively prime to p (if p divides a,
6 legendresymbol(a, p, r) {
13 # Find a quadratic residue (mod p) of 'a'. p must be an
16 # Solve the congruence of the form:
18 # And returns x. Node that p - x is also a root.
20 # 0 is returned if no square root exists for these
23 # The Tonelli-Shanks algorithm is used (except
24 # for some simple cases in which the solution is known
27 if(legendresymbol(a, p) != 1)
37 # Partition p-1 to s * 2^e for an odd s (i.e.
38 # reduce all the powers of 2 from p-1)
46 # Find some 'n' with a legendre symbol n|p = -1.
47 # Shouldn't take long.
49 while(legendresymbol(n, p) != -1)
52 # x is a guess of the square root that gets better
53 # with each iteration.
54 # b is the "fudge factor" - by now much we're off
55 # with the guess. The invariant x^2 == a*b (mod p)
56 # is maintained throughout the loop.
57 # g is used for successive powers of n to update
59 # e is the exponent - decreases with each update
90 # modular inverse square-root