private BigInteger Sqrt(BigInteger val, BigInteger field)
{
if ((field & 3) == 3)
{
return(BigInteger.Pow(val, (field + 1) >> 2, field));
}
BigInteger root = 0;
BigInteger delta = ((field - 4) * (field - val)) % field;
BigInteger temp = 1;
BigInteger qnr = 0;
BigInteger buf = 0;
int ID = 1;
switch (ID)
{
case 1:
root = TonelliShanks(val, field);
if (val == (root * root) % field)
{
return(root);
}
goto case 2;
case 2:
qnr = BigInteger.Next(rand, 2, field - 1);
if (BigInteger.Jacobi(qnr, field) != -1)
{
goto case 2;
}
BigInteger square = (qnr * qnr) % field;
delta = (delta * square) % field;
temp = (temp * qnr) % field;
buf = TonelliShanks(delta, field);
if (delta != (buf * buf) % field)
{
goto case 2;
}
goto case 3;
case 3:
BigInteger vtemp = (2 * temp) % field;
BigInteger inv = vtemp.Inverse(field);
root = (buf * inv) % field;
break;
}
return(root);
}