in src/compression/sidh_compressed.c [518:577]
static void PKBDecompression(const unsigned char* SecretKeyA, const unsigned char* CompressedPKB, point_proj_t R, f2elm_t A)
{ // Bob's PK decompression -- SIDH protocol
uint64_t mask = (digit_t)(-1);
unsigned char bit,qnr,ind;
f2elm_t A24;
digit_t tmp1[2*NWORDS_ORDER] = {0}, tmp2[2*NWORDS_ORDER] = {0}, vone[2*NWORDS_ORDER] = {0};
digit_t SKin[NWORDS_ORDER] = {0}, comp_temp[NWORDS_ORDER] = {0};
point_proj_t Rs[3] = {0};
mask >>= (MAXBITS_ORDER - OALICE_BITS);
vone[0] = 1;
fp2_decode(&CompressedPKB[3*ORDER_A_ENCODED_BYTES], A);
bit = CompressedPKB[3*ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES] >> 7;
qnr = CompressedPKB[3*ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES] & 0x1;
ind = CompressedPKB[3*ORDER_A_ENCODED_BYTES + FP2_ENCODED_BYTES + 1];
// Rebuild the basis
BuildEntangledXonly_Decomp(A,Rs,qnr,ind);
fpcopy((digit_t*)Montgomery_one, (Rs[0]->Z)[0]);
fpcopy((digit_t*)Montgomery_one, (Rs[1]->Z)[0]);
fpadd(A[0], (digit_t*)Montgomery_one, A24[0]);
fpcopy(A[1], A24[1]);
fpadd(A24[0], (digit_t*)Montgomery_one, A24[0]);
fp2div2(A24, A24);
fp2div2(A24, A24);
decode_to_digits(SecretKeyA, SKin, SECRETKEY_A_BYTES, NWORDS_ORDER);
swap_points(Rs[0], Rs[1], 0-(digit_t)bit);
if (bit == 0) {
decode_to_digits(&CompressedPKB[ORDER_A_ENCODED_BYTES], comp_temp, ORDER_A_ENCODED_BYTES, NWORDS_ORDER);
multiply((digit_t*)SKin, comp_temp, tmp1, NWORDS_ORDER);
mp_add(tmp1, vone, tmp1, NWORDS_ORDER);
tmp1[NWORDS_ORDER-1] &= (digit_t)mask;
inv_mod_orderA(tmp1, tmp2);
decode_to_digits(&CompressedPKB[2*ORDER_A_ENCODED_BYTES], comp_temp, ORDER_A_ENCODED_BYTES, NWORDS_ORDER);
multiply((digit_t*)SKin, comp_temp, tmp1, NWORDS_ORDER);
decode_to_digits(&CompressedPKB[0], comp_temp, ORDER_A_ENCODED_BYTES, NWORDS_ORDER);
mp_add(&comp_temp[0], tmp1, tmp1, NWORDS_ORDER);
multiply(tmp1, tmp2, vone, NWORDS_ORDER);
vone[NWORDS_ORDER-1] &= (digit_t)mask;
Ladder3pt_dual(Rs,vone,ALICE,R,A24);
} else {
decode_to_digits(&CompressedPKB[2*ORDER_A_ENCODED_BYTES], comp_temp, ORDER_A_ENCODED_BYTES, NWORDS_ORDER);
multiply((digit_t*)SKin, comp_temp, tmp1, NWORDS_ORDER);
mp_add(tmp1, vone, tmp1, NWORDS_ORDER);
tmp1[NWORDS_ORDER-1] &= (digit_t)mask;
inv_mod_orderA(tmp1, tmp2);
decode_to_digits(&CompressedPKB[ORDER_A_ENCODED_BYTES], comp_temp, ORDER_A_ENCODED_BYTES, NWORDS_ORDER);
multiply((digit_t*)SKin, comp_temp, tmp1, NWORDS_ORDER);
decode_to_digits(&CompressedPKB[0], comp_temp, ORDER_A_ENCODED_BYTES, NWORDS_ORDER);
mp_add(&comp_temp[0], tmp1, tmp1, NWORDS_ORDER);
multiply(tmp1, tmp2, vone, NWORDS_ORDER);
vone[NWORDS_ORDER-1] &= (digit_t)mask;
Ladder3pt_dual(Rs,vone,ALICE,R,A24);
}
fp2div2(A,A24);
xTPLe_fast(R, R, A24, OBOB_EXPON);
}