fn mod_sqrt_tonelli_shanks(&self, p: &BigInt) -> BigInt {
        // Break p-1 into s*2^e such that s is odd.
        let mut s = BigInt {
            nat: p.nat.clone() - 1u32,
            sign: Natural,
        };
        
        let e = s.nat.trailling_zeros();
        s.nat.shr_inner(&e);

        // find some non-square n
        let mut n = BigInt::from(2u32);
        while n.jacobi(p) != Some(-1) {
            n.nat.add_inner_basic(&1u32);
        }

        // Core of the Tonelli-Shanks algorithm. Follows the description in
        // section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra
        // Brown:
        // https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf
        
        let mut tmp = BigInt {nat: s.nat.clone() + 1u32, sign: Natural};
        tmp.nat.shr_inner(&1);
        let mut y = self.exp(&tmp, p); // y = x^((s+1)/2)
        let mut b = self.exp(&s, p); // b = x^s
        let mut g = n.exp(&s, p);
        let mut r = e;
        loop {
            tmp.sign =b.sign; tmp.nat.clear(); tmp.nat.as_mut_vec().extend(b.nat.iter());
            let mut m = 0;
            while tmp != 1u32 {
                tmp.mul_inner(tmp.clone());
                tmp.rem_euclid_inner(p.clone());
                m += 1;
            }
            
            if m == 0 {
                return y;
            }
            
            tmp.nat.clear(); tmp.nat.as_mut_vec().push(0);
            tmp.set_bits(r - m -1, true);
            let t = g.exp(&tmp, p);
            g.sign = Natural; Nat::sqr_v(g.nat.as_mut_vec(), t.nat.as_slice());
            g.rem_euclid_inner(p.clone());
            y.mul_inner(t.clone());
            y.rem_euclid_inner(p.clone());
            b.mul_inner(g.clone());
            b.rem_euclid_inner(p.clone());
            r = m;
        }
    }
/// compute the square root of a quadratic residue modulo any prime by the Tonelli-Shanks algorithm
compute the square root of a quadratic residue modulo any prime by the Tonelli-Shanks algorithm
compute the square root of a quadratic residue modulo any prime by the Tonelli - Shanks algorithm
fn mod_sqrt_tonelli_shanks(&self, p: &BigInt) -> BigInt {
        // Break p-1 into s*2^e such that s is odd.
        let mut s = BigInt {
            nat: p.nat.clone() - 1u32,
            sign: Natural,
        };
        let e = s.nat.trailling_zeros();
        s.nat.shr_inner(&e);
        // find some non-square n
        let mut n = BigInt::from(2u32);
        while n.jacobi(p) != Some(-1) {
            n.nat.add_inner_basic(&1u32);
        }
        // Core of the Tonelli-Shanks algorithm. Follows the description in
        // section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra
        // Brown:
        // https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf
        let mut tmp = BigInt {nat: s.nat.clone() + 1u32, sign: Natural};
        tmp.nat.shr_inner(&1);
        let mut y = self.exp(&tmp, p); // y = x^((s+1)/2)
        let mut b = self.exp(&s, p); // b = x^s
        let mut g = n.exp(&s, p);
        let mut r = e;
        loop {
            tmp.sign =b.sign; tmp.nat.clear(); tmp.nat.as_mut_vec().extend(b.nat.iter());
            let mut m = 0;
            while tmp != 1u32 {
                tmp.mul_inner(tmp.clone());
                tmp.rem_euclid_inner(p.clone());
                m += 1;
            }
            if m == 0 {
                return y;
            }
            tmp.nat.clear(); tmp.nat.as_mut_vec().push(0);
            tmp.set_bits(r - m -1, true);
            let t = g.exp(&tmp, p);
            g.sign = Natural; Nat::sqr_v(g.nat.as_mut_vec(), t.nat.as_slice());
            g.rem_euclid_inner(p.clone());
            y.mul_inner(t.clone());
            y.rem_euclid_inner(p.clone());
            b.mul_inner(g.clone());
            b.rem_euclid_inner(p.clone());
            r = m;
        }
    }
fn mod_sqrt_tonelli_shanks ( & self , p : & BigInt ) -> BigInt { // Break p-1 into s*2^e such that s is odd. let mut s = BigInt { nat : p . nat . clone ( ) - 1u32 , sign : Natural , } ; let e = s . nat . trailling_zeros ( ) ; s . nat . shr_inner ( & e ) ; // find some non-square n let mut n = BigInt :: from ( 2u32 ) ; while n . jacobi ( p ) != Some ( - 1 ) { n . nat . add_inner_basic ( & 1u32 ) ; } // Core of the Tonelli-Shanks algorithm. Follows the description in // section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra // Brown: // https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf let mut tmp = BigInt { nat : s . nat . clone ( ) + 1u32 , sign : Natural } ; tmp . nat . shr_inner ( & 1 ) ; let mut y = self . exp ( & tmp , p ) ; // y = x^((s+1)/2) let mut b = self . exp ( & s , p ) ; // b = x^s let mut g = n . exp ( & s , p ) ; let mut r = e ; loop { tmp . sign = b . sign ; tmp . nat . clear ( ) ; tmp . nat . as_mut_vec ( ) . extend ( b . nat . iter ( ) ) ; let mut m = 0 ; while tmp != 1u32 { tmp . mul_inner ( tmp . clone ( ) ) ; tmp . rem_euclid_inner ( p . clone ( ) ) ; m += 1 ; } if m == 0 { return y ; } tmp . nat . clear ( ) ; tmp . nat . as_mut_vec ( ) . push ( 0 ) ; tmp . set_bits ( r - m - 1 , true ) ; let t = g . exp ( & tmp , p ) ; g . sign = Natural ; Nat :: sqr_v ( g . nat . as_mut_vec ( ) , t . nat . as_slice ( ) ) ; g . rem_euclid_inner ( p . clone ( ) ) ; y . mul_inner ( t . clone ( ) ) ; y . rem_euclid_inner ( p . clone ( ) ) ; b . mul_inner ( g . clone ( ) ) ; b . rem_euclid_inner ( p . clone ( ) ) ; r = m ; } }
compute the square root of a quadratic residue modulo any prime by the Tonelli-Shanks algorithm
compute the square root of a quadratic residue modulo any prime by the Tonelli - Shanks algorithm
&self
p
&BigInt
&self
p
&BigInt