This problem on codechef motivated me to implement tonelli-shanks.
Given non-zero integar n and prime number p, It finds R such that,
(R)^2 congruence n (mod p)
Input: n, p Goal: R, where (R)^2 ≡ n (mod p); If solution exists else -1
-
Check if solution exists using Euler's criterion. Return -1 if not.
-
Find
Q and Ssuch thatp - 1 = Q * (2)^S
divide p - 1 by 2 until it's modulo 2 is not equal to 0. Keep count number of division, store it as
S, remaining value (ofp-1) isQ.
- Find smallest
zwhich is quadratic non-residue.
continue
i = 2 to (p-1)until euler's criterion (i, p) is1. Storez = iat end.
- Define some variables
m = S
c = (z)^Q
t = (n)^Q
R = (n)^((Q+1)/2)Note: Make sure all operations don't go beyond
p. For example, (3)^3 andp = 10=> ans =[[[[(1 * 3)%10]*3]%10]*3]%10
- Infinite loop,
- if
t = 0, return0 - if
t = 1, returnR - For i =
(1 to m - 1), such(t)^((2)^i) % p = 1
Note: Operations must not go beyond
p.
b = (c)^((2)^(M - i - 1))M = ic = (b)^2 % pt = t * (b)^2 % pR = (R * b) % p