$m_root_check = self::
fe_sub($vxx,
$u); /* vx^2-u */
$p_root_check = self::
fe_add($vxx,
$u); /* vx^2+u */
$f_root_check = self::
fe_mul($u,
$sqrtm1); /* u*sqrt(-1) */
$f_root_check = self::
fe_add($vxx,
$f_root_check); /* vx^2+u*sqrt(-1) */
$has_m_root = self::
fe_iszero($m_root_check);
$has_p_root = self::
fe_iszero($p_root_check);
$has_f_root = self::
fe_iszero($f_root_check);
$x_sqrtm1 = self::
fe_mul($x,
$sqrtm1); /* x*sqrt(-1) */
$x = self::
fe_abs( self::
fe_cmov($x,
$x_sqrtm1,
$has_p_root |
$has_f_root) );
return array
( 'x' =>
$x,
'nonsquare' =>
$has_m_root |
$has_p_root );
} /**
* @param string $s
* @return int
* @throws SodiumException
*/