void from_base()

in src/compression/dlog.c [9:83]


void from_base(int *D, digit_t *r, int Dlen, int base) 
{ // Convert a number in base "base" with signed digits: (D[k-1]D[k-2]...D[1]D[0])_base < 2^(NWORDS_ORDER*RADIX) into decimal 
  // Output: r = (D[k-1]*base^(k-1) + ... + D[1]*base + D[0])_10
    digit_t ell[NWORDS_ORDER] = {0}, digit[NWORDS_ORDER] = {0}, temp[NWORDS_ORDER] = {0};    
    int ellw;
    
    ell[0] = base;
    if (D[Dlen-1] < 0) {
        digit[0] = (digit_t)(((int)-D[Dlen-1])*ell[0]);
        if ((base & 1) == 0) {
            Montgomery_neg(digit, (digit_t*)Alice_order);
            copy_words(digit, r, NWORDS_ORDER);
        } else {
            mp_sub((digit_t*)Bob_order, digit, r, NWORDS_ORDER);             
        }        
    } else {
        r[0] = (digit_t)(D[Dlen-1]*ell[0]);
    }

    for (int i = Dlen-2; i >= 1; i--) {
        ellw = base;
        memset(digit,0,NWORDS_ORDER*sizeof(digit_t));
        if (D[i] < 0) {
            digit[0] = (digit_t)(-D[i]);
            if ((base & 1) == 0) {
                Montgomery_neg(digit, (digit_t*)Alice_order);
            } else {  
                mp_sub((digit_t*)Bob_order, digit, digit, NWORDS_ORDER);                            
            }
        } else {
            digit[0] = (digit_t)D[i];
        }
        mp_add(r, digit, r, NWORDS_ORDER);
        if ((base & 1) != 0) {
            if (!is_orderelm_lt(r, (digit_t*)Bob_order))
                mp_sub(r,(digit_t*)Bob_order, r, NWORDS_ORDER);               
        }
        
        if ((base & 1) == 0) {
            while (ellw > 1) {
                mp_add(r, r, r, NWORDS_ORDER);   
                ellw /= 2;
            }
        } else {
            while (ellw > 1) {
                memset(temp,0,NWORDS_ORDER*sizeof(digit_t));
                mp_add(r, r, temp, NWORDS_ORDER);
                if (!is_orderelm_lt(temp, (digit_t*)Bob_order)) 
                    mp_sub(temp,(digit_t*)Bob_order, temp, NWORDS_ORDER);
                
                mp_add(r, temp, r, NWORDS_ORDER);

                if (!is_orderelm_lt(r, (digit_t*)Bob_order))
                    mp_sub(r,(digit_t*)Bob_order, r, NWORDS_ORDER);                
                ellw /= 3;
            }
        }
    }
    memset(digit,0,NWORDS_ORDER*sizeof(digit_t));
    if (D[0] < 0) {
        digit[0] = (digit_t)(-D[0]);
        if ((base & 1) == 0) {
            Montgomery_neg(digit, (digit_t*)Alice_order);
        } else { 
            mp_sub((digit_t*)Bob_order, digit, digit, NWORDS_ORDER);            
        }
    } else {
        digit[0] = (digit_t)D[0];
    }
    mp_add(r, digit, r, NWORDS_ORDER);
    if ((base & 1) != 0) { 
        if (!is_orderelm_lt(r, (digit_t*)Bob_order))
            mp_sub(r,(digit_t*)Bob_order, r, NWORDS_ORDER);     
    }
}