Exemple #1
0
void bignum_init_base_convert(size_t size, int base) {
    bignum multiplier;
    bignum_init(&multiplier);
    bignum_from_int(&multiplier, 1);
    mul_lut = malloc(size * sizeof(bignum));
    mul_lut_size = size;
    for (int i = 0; i < size; ++i) {
        bignum_init(&mul_lut[i]);
        bignum_copy(&mul_lut[i], &multiplier);
        bignum_mul_int(&multiplier, base);
    }
    bignum_free(&multiplier);

    bignum sum;
    bignum_init(&sum);
    for (int i = 0; i < SUMSZ; ++i) {
        for (int j = 0; j < 256; ++j) {
            int m = i*8;
            bignum_from_int(&sum, 0);
            for (uint8_t mask = 1; mask != 0; mask <<= 1) {
                if (j & mask) {
                    bignum_add(&sum, &mul_lut[m]);
                }
                ++m;
            }
            bignum_init(&sum_lut[i][j]);
            bignum_copy(&sum_lut[i][j], &sum);
        }
    }
    bignum_free(&sum);
}
Exemple #2
0
/**
 * Perform an in place divide of source, also producing a remainder.
 * source = source/div and remainder = source - source/div.
 */
void bignum_idivider(bignum* source, bignum* div, bignum* remainder) {
    bignum *q = bignum_init(), *r = bignum_init();
    bignum_divide(q, r, source, div);
    bignum_copy(q, source);
    bignum_copy(r, remainder);
    bignum_deinit(q);
    bignum_deinit(r);
}
Exemple #3
0
// a *= b
void bignum_mul_int(bignum *a, unsigned int b) {
    bignum tmp;
    bignum_init(&tmp);
    uint8_t b_bytes[] = {
         b & 0x000000ff,
        (b & 0x0000ff00) >> 8,
        (b & 0x00ff0000) >> 16,
        (b & 0xff000000) >> 24,
    };
    int b_size = 3;
    while (b_size > 1 && b_bytes[b_size] == 0) --b_size;
    for (int bi = 0; bi < b_size; ++bi) {
        int carry = 0;
        for (int ai = 0; ai < a->size; ++ai) {
            int prod = carry + a->data[ai] * b_bytes[bi];
            carry = prod / 256;
            tmp.data[ai + bi] = prod % 256;
        }
        tmp.data[bi + a->size] = carry;
    }
    tmp.size = a->size + b_size;
    while (tmp.size > 0 && tmp.data[tmp.size - 1] == 0) {
        --tmp.size;
    }
    if (tmp.size == 0) {
        tmp.size = 1;
    }
    bignum_copy(a, &tmp);
    bignum_free(&tmp);
}
Exemple #4
0
/**
 * Modulate the source by the modulus. source = source % modulus
 */
void bignum_imodulate(bignum* source, bignum* modulus) {
    bignum *q = bignum_init(), *r = bignum_init();
    bignum_divide(q, r, source, modulus);
    bignum_copy(r, source);
    bignum_deinit(q);
    bignum_deinit(r);
}
Exemple #5
0
void comb_fast_sum(bignum_t* sum, const byte* comb_set)
{
    int i;
    bignum_copy(sum, &all_sums_by_word_and_pos[0][*(uint16_t*)comb_set]);
    for (i = 1; i < 5; i++)
        bignum_add(sum, &all_sums_by_word_and_pos[i][((uint16_t*)comb_set)[i]]);
}
Exemple #6
0
// a %= b
void bignum_mod(bignum *a, bignum *b) {
    bignum tmp;
    bignum_init(&tmp);
    bignum_div_mod(a, b, &tmp);
    bignum_copy(a, &tmp);
    bignum_free(&tmp);
}
Exemple #7
0
/**
 * Perform an in place divide of source. source = source/div.
 */
void bignum_idivide(bignum *source, bignum *div) {
    bignum *q = bignum_init(), *r = bignum_init();
    bignum_divide(q, r, source, div);
    bignum_copy(q, source);
    bignum_deinit(q);
    bignum_deinit(r);
}
Exemple #8
0
/**
 * Compute the inverse of a mod m. Or, result = a^-1 mod m.
 */
void bignum_inverse(bignum* a, bignum* m, bignum* result) {
    bignum *remprev = bignum_init(), *rem = bignum_init();
    bignum *auxprev = bignum_init(), *aux = bignum_init();
    bignum *rcur = bignum_init(), *qcur = bignum_init(), *acur = bignum_init();
    
    bignum_copy(m, remprev);
    bignum_copy(a, rem);
    bignum_fromint(auxprev, 0);
    bignum_fromint(aux, 1);
    while(bignum_greater(rem, &NUMS[1])) {
        bignum_divide(qcur, rcur, remprev, rem);
        /* Observe we are finding the inverse in a finite field so we can use
         * a modified algorithm that avoids negative numbers here */
        bignum_subtract(acur, m, qcur);
        bignum_imultiply(acur, aux);
        bignum_iadd(acur, auxprev);
        bignum_imodulate(acur, m);
        
        bignum_copy(rem, remprev);
        bignum_copy(aux, auxprev);
        bignum_copy(rcur, rem);
        bignum_copy(acur, aux);
    }
    
    bignum_copy(acur, result);
    
    bignum_deinit(remprev);
    bignum_deinit(rem);
    bignum_deinit(auxprev);
    bignum_deinit(aux);
    bignum_deinit(rcur);
    bignum_deinit(qcur);
    bignum_deinit(acur);
}
int bignum_is_lychrel(const bignum *a, int tries) {
    bignum *b, *c;
    int i, result = 1;

    b = bignum_copy(a);
    for (i = 0; i < tries; i++) {
        c = bignum_copy(b);
        bignum_reverse_digits(b);
        bignum_add(b, c);
        bignum_delete(c);
        if (bignum_is_palindrome(b)) {
            result = 0;
            break;
        }
    }
    bignum_delete(b);
    return result;
}
Exemple #10
0
// a *= b
void bignum_mul_int_silly_loop(bignum *a, unsigned int b) {
    bignum tmp;
    bignum_init(&tmp);
    bignum_copy(&tmp, a);
    --b;
    // XXX: this loop is probably quite inefficient, think of something better
    while (b > 0) {
        bignum_add(a, &tmp);
        --b;
    }
    bignum_free(&tmp);
}
Exemple #11
0
/**
 * Compute the jacobi symbol, J(ac, nc).
 */
int bignum_jacobi(bignum* ac, bignum* nc) {
    bignum *remainder = bignum_init(), *twos = bignum_init();
    bignum *temp = bignum_init(), *a = bignum_init(), *n = bignum_init();
    int mult = 1, result = 0;
    bignum_copy(ac, a);
    bignum_copy(nc, n);
    while(bignum_greater(a, &NUMS[1]) && !bignum_equal(a, n)) {
        bignum_imodulate(a, n);
        if(bignum_leq(a, &NUMS[1]) || bignum_equal(a, n)) break;
        bignum_fromint(twos, 0);
        /* Factor out multiples of two */
        while(a->data[0] % 2 == 0) {
            bignum_iadd(twos, &NUMS[1]);
            bignum_idivide(a, &NUMS[2]);
        }
        /* Coefficient for flipping */
        if(bignum_greater(twos, &NUMS[0]) && twos->data[0] % 2 == 1) {
            bignum_remainder(n, &NUMS[8], remainder);
            if(!bignum_equal(remainder, &NUMS[1]) && !bignum_equal(remainder, &NUMS[7])) {
                mult *= -1;
            }
        }
        if(bignum_leq(a, &NUMS[1]) || bignum_equal(a, n)) break;
        bignum_remainder(n, &NUMS[4], remainder);
        bignum_remainder(a, &NUMS[4], temp);
        if(!bignum_equal(remainder, &NUMS[1]) && !bignum_equal(temp, &NUMS[1])) mult *= -1;
        bignum_copy(a, temp);
        bignum_copy(n, a);
        bignum_copy(temp, n);
    }
    if(bignum_equal(a, &NUMS[1])) result = mult;
    else result = 0;
    bignum_deinit(remainder);
    bignum_deinit(twos);
    bignum_deinit(temp);
    bignum_deinit(a);
    bignum_deinit(n);
    return result;
}
Exemple #12
0
/**
 * Perform modular exponentiation by repeated squaring. This will compute
 * result = base^exponent mod modulus
 */
void bignum_modpow(bignum* base, bignum* exponent, bignum* modulus, bignum* result) {
    bignum *a = bignum_init(), *b = bignum_init(), *c = bignum_init();
    bignum *discard = bignum_init(), *remainder = bignum_init();
    bignum_copy(base, a);
    bignum_copy(exponent, b);
    bignum_copy(modulus, c);
    bignum_fromint(result, 1);
    while(bignum_greater(b, &NUMS[0])) {
        if(b->data[0] & 1) {
            bignum_imultiply(result, a);
            bignum_imodulate(result, c);
        }
        bignum_idivide(b, &NUMS[2]);
        bignum_copy(a, discard);
        bignum_imultiply(a, discard);
        bignum_imodulate(a, c);
    }
    bignum_deinit(a);
    bignum_deinit(b);
    bignum_deinit(c);
    bignum_deinit(discard);
    bignum_deinit(remainder);
}
Exemple #13
0
/**
 * Check whether a is a Euler witness for n. That is, if a^(n - 1)/2 != Ja(a, n) mod n
 */
int solovayPrime(int a, bignum* n) {
    bignum *ab = bignum_init(), *res = bignum_init(), *pow = bignum_init();
    bignum *modpow = bignum_init();
    int x, result;
    
    bignum_fromint(ab, a);
    x = bignum_jacobi(ab, n);
    if(x == -1) bignum_subtract(res, n, &NUMS[1]);
    else bignum_fromint(res, x);
    bignum_copy(n, pow);
    bignum_isubtract(pow, &NUMS[1]);
    bignum_idivide(pow, &NUMS[2]);
    bignum_modpow(ab, pow, n, modpow);
    
    result = !bignum_equal(res, &NUMS[0]) && bignum_equal(modpow, res);
    bignum_deinit(ab);
    bignum_deinit(res);
    bignum_deinit(pow);
    bignum_deinit(modpow);
    return result;
}
Exemple #14
0
/**
 * Print a bignum to stdout as base 10 integer. This is done by
 * repeated division by 10. We can make it more efficient by dividing by
 * 10^9 for example, then doing single precision arithmetic to retrieve the
 * 9 remainders
 */
void bignum_print(bignum* b) {
    int cap = 100, len = 0, i;
    char* buffer = malloc(cap * sizeof(char));
    bignum *copy = bignum_init(), *remainder = bignum_init();
    if(b->length == 0 || bignum_iszero(b)) printf("0");
    else {
        bignum_copy(b, copy);
        while(bignum_isnonzero(copy)) {
            bignum_idivider(copy, &NUMS[10], remainder);
            buffer[len++] = remainder->data[0];
            if(len >= cap) {
                cap *= 2;
                buffer = realloc(buffer, cap * sizeof(char));
            }
        }
        for(i = len - 1; i >= 0; i--) printf("%d", buffer[i]);
    }
    bignum_deinit(copy);
    bignum_deinit(remainder);
    free(buffer);
}
Exemple #15
0
/**
 * Compute the gcd of two bignums. result = gcd(b1, b2)
 */
void bignum_gcd(bignum* b1, bignum* b2, bignum* result) {
    bignum *a = bignum_init(), *b = bignum_init(), *remainder = bignum_init();
    bignum *temp = bignum_init(), *discard = bignum_init();
    bignum_copy(b1, a);
    bignum_copy(b2, b);
    while(!bignum_equal(b, &NUMS[0])) {
        bignum_copy(b, temp);
        bignum_imodulate(a, b);
        bignum_copy(a, b);
        bignum_copy(temp, a);
    }
    bignum_copy(a, result);
    bignum_deinit(a);
    bignum_deinit(b);
    bignum_deinit(remainder);
    bignum_deinit(temp);
    bignum_deinit(discard);
}
Exemple #16
0
bignum* bignum_dumb_mul(bignum a, bignum b) {
    // Optimisation
    if(bignum_absgt(b, a))
        return bignum_dumb_mul(b, a);

    bignum* prod = bignum_fromstr("0");
    bignum* zero = bignum_fromstr("0");
    bignum* dec = bignum_fromstr("-1");

    char sign = a.sign != b.sign;

    bignum* b_copy = bignum_copy(&b);
    b_copy->sign = 0;
    bignum* add_result = NULL;
    bignum* prod_result = NULL;

    a.sign = 0;

    while(!bignum_eq(*b_copy, *zero)) {
        add_result = bignum_add(*b_copy, *dec);
        bignum_destoroyah(b_copy);
        b_copy = add_result;

        prod_result = bignum_add(*prod, a);
        bignum_destoroyah(prod);
        prod = prod_result;
    }

    bignum_destoroyah(b_copy);
    bignum_destoroyah(zero);
    bignum_destoroyah(dec);

    prod->sign = sign;

    return prod;
}
Exemple #17
0
/**
 * Algo de karatsuba pour la multiplication de grands entiers
 */
bignum* bignum_mul(bignum a, bignum b) {
    int len_a = bignum_len(a);
    int len_b = bignum_len(b);

    // Multiplication stupide pour les petits nombres
    if(len_a < 2 || len_b < 2) {
        return bignum_dumb_mul(a, b);
    }
    int max = MAX(len_a, len_b);
    int max_middle = max/2;

    bignum* high_a = bignum_init();
    bignum* high_b = bignum_init();
    bignum* low_a = bignum_init();
    bignum* low_b = bignum_init();

    bignum_split(a, max-max_middle, high_a, low_a);
    bignum_split(b, max-max_middle, high_b, low_b);

    bignum* z2 = bignum_mul(*high_a, *high_b);
    bignum* z0 = bignum_mul(*low_a, *low_b);

    // Je voudrais de l'operator overloading : (z2*10^(max))+((z1-z2-z0)*10^(max_middle))+(z0)
    bignum* sum_a = bignum_add(*low_a, *high_a);
    bignum* sum_b = bignum_add(*low_b, *high_b);

    bignum_destoroyah(high_a);
    bignum_destoroyah(high_b);
    bignum_destoroyah(low_a);
    bignum_destoroyah(low_b);

    // z1 = (sum_a*sum_b) - z2 - z0
    bignum* mul_of_sum = bignum_mul(*sum_a, *sum_b);
    bignum* diff_a = bignum_sub(*mul_of_sum,*z2);
    bignum* z1 = bignum_sub(*diff_a, *z0);

    bignum_destoroyah(mul_of_sum);
    bignum_destoroyah(diff_a);
    bignum_destoroyah(sum_a);
    bignum_destoroyah(sum_b);

    //arrondir pour avoir la bonne puissance de 10 dans les shifts.
    float inter = (float)max;
    inter = inter/2.0f;
    inter += 0.5f;
    max_middle = (int) inter;
    if(max%2 == 1){
        max++;
    }

    //r1 = z2*10^(max)
    bignum* r1 = bignum_copy(z2);
    bignum_shift_left(r1, max);

    //r2 = z1
    bignum* r2 = bignum_copy(z1);
    //r2 = r2*10^(max_middle)
    bignum_shift_left(r2, max_middle);
    //r3 = r2 + z0
    bignum* r3 = bignum_add(*r2, *z0);

    //bignum_destoroyah(z0);
    bignum_destoroyah(r2);
    //rf = r1+r3
    bignum* rf = bignum_add(*r1, *r3);

    bignum_destoroyah(r1);
    bignum_destoroyah(r3);

    bignum_destoroyah(z0);
    bignum_destoroyah(z1);
    bignum_destoroyah(z2);
    return rf;
}
Exemple #18
0
int main(int argc, const char * argv[]) {
    
    char *p=(char*)malloc(BUF_SIZE*sizeof(char));
    printf("\n请输入选择的大素数p:\n");
    scanf("%s",p);
    bignum *p1 = bignum_init();
    bignum_fromstring(p1, p);
    free(p);
    if(probablePrime(p1, ACCURACY))
    {
        printf("p合理");
        bignum *yz = bignum_init();
        bignum_fromint(yz, 3);
        if (bignum_equal(yz,p1)) {
            printf("但p太小不适用!\n");
            return 1;
        }
    }else{
        printf("p不是素数!\n");
        return 1;
    }
    bignum *p2 = bignum_init();
    bignum *temp = bignum_init();
    bignum_fromint(temp, 1);
    bignum_subtract(p2, p1, temp);
    printf("\n请输入选择的本原元α:\n");
    char *a=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",a);
    bignum *a1 = bignum_init();
    bignum_fromstring(a1, a);
    free(a);
    printf("\n请输入选择的随机整数d:(2<=d<=p-2)\n");
    char *d=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",d);
    bignum *d1 = bignum_init();
    bignum_fromstring(d1, d);
    free(d);
    bignum *yz0 = bignum_init();
    bignum_fromint(yz0, 2);
    bignum *yz1 = bignum_init();
    bignum_subtract(yz1, p1, yz0);
    if( (bignum_greater(d1, yz0)||bignum_equal(d1, yz0))&&(bignum_greater(yz1,d1)||bignum_equal(yz1,d1)) )
    {
        printf("d合理");
    }else{
        printf("d不合要求!\n");
        return 1;
    }
    printf("\n请输入您的消息x:\n");
    char *x=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",x);
    bignum *x1 = bignum_init();
    bignum_fromstring(x1, x);
    free(x);
    printf("\n请输入您选择的k:(2<=k<=p-2且k应与p-1互质)\n");
    char *k=(char*)malloc(BUF_SIZE*sizeof(char));
    scanf("%s",k);
    bignum *k1 = bignum_init();
    bignum_fromstring(k1, k);
    free(k);
    if( (bignum_greater(k1, yz0)||bignum_equal(k1, yz0))&&(bignum_greater(yz1,k1)||bignum_equal(yz1,k1)) )
    {
        bignum *yz2 = bignum_init();
        bignum_gcd(k1, p2, yz2);
        if (!bignum_equal(yz2,temp)) {
            printf("k不合要求!\n");
            return 1;
        }
        printf("k合理");
    }else{
        printf("k不合要求!\n");
        return 1;
    }
    
    
    
    bignum *b1 = bignum_init();
    bignum_modpow(a1,d1,p1,b1);
    printf("\n\n所以\n您生成的公钥(p,α,β)为:\t(");
    bignum_print(p1);
    printf(",");
    bignum_print(a1);
    printf(",");
    bignum_print(b1);
    printf(")\n");
    
    printf("您的私钥为:");
    bignum_print(d1);
    printf("\n");
    printf("您发出的消息(x(r,s))为:\t(");
    bignum_print(x1);
    printf(",(");
    bignum *r1 = bignum_init();
    bignum_modpow(a1,k1,p1,r1);
    bignum_print(r1);
    printf(",");
    bignum *s1=bignum_init();
    bignum_multiply(temp, d1, r1);
    
    bignum *temp2 = bignum_init();
    bignum *x2 = bignum_init();
    bignum_copy(x1, x2);
    while (bignum_less(x2, temp)) {
        bignum *add = bignum_init();
        bignum_copy(p2, add);
        bignum_iadd(x2, add) ;
    }
    bignum_subtract(temp2, x2, temp);
//    printf("\ntemp2:");
//    bignum_print(temp2);
//    printf("\t");
//    bignum_print(x2);
//    printf("\t");
//    bignum_print(temp);
//    printf("\n");
    bignum_inverse(k1, p2, temp);//计算a的逆元result = a^-1 mod m
    bignum_multiply(s1, temp, temp2);
    bignum_imodulate(s1, p2);//source = source % modulus
    bignum_print(s1);
    printf("))\n");
    
    bignum *t0 = bignum_init();
    bignum_modpow(a1,x1,p1,t0);
    bignum *t1 = bignum_init();
    bignum_modpow(b1,r1,p1,t1);
    bignum *t2 = bignum_init();
    bignum_modpow(r1,s1,p1,t2);
    bignum *t3 = bignum_init();
    bignum_multiply(t3, t1, t2);
    bignum_imodulate(t3, p1);
    printf("按t=(α^x)mod p,结果为:");
    bignum_print(t0);
    printf("\n按t=(β^r*r^s)mod p,结果为:");
    bignum_print(t3);
    printf("\n");
    if (bignum_equal(t0, t3)) {
        printf("此签名正确有效~\n\n");
    }else{
        printf("此签名错误无效!\n\n");
    }
}
Exemple #19
0
/**
 * Divide two bignums by naive long division, producing both a quotient and remainder.
 * quotient = floor(b1/b2), remainder = b1 - quotient * b2. If b1 < b2 the quotient is
 * trivially 0 and remainder is b2.
 */
void bignum_divide(bignum* quotient, bignum* remainder, bignum* b1, bignum* b2) {
    bignum *b2copy = bignum_init(), *b1copy = bignum_init();
    bignum *temp = bignum_init(), *temp2 = bignum_init(), *temp3 = bignum_init();
    bignum* quottemp = bignum_init();
    word carry = 0;
    int n, m, i, j, length = 0;
    unsigned long long factor = 1;
    unsigned long long gquot, gtemp, grem;
    if(bignum_less(b1, b2)) { /* Trivial case, b1/b2 = 0 iff b1 < b2. */
        quotient->length = 0;
        bignum_copy(b1, remainder);
    }
    else if(bignum_iszero(b1)) { /* 0/x = 0.. assuming b2 is nonzero */
        quotient->length = 0;
        bignum_fromint(remainder, 0);
    }
    else if(b2->length == 1) { /* Division by a single limb means we can do simple division */
        if(quotient->capacity < b1->length) {
            quotient->capacity = b1->length;
            quotient->data = realloc(quotient->data, quotient->capacity * sizeof(word));
        }
        for(i = b1->length - 1; i >= 0; i--) {
            gtemp = carry * RADIX + b1->data[i];
            gquot = gtemp / b2->data[0];
            quotient->data[i] = (unsigned)gquot;
            if(quotient->data[i] != 0 && length == 0) length = i + 1;
            carry = gtemp % b2->data[0];
        }
        bignum_fromint(remainder, carry);
        quotient->length = length;
    }
    else { /* Long division is neccessary */
        n = b1->length + 1;
        m = b2->length;
        if(quotient->capacity < n - m) {
            quotient->capacity = n - m;
            quotient->data = realloc(quotient->data, (n - m) * sizeof(word));
        }
        bignum_copy(b1, b1copy);
        bignum_copy(b2, b2copy);
        /* Normalize.. multiply by the divisor by 2 until MSB >= HALFRADIX. This ensures fast
         * convergence when guessing the quotient below. We also multiply the dividend by the
         * same amount to ensure the result does not change. */
        while(b2copy->data[b2copy->length - 1] < HALFRADIX) {
            factor *= 2;
            bignum_imultiply(b2copy, &NUMS[2]);
        }
        if(factor > 1) {
            bignum_fromint(temp, (unsigned)factor);
            bignum_imultiply(b1copy, temp);
        }
        /* Ensure the dividend is longer than the original (pre-normalized) divisor. If it is not
         * we introduce a dummy zero word to artificially inflate it. */
        if(b1copy->length != n) {
            b1copy->length++;
            if(b1copy->length > b1copy->capacity) {
                b1copy->capacity = b1copy->length;
                b1copy->data = realloc(b1copy->data, b1copy->capacity * sizeof(word));
            }
            b1copy->data[n - 1] = 0;
        }
        
        /* Process quotient by long division */
        for(i = n - m - 1; i >= 0; i--) {
            gtemp = RADIX * b1copy->data[i + m] + b1copy->data[i + m - 1];
            gquot = gtemp / b2copy->data[m - 1];
            if(gquot >= RADIX) gquot = UINT_MAX;
            grem = gtemp % b2copy->data[m - 1];
            while(grem < RADIX && gquot * b2copy->data[m - 2] > RADIX * grem + b1copy->data[i + m - 2]) { /* Should not overflow... ? */
                gquot--;
                grem += b2copy->data[m - 1];
            }
            quottemp->data[0] = (unsigned)gquot % RADIX;
            quottemp->data[1] = (gquot / RADIX);
            if(quottemp->data[1] != 0) quottemp->length = 2;
            else quottemp->length = 1;
            bignum_multiply(temp2, b2copy, quottemp);
            if(m + 1 > temp3->capacity) {
                temp3->capacity = m + 1;
                temp3->data = realloc(temp3->data, temp3->capacity * sizeof(word));
            }
            temp3->length = 0;
            for(j = 0; j <= m; j++) {
                temp3->data[j] = b1copy->data[i + j];
                if(temp3->data[j] != 0) temp3->length = j + 1;
            }
            if(bignum_less(temp3, temp2)) {
                bignum_iadd(temp3, b2copy);
                gquot--;
            }
            bignum_isubtract(temp3, temp2);
            for(j = 0; j < temp3->length; j++) b1copy->data[i + j] = temp3->data[j];
            for(j = temp3->length; j <= m; j++) b1copy->data[i + j] = 0;
            quotient->data[i] = (unsigned)gquot;
            if(quotient->data[i] != 0) quotient->length = i;
        }
        
        if(quotient->data[b1->length - b2->length] == 0) quotient->length = b1->length - b2->length;
        else quotient->length = b1->length - b2->length + 1;
        
        /* Divide by factor now to find final remainder */
        carry = 0;
        for(i = b1copy->length - 1; i >= 0; i--) {
            gtemp = carry * RADIX + b1copy->data[i];
            b1copy->data[i] = (unsigned)gtemp/factor;
            if(b1copy->data[i] != 0 && length == 0) length = i + 1;
            carry = (unsigned)gtemp % factor;
        }
        b1copy->length = length;
        bignum_copy(b1copy, remainder);
    }
    bignum_deinit(temp);
    bignum_deinit(temp2);
    bignum_deinit(temp3);
    bignum_deinit(b1copy);
    bignum_deinit(b2copy);
    bignum_deinit(quottemp);
}
Exemple #20
0
/**
 * Perform an in place add into the source bignum. That is source += add
 */
void bignum_iadd(bignum* source, bignum* add) {
    bignum* temp = bignum_init();
    bignum_add(temp, source, add);
    bignum_copy(temp, source);
    bignum_deinit(temp);
}
Exemple #21
0
/**
 * Perform an in place subtract from the source bignum. That is, source -= sub
 */
void bignum_isubtract(bignum* source, bignum* sub) {
    bignum* temp = bignum_init();
    bignum_subtract(temp, source, sub);
    bignum_copy(temp, source);
    bignum_deinit(temp);
}
Exemple #22
0
/**
 * Perform an in place multiplication into the source bignum. That is source *= mult
 */
void bignum_imultiply(bignum* source, bignum* mult) {
    bignum* temp = bignum_init();
    bignum_multiply(temp, source, mult);
    bignum_copy(temp, source);
    bignum_deinit(temp);
}