in src/compression/torsion_basis.c [159:212]
static bool FirstPoint_dual(const point_proj_t P, point_full_proj_t R, unsigned char *ind)
{
point_full_proj_t R3,S3;
f2elm_t gX[2],gZ[2];
felm_t zero = {0};
unsigned long long nbytes = NBITS_TO_NBYTES(NBITS_FIELD);
unsigned char alpha,beta;
fpcopy((digit_t*)B_gen_3_tors + 0*NWORDS_FIELD, (R3->X)[0]);
fpcopy((digit_t*)B_gen_3_tors + 1*NWORDS_FIELD, (R3->X)[1]);
fpcopy((digit_t*)B_gen_3_tors + 2*NWORDS_FIELD, (R3->Y)[0]);
fpcopy((digit_t*)B_gen_3_tors + 3*NWORDS_FIELD, (R3->Y)[1]);
fpcopy((digit_t*)B_gen_3_tors + 4*NWORDS_FIELD, (S3->X)[0]);
fpcopy((digit_t*)B_gen_3_tors + 5*NWORDS_FIELD, (S3->X)[1]);
fpcopy((digit_t*)B_gen_3_tors + 6*NWORDS_FIELD, (S3->Y)[0]);
fpcopy((digit_t*)B_gen_3_tors + 7*NWORDS_FIELD, (S3->Y)[1]);
CompletePoint(P,R);
Tate3_proj(R3,R,gX[0],gZ[0]);
Tate3_proj(S3,R,gX[1],gZ[1]);
FinalExpo3_2way(gX,gZ);
// Do small DLog with respect to g_R3_S3
fp2correction(gX[0]);
fp2correction(gX[1]);
if (memcmp(gX[0][1], zero, (size_t)nbytes) == 0) // = 1
alpha = 0;
else if (memcmp(gX[0][1], g_R_S_im, (size_t)nbytes) == 0) // = g_R3_S3
alpha = 1;
else // = g_R3_S3^2
alpha = 2;
if (memcmp(gX[1][1], zero, (size_t)nbytes) == 0) // = 1
beta = 0;
else if (memcmp(gX[1][1], g_R_S_im, (size_t)nbytes) == 0) // = g_R3_S3
beta = 1;
else // = g_R3_S3^2
beta = 2;
if (alpha == 0 && beta == 0) // Not full order
return false;
// Return the 3-torsion point that R lies above
if (alpha == 0) // Lies above R3
*ind = 0;
else if (beta == 0) // Lies above S3
*ind = 1;
else if (alpha + beta == 3) // Lies above R3+S3
*ind = 3;
else // Lies above R3-S3
*ind = 2;
return true;
}