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