function sqrtRatioM1()

in src/ristretto255.js [410:445]


function sqrtRatioM1(x, u, v) {
  const v3 = lowlevel.gf();
  const vxx = lowlevel.gf();
  const mRootCheck = lowlevel.gf();
  const pRootCheck = lowlevel.gf();
  const fRootCheck = lowlevel.gf();
  const xSqrtM1 = lowlevel.gf(); // gf elements

  lowlevel.S(v3, v);
  lowlevel.M(v3, v3, v); /* v3 = v^3 */

  lowlevel.S(x, v3);
  lowlevel.M(x, x, v);
  lowlevel.M(x, x, u); /* x = uv^7 */

  lowlevel.pow2523(x, x); /* x = (uv^7)^((q-5)/8), ((q-5)/8) = 2^252 - 3 */
  lowlevel.M(x, x, v3);
  lowlevel.M(x, x, u); /* x = uv^3(uv^7)^((q-5)/8) */

  lowlevel.S(vxx, x);
  lowlevel.M(vxx, vxx, v); /* vx^2 */

  lowlevel.Z(mRootCheck, vxx, u); /* vx^2-u */
  lowlevel.A(pRootCheck, vxx, u); /* vx^2+u */
  lowlevel.M(fRootCheck, u, sqrtm1); /* u*sqrt(-1) */
  lowlevel.A(fRootCheck, vxx, fRootCheck); /* vx^2+u*sqrt(-1) */
  const hasMRoot = iszero25519(mRootCheck); /* hasMRoot = (vxx == u) */
  const hasPRoot = iszero25519(pRootCheck); /* hasPRoot = (vxx == -u) */
  const hasFRoot = iszero25519(fRootCheck); /* hasFRoot = (vxx = -u*sqrt(-1)) */
  lowlevel.M(xSqrtM1, x, sqrtm1); /* x*sqrt(-1) */

  cmov25519(x, xSqrtM1, hasPRoot | hasFRoot);
  abs25519(x, x);

  return hasMRoot | hasPRoot;
}