public static void ge_fromfe_frombytes_vartime(out GroupElementP2 r, byte[] s, int offset) { FieldElement u, v, w, x, y, z; byte sign; FieldOperations.fe_frombytes(out u, s, offset); FieldOperations.fe_sq2(out v, ref u); /* 2 * u^2 */ FieldOperations.fe_1(out w); FieldOperations.fe_add(out w, ref v, ref w); /* w = 2 * u^2 + 1 */ FieldOperations.fe_sq(out x, ref w); /* w^2 */ FieldOperations.fe_mul(out y, ref FieldOperations.fe_ma2, ref v); /* -2 * A^2 * u^2 */ FieldOperations.fe_add(out x, ref x, ref y); /* x = w^2 - 2 * A^2 * u^2 */ FieldOperations.fe_divpowm1(out r.X, ref w, ref x); /* (w / x)^(m + 1) */ FieldOperations.fe_sq(out y, ref r.X); FieldOperations.fe_mul(out x, ref y, ref x); FieldOperations.fe_sub(out y, ref w, ref x); FieldOperations.fe_copy(out z, ref FieldOperations.fe_ma); if (FieldOperations.fe_isnonzero(ref y) != 0) { FieldOperations.fe_add(out y, ref w, ref x); if (FieldOperations.fe_isnonzero(ref y) != 0) { goto negative; } else { FieldOperations.fe_mul(out r.X, ref r.X, ref FieldOperations.fe_fffb1); } } else { FieldOperations.fe_mul(out r.X, ref r.X, ref FieldOperations.fe_fffb2); } FieldOperations.fe_mul(out r.X, ref r.X, ref u); /* u * sqrt(2 * A * (A + 2) * w / x) */ FieldOperations.fe_mul(out z, ref z, ref v); /* -2 * A * u^2 */ sign = 0; goto setsign; negative: FieldOperations.fe_mul(out x, ref x, ref FieldOperations.fe_sqrtm1); FieldOperations.fe_sub(out y, ref w, ref x); if (FieldOperations.fe_isnonzero(ref y) != 0) { //assert((fe_add(y, w, x), !fe_isnonzero(y))); FieldOperations.fe_mul(out r.X, ref r.X, ref FieldOperations.fe_fffb3); } else { FieldOperations.fe_mul(out r.X, ref r.X, ref FieldOperations.fe_fffb4); } /* r->X = sqrt(A * (A + 2) * w / x) */ /* z = -A */ sign = 1; setsign: if (FieldOperations.fe_isnegative(ref r.X) != sign) { //assert(fe_isnonzero(r->X)); FieldOperations.fe_neg(out r.X, ref r.X); } FieldOperations.fe_add(out r.Z, ref z, ref w); FieldOperations.fe_sub(out r.Y, ref z, ref w); FieldOperations.fe_mul(out r.X, ref r.X, ref r.Z); }