public BigInteger SquareRootModPrime(BigInteger a, BigInteger p) { long e = 0, r, s; BigInteger b = 0, bp = 0, q = p - 1, m = 0, n = 0; BigInteger p1 = p - 1, t = 0, x = 0, y = 0, z = 0; m = q % 2; while (m == 0) { q = q / 2; m = q % 2; e++; } int jac = 0; do { n = RandomRange(1, p1); jac = Maths.JacobiRand(n, p); }while (jac == -1); z = BigInteger.ModPow(n, q, p); y = z; r = e; x = BigInteger.ModPow(a, (q - 1) / 2, p); b = (((a * x) % p) * x) % p; x = (a * x) % p; while (true) { if (b == 1 || b == p1) { return(x); } s = 1; do { bp = BigInteger.ModPow(b, (long)Math.Pow(2, s), p); s++; }while (bp != 1 && bp != p1 && s < r); if (s == r) { return(0); } t = BigInteger.ModPow(y, (long)Math.Pow(2, r - s - 1), p); y = (t * t) % p; x = (x * t) % p; b = (b * y) % p; r = s; } }