in src/compression/torsion_basis.c [12:74]
static void Elligator2(const f2elm_t a24, const unsigned int r, f2elm_t x, unsigned char *bit, const unsigned char COMPorDEC)
{ // Generate an x-coordinate of a point on curve with (affine) coefficient a24
// Use a precomputed Elligator table of size TABLE_V3_LEN and switch to online computations if table runs out of elements.
// Use the counter r
int i;
felm_t one_fp, a2, b2, N, temp0, temp1, rmonty = {0}, *U;
f2elm_t A, y2, *t_ptr, v;
fpcopy((digit_t*)&Montgomery_one, one_fp);
fp2add(a24, a24, A);
fpsub(A[0], one_fp, A[0]);
fp2add(A, A, A); // A = 4*a24-2
// Elligator computation
if (r < TABLE_V3_LEN) {
t_ptr = (f2elm_t *)&v_3_torsion[r];
fp2copy((felm_t*)t_ptr, v);
} else { // Compute v = 1/(1+U*r^2)
U = (felm_t *)U3;
rmonty[0] = r;
to_mont(rmonty, rmonty);
fpsqr_mont(rmonty, rmonty);
fpmul_mont(U[0], rmonty, v[0]);
fpmul_mont(U[1], rmonty, v[1]);
fpadd(v[0], (digit_t*)&Montgomery_one, v[0]);
fp2inv_mont_bingcd(v);
}
fp2mul_mont(A, v, x); // x = A*v; v := 1/(1 + U*r^2) table lookup
fp2neg(x); // x = -A*v;
if (COMPorDEC == COMPRESSION) {
fp2add(A, x, y2); // y2 = x + A
fp2mul_mont(y2, x, y2); // y2 = x*(x + A)
fpadd(y2[0], one_fp, y2[0]); // y2 = x(x + A) + 1
fp2mul_mont(x, y2, y2); // y2 = x*(x^2 + Ax + 1);
fpsqr_mont(y2[0], a2);
fpsqr_mont(y2[1], b2);
fpadd(a2, b2, N); // N := norm(y2);
fpcopy(N, temp0);
for (i = 0; i < OALICE_BITS - 2; i++) {
fpsqr_mont(temp0, temp0);
}
for (i = 0; i < OBOB_EXPON; i++) {
fpsqr_mont(temp0, temp1);
fpmul_mont(temp0, temp1, temp0);
}
fpsqr_mont(temp0, temp1); // z = N^((p + 1) div 4);
fpcorrection(temp1);
fpcorrection(N);
if (memcmp(temp1, N, NBITS_TO_NBYTES(NBITS_FIELD)) != 0) {
fp2neg(x);
fp2sub(x, A, x); // x = -x - A;
if (COMPorDEC == COMPRESSION)
*bit = 1;
}
} else {
if (*bit) {
fp2neg(x);
fp2sub(x,A,x); // x = -x - A;
}
}
}