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

01 Apr, 2021
Given a number ‘n’ and a prime ‘p’, find square root of n under modulo p if it exists. Examples:  
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 the implementation of above algorithm.  
C++
Java
Python3
C#
PHP
Javascript
// 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) % modulusint 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 gcdint 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 eint convertx2e(int x, int& e){    e = 0;    while (x % 2 == 0)    {        x /= 2;        e++;    }    return x;} //  Main function for finding the modular square rootint 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 functionint 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);}
// Java program to implement Shanks// Tonelli algorithm for finding// Modular Square Rootsclass GFG{    static int z = 0;     // utility function to find// pow(base, exponent) % modulusstatic int pow1(int base1,    int exponent, int modulus){    int result = 1;    base1 = base1 % modulus;    while (exponent > 0)    {        if (exponent % 2 == 1)            result = (result * base1) % modulus;        exponent = exponent >> 1;        base1 = (base1 * base1) % modulus;    }    return result;} // utility function to find gcdstatic 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)static int order(int p, int b){    if (gcd(p, b) != 1)    {        System.out.println("p and b are" +                            "not co-prime.");        return -1;    }     // Initializing k with first    // odd prime number    int k = 3;    while (true)    {        if (pow1(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 estatic int convertx2e(int x){    z = 0;    while (x % 2 == 0)    {        x /= 2;        z++;    }    return x;} // Main function for finding// the modular square rootstatic int STonelli(int n, int p){    // a and p should be coprime for     // finding the modular square root    if (gcd(n, p) != 1)    {        System.out.println("a and p are not coprime");        return -1;    }     // If below expression return (p - 1) then modular    // square root is not possible    if (pow1(n, (p - 1) / 2, p) == (p - 1))    {        System.out.println("no sqrt possible");        return -1;    }     // expressing p - 1, in terms of     // s * 2^e, where s is odd number    int s, e;    s = convertx2e(p - 1);    e = z;     // 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 (pow1(q, (p - 1) / 2, p) == (p - 1))            break;    }     // Initializing variable x, b and g    int x = pow1(n, (s + 1) / 2, p);    int b = pow1(n, s, p);    int g = pow1(q, s, p);     int r = e;     // keep looping until b    // become 1 or m becomes 0    while (true)    {        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) == Math.pow(2, m))                break;        }        if (m == 0)            return x;         // updating value of x, g and b        // according to algorithm        x = (x * pow1(g, (int)Math.pow(2,                            r - m - 1), p)) % p;        g = pow1(g, (int)Math.pow(2, r - m), p);        b = (b * g) % p;         if (b == 1)            return x;        r = m;    }} // Driver codepublic static void main (String[] args){     int n = 2;     // p should be prime    int p = 113;     int x = STonelli(n, p);     if (x == -1)        System.out.println("Modular square" +                        "root is not exist\n");    else        System.out.println("Modular square root of " +                            n + " and " + p + " is " +                            x + "\n");}} // This code is contributed by mits
# Python3 program to implement Shanks Tonelli# algorithm for finding Modular Square Roots # utility function to find pow(base,# exponent) % modulusdef pow1(base, exponent, modulus):     result = 1;    base = base % modulus;    while (exponent > 0):        if (exponent % 2 == 1):            result = (result * base) % modulus;        exponent = int(exponent) >> 1;        base = (base * base) % modulus;     return result; # utility function to find gcddef gcd(a, b):    if (b == 0):        return a;    else:        return gcd(b, a % b); # Returns k such that b^k = 1 (mod p)def order(p, b):     if (gcd(p, b) != 1):        print("p and b are not co-prime.\n");        return -1;     # Initializing k with first    # odd prime number    k = 3;    while (True):        if (pow1(b, k, p) == 1):            return k;        k += 1; # 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 edef convertx2e(x):    z = 0;    while (x % 2 == 0):        x = x / 2;        z += 1;             return [x, z]; # Main function for finding the# modular square rootdef STonelli(n, p):     # a and p should be coprime for    # finding the modular square root    if (gcd(n, p) != 1):        print("a and p are not coprime\n");        return -1;     # If below expression return (p - 1) then    # modular square root is not possible    if (pow1(n, (p - 1) / 2, p) == (p - 1)):        print("no sqrt possible\n");        return -1;     # expressing p - 1, in terms of s * 2^e,    # where s is odd number    ar = convertx2e(p - 1);    s = ar[0];    e = ar[1];     # finding smallest q such that    # q ^ ((p - 1) / 2) (mod p) = p - 1    q = 2;    while (True):                 # q - 1 is in place of (-1 % p)        if (pow1(q, (p - 1) / 2, p) == (p - 1)):            break;        q += 1;     # Initializing variable x, b and g    x = pow1(n, (s + 1) / 2, p);    b = pow1(n, s, p);    g = pow1(q, s, p);     r = e;     # keep looping until b become    # 1 or m becomes 0    while (True):        m = 0;        while (m < r):            if (order(p, b) == -1):                return -1;             # finding m such that b^ (2^m) = 1            if (order(p, b) == pow(2, m)):                break;            m += 1;         if (m == 0):            return x;         # updating value of x, g and b        # according to algorithm        x = (x * pow1(g, pow(2, r - m - 1), p)) % p;        g = pow1(g, pow(2, r - m), p);        b = (b * g) % p;         if (b == 1):            return x;        r = m; # Driver Coden = 2; # p should be primep = 113; x = STonelli(n, p); if (x == -1):    print("Modular square root is not exist\n");else:    print("Modular square root of", n,          "and", p, "is", x);         # This code is contributed by mits
// C# program to implement Shanks// Tonelli algorithm for finding// Modular Square Rootsusing System; class GFG{     static int z=0;     // utility function to find// pow(base, exponent) % modulusstatic int pow1(int base1,        int exponent, int modulus){    int result = 1;    base1 = base1 % modulus;    while (exponent > 0)    {        if (exponent % 2 == 1)            result = (result * base1) % modulus;        exponent = exponent >> 1;        base1 = (base1 * base1) % modulus;    }    return result;} // utility function to find gcdstatic 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)static int order(int p, int b){    if (gcd(p, b) != 1)    {        Console.WriteLine("p and b are" +                            "not co-prime.");        return -1;    }     // Initializing k with    // first odd prime number    int k = 3;    while (true)    {        if (pow1(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 estatic int convertx2e(int x){    z = 0;    while (x % 2 == 0)    {        x /= 2;        z++;    }    return x;} // Main function for finding// the modular square rootstatic int STonelli(int n, int p){    // a and p should be coprime for    // finding the modular square root    if (gcd(n, p) != 1)    {        Console.WriteLine("a and p are not coprime");        return -1;    }     // If below expression return (p - 1) then    // modular square root is not possible    if (pow1(n, (p - 1) / 2, p) == (p - 1))    {        Console.WriteLine("no sqrt possible");        return -1;    }     // expressing p - 1, in terms of s * 2^e,    //  where s is odd number    int s, e;    s = convertx2e(p - 1);    e=z;     // 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 (pow1(q, (p - 1) / 2, p) == (p - 1))            break;    }     // Initializing variable x, b and g    int x = pow1(n, (s + 1) / 2, p);    int b = pow1(n, s, p);    int g = pow1(q, s, p);     int r = e;     // keep looping until b become    // 1 or m becomes 0    while (true)    {        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) == Math.Pow(2, m))                break;        }        if (m == 0)            return x;         // updating value of x, g and b         // according to algorithm        x = (x * pow1(g, (int)Math.Pow(2, r - m - 1), p)) % p;        g = pow1(g, (int)Math.Pow(2, r - m), p);        b = (b * g) % p;         if (b == 1)            return x;        r = m;    }} // Driver codestatic void Main(){    int n = 2;     // p should be prime    int p = 113;     int x = STonelli(n, p);     if (x == -1)        Console.WriteLine("Modular square root" +                            "is not exist\n");    else        Console.WriteLine("Modular square root of" +                        "{0} and {1} is {2}\n", n, p, x);}} // This code is contributed by mits
<?php// PHP program to implement Shanks Tonelli// algorithm for finding Modular Square Roots // utility function to find pow(base,// exponent) % modulusfunction pow1($base, $exponent, $modulus){    $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 gcdfunction gcd($a, $b){    if ($b == 0)        return $a;    else        return gcd($b, $a % $b);} // Returns k such that b^k = 1 (mod p)function order($p, $b){    if (gcd($p, $b) != 1)    {        print("p and b are not co-prime.\n");        return -1;    }     // Initializing k with first    // odd prime number    $k = 3;    while (1)    {        if (pow1($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 efunction convertx2e($x, &$e){    $e = 0;    while ($x % 2 == 0)    {        $x = (int)($x / 2);        $e++;    }    return $x;} // Main function for finding the// modular square rootfunction STonelli($n, $p){    // a and p should be coprime for    // finding the modular square root    if (gcd($n, $p) != 1)    {        print("a and p are not coprime\n");        return -1;    }     // If below expression return (p - 1) then    // modular square root is not possible    if (pow1($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    $e = 0;    $s = convertx2e($p - 1, $e);     // finding smallest q such that    // q ^ ((p - 1) / 2) (mod p) = p - 1    $q = 2;    for (; ; $q++)    {        // q - 1 is in place of (-1 % p)        if (pow1($q, ($p - 1) / 2, $p) == ($p - 1))            break;    }     // Initializing variable x, b and g    $x = pow1($n, ($s + 1) / 2, $p);    $b = pow1($n, $s, $p);    $g = pow1($q, $s, $p);     $r = $e;     // keep looping until b become    // 1 or m becomes 0    while (1)    {        $m = 0;        for (; $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 * pow1($g, pow(2, $r - $m - 1), $p)) % $p;        $g = pow1($g, pow(2, $r - $m), $p);        $b = ($b * $g) % $p;         if ($b == 1)            return $x;        $r = $m;    }} // Driver Code$n = 2; // p should be prime$p = 113; $x = STonelli($n, $p); if ($x == -1)    print("Modular square root is not exist\n");else    print("Modular square root of " .          "$n and $p is $x\n");     // This code is contributed by mits?>
<script> // JavaScript program to implement Shanks// Tonelli algorithm for finding// Modular Square Roots     let z = 0;       // utility function to find// pow(base, exponent) % modulusfunction pow1(base1,    exponent, modulus){    let result = 1;    base1 = base1 % modulus;    while (exponent > 0)    {        if (exponent % 2 == 1)            result = (result * base1) % modulus;        exponent = exponent >> 1;        base1 = (base1 * base1) % modulus;    }    return result;}   // utility function to find gcdfunction gcd(a, b){    if (b == 0)        return a;    else        return gcd(b, a % b);}   // Returns k such that b^k = 1 (mod p)function order(p, b){    if (gcd(p, b) != 1)    {        document.write("p and b are" +                            "not co-prime." + "<br/>");        return -1;    }       // Initializing k with first    // odd prime number    let k = 3;    while (true)    {        if (pow1(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 efunction convertx2e(x){    z = 0;    while (x % 2 == 0)    {        x /= 2;        z++;    }    return x;}   // Main function for finding// the modular square rootfunction STonelli(n, p){    // a and p should be coprime for     // finding the modular square root    if (gcd(n, p) != 1)    {        System.out.prletln("a and p are not coprime");        return -1;    }       // If below expression return (p - 1) then modular    // square root is not possible    if (pow1(n, (p - 1) / 2, p) == (p - 1))    {        document.write("no sqrt possible" + "<br/>");        return -1;    }       // expressing p - 1, in terms of     // s * 2^e, where s is odd number    let s, e;    s = convertx2e(p - 1);    e = z;       // finding smallest q such that q ^ ((p - 1) / 2)    // (mod p) = p - 1    let q;    for (q = 2; ; q++)    {        // q - 1 is in place of (-1 % p)        if (pow1(q, (p - 1) / 2, p) == (p - 1))            break;    }       // Initializing variable x, b and g    let x = pow1(n, (s + 1) / 2, p);    let b = pow1(n, s, p);    let g = pow1(q, s, p);       let r = e;       // keep looping until b    // become 1 or m becomes 0    while (true)    {        let 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) == Math.pow(2, m))                break;        }        if (m == 0)            return x;           // updating value of x, g and b        // according to algorithm        x = (x * pow1(g, Math.pow(2,                            r - m - 1), p)) % p;        g = pow1(g, Math.pow(2, r - m), p);        b = (b * g) % p;           if (b == 1)            return x;        r = m;    }} // Driver Code      let n = 2;       // p should be prime    let p = 113;       let x = STonelli(n, p);       if (x == -1)        document.write("Modular square" +                        "root is not exist\n");    else        document.write("Modular square root of " +                            n + " and " + p + " is " +                            x + "\n"); </script>
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.pdfFor detail of example (2, 113) see : http://www.math.vt.edu/people/brown/class_homepages/shanks_tonelli.pdfThis 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 
Mithun Kumar
chinmoy1997pal
Modular Arithmetic
Mathematical
Mathematical
Modular Arithmetic
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.