static void Elligator2()

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;
        }       
    }
}