static void PKBDecompression()

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