# Find Square Root under Modulo p | Set 2 (Shanks Tonelli algorithm)

Given a number ‘n’ and a prime ‘p’, find square root of n under modulo p if it exists.

```Input: n = 2, p = 113
Output: 62
62^2 = 3844  and  3844 % 113 = 2

Input:  n = 2, p = 7
Output: 3 or 4
3 and 4 both are square roots of 2 under modulo
7 because (3*3) % 7 = 2 and (4*4) % 7 = 2

Input:  n = 2, p = 5
Output: Square root doesn't exist```

We have discussed Euler’s criterion to check if square root exists or not. We have also discussed a solution that works only when p is in form of 4*i + 3

In this post, Shank Tonelli’s algorithm is discussed that works for all types of inputs.

Algorithm steps to find modular square root using shank Tonelli’s algorithm :

1) Calculate n ^ ((p – 1) / 2) (mod p), it must be 1 or p-1, if it is p-1, then modular square root is not possible.

2) Then after write p-1 as (s * 2^e) for some integer s and e, where s must be an odd number and both s and e should be positive.

3) Then find a number q such that q ^ ((p – 1) / 2) (mod p) = -1

4) Initialize variable x, b, g and r by following values

```   x = n ^ ((s + 1) / 2 (first guess of square root)
b = n ^ s
g = q ^ s
r = e   (exponent e will decrease after each updation) ```

5) Now loop until m > 0 and update value of x, which will be our final answer.

```   Find least integer m such that b^(2^m) = 1(mod p)  and  0 <= m <= r – 1
If m = 0, then we found correct answer and return x as result
Else update x, b, g, r as below
x = x * g ^ (2 ^ (r – m - 1))
b = b * g ^(2 ^ (r - m))
g = g ^ (2 ^ (r - m))
r = m ```

so if m becomes 0 or b becomes 1, we terminate and print the result. This loop guarantees to terminate because value of m is decreased each time after updation.

Following is C++ implementation of above algorithm.

```// C++ program to implement Shanks Tonelli algorithm for
// finding Modular  Square Roots
#include <bits/stdc++.h>
using namespace std;

//  utility function to find pow(base, exponent) % modulus
int pow(int base, int exponent, int modulus)
{
int result = 1;
base = base % modulus;
while (exponent > 0)
{
if (exponent % 2 == 1)
result = (result * base)% modulus;
exponent = exponent >> 1;
base = (base * base) % modulus;
}
return result;
}

//  utility function to find gcd
int gcd(int a, int b)
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}

//  Returns k such that b^k = 1 (mod p)
int order(int p, int b)
{
if (gcd(p, b) != 1)
{
printf("p and b are not co-prime.\n");
return -1;
}

//  Initializing k with first odd prime number
int k = 3;
while (1)
{
if (pow(b, k, p) == 1)
return k;
k++;
}
}

//  function return  p - 1 (= x argument) as  x * 2^e,
//  where x will be odd  sending e as reference because
//  updation is needed in actual e
int convertx2e(int x, int& e)
{
e = 0;
while (x % 2 == 0)
{
x /= 2;
e++;
}
return x;
}

//  Main function for finding the modular square root
int STonelli(int n, int p)
{
//  a and p should be coprime for finding the modular
// square root
if (gcd(n, p) != 1)
{
printf("a and p are not coprime\n");
return -1;
}

//  If below expression return (p - 1)  then modular
// square root is not possible
if (pow(n, (p - 1) / 2, p) == (p - 1))
{
printf("no sqrt possible\n");
return -1;
}

//  expressing p - 1, in terms of s * 2^e,  where s
// is odd number
int s, e;
s = convertx2e(p - 1, e);

//  finding smallest q such that q ^ ((p - 1) / 2)
//  (mod p) = p - 1
int q;
for (q = 2; ; q++)
{
// q - 1 is in place of  (-1 % p)
if (pow(q, (p - 1) / 2, p) == (p - 1))
break;
}

//  Initializing variable x, b and g
int x = pow(n, (s + 1) / 2, p);
int b = pow(n, s, p);
int g = pow(q, s, p);

int r = e;

// keep looping until b become 1 or m becomes 0
while (1)
{
int m;
for (m = 0; m < r; m++)
{
if (order(p, b) == -1)
return -1;

//  finding m such that b^ (2^m) = 1
if (order(p, b) == pow(2, m))
break;
}
if (m == 0)
return x;

// updating value of x, g and b according to
// algorithm
x = (x * pow(g, pow(2, r - m - 1), p)) % p;
g = pow(g, pow(2, r - m), p);
b = (b * g) % p;

if (b == 1)
return x;
r = m;
}
}

//  driver program to test above function
int main()
{
int n = 2;

// p should be prime
int p = 113;

int x = STonelli(n, p);

if (x == -1)
printf("Modular square root is not exist\n");
else
printf("Modular square root of %d and %d is %d\n",
n, p, x);
}
```

Output :

`Modular square root of 2 and 113 is 62`

For more detail about above algorithm please visit :
http://cs.indstate.edu/~sgali1/Shanks_Tonelli.pdf

For detail of example (2, 113) see :
http://www.math.vt.edu/people/brown/class_homepages/shanks_tonelli.pdf

This article is contributed by Utkarsh Trivedi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

# GATE CS Corner    Company Wise Coding Practice

3 Average Difficulty : 3/5.0
Based on 1 vote(s)

Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.