int ord2w_dloghyb()

in src/compression/dlog.c [137:213]


int ord2w_dloghyb(const felm_t *h, const int *logT, const felm_t *Texp, const felm_t *G)
{
    int k = 0, d = 0, index = 0, ord = 0, tmp = 0, w = W_2, w2 = w - W_2_1, i_j = 0, t;
    uint8_t inv = 0, flag = 0;
    f2elm_t H[W_2_1+1] = {0}; // Size of H should be max of {W_2_1+1, W_2 - W_2_1}
    felm_t one = {0};

    fpcopy((digit_t*)&Montgomery_one, one);    
    fp2copy(h, (felm_t*)&H[0]);
    fpcorrection(H[0][0]);
    fpcorrection(H[0][1]);

    for (int i = 1; i <= w2; ++i) {
        if (!is_felm_zero(H[0][1])) { // check if first compressed Fp2 element in H is NOT the identity
            for (int j = k; j >= 0; j--) fp2copy(H[j], H[j+1]);
            sqr_Fp2_cycl_proj(H[0]);
            k++;
        } else {
            break;
        }        
    }

    fpcorrection(H[0][1]);
    if (is_felm_zero(H[0][1]) && k <= W_2_1) return ord2w_dlog(H[k], logT, Texp) << w2;

    if (!is_felm_zero(H[0][1])) {        
        d = mod(ord2w_dlog(H[0], logT, Texp), (1 << W_2_1));
        index = 0;
    } else {        
        d = mod(ord2w_dlog(&H[W_2_1][0], logT, Texp), (1 << W_2_1));
        index = W_2_1;
    }

    t = highest_t(d);
    ord = W_2_1 - t;
    tmp = ((d >> (W_2_1-ord))-1) >> 1;
    i_j = reverse_bits(tmp,ord-1);
    fpcorrection(H[0][0]);
    if (is_felm_zero(H[0][0])) { // check if compressed Fp2 element H[0] is -1
        fpneg(one);
        fpcorrection(one);
        if ( ((memcmp(G[0],&Montgomery_one,NBITS_TO_NBYTES(NBITS_FIELD)) == 0) && (memcmp(H[1][0],H[1][1],NBITS_TO_NBYTES(NBITS_FIELD)) != 0)) ||
             ((memcmp(G[0],one,NBITS_TO_NBYTES(NBITS_FIELD)) == 0) && (memcmp(H[1][0],H[1][1],NBITS_TO_NBYTES(NBITS_FIELD)) == 0))) { // check if G[0] != H[1]
            for (int i = 0; i <= k; ++i) inv_Fp2_cycl_proj(H[i]);
            inv = 1;
        }
    } else {
        if (i_j >= (1 << (ord-2))) {
            i_j = (1 << (ord-1)) - i_j - 1; 
            d = (1 << (W_2_1)) - d;
            for (int i = 0; i <= k; ++i) inv_Fp2_cycl_proj(H[i]);             
            inv = 1;   
        }
    } 
    d <<= w2;
    for (int j = index+1; j <= k; ++j) {
        i_j <<= 1;
        d >>= 1;

        if ((j-index+ord-3) < 0) {
            fpmul_mont(G[0], H[j][1], one);
        } else {            
            fpmul_mont(G[(1 << (j-index+ord-2)) - (1 << (j-index+ord-3)) + (i_j >> 1)], H[j][1], one);
        }
        fpcorrection(one);
        if (memcmp(H[j][0], one, NBITS_TO_NBYTES(NBITS_FIELD)) != 0) {
            d += 1 << (w-1);
            i_j++;
            flag = 1;
        }
    }

    if (d > (1 << (w-1))) d = (1 << w) - d;
    if (inv ^ flag) d = -d;
    
    return d;
}