int inverse(bn_st * inv_in, bn_st * in, bn_st * modulus, int sizeof_mod) { // Compute the inverse of in using an extended Euclidian Algorithm // This cooresponds to the formula out = inv_in*in + useless*modulus // Where, since mod is prime, out should be equal to 1 and 1 = in*inv_in // Otherwise throws an error bn_mod_basic(in,in,modulus); bn_st out, useless; bn_new_size(&out, 2*sizeof_mod+1); bn_new_size(&useless, sizeof_mod); bn_gcd_ext(&out, inv_in, &useless, in, modulus); // Check if out is actually one bn_st is_one; bn_new_size(&is_one, sizeof_mod); bn_set_2b(&is_one, 0); // Set an integer to one if (bn_cmp(&out, &is_one) != CMP_EQ) { error_hdl(-1,"The modulus is not prime, can't calculate the inverse"); return 1; } bn_clean(&is_one); bn_clean(&out); bn_clean(&useless); return 0; }
void bn_sqr_comba(bn_t c, const bn_t a) { int digits; bn_t t; bn_null(t); digits = 2 * a->used; TRY { /* We need a temporary variable so that c can be a or b. */ bn_new_size(t, digits); t->used = digits; bn_sqrn_low(t->dp, a->dp, a->used); t->sign = BN_POS; bn_trim(t); bn_copy(c, t); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }
void bn_sqr_basic(bn_t c, const bn_t a) { int i, digits; bn_t t; bn_null(t); digits = 2 * a->used; TRY { bn_new_size(t, digits); bn_zero(t); t->used = digits; for (i = 0; i < a->used; i++) { bn_sqra_low(t->dp + (2 * i), a->dp + i, a->used - i); } t->sign = BN_POS; bn_trim(t); bn_copy(c, t); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }
int bn_new_array(bn_st * array, int size) { for (int i = 0; i < size; ++i) { bn_new_size(array + i, RELIC_DIGS); } return 0; }
int bn_sqr_mod(bn_st * out, bn_st * in, bn_st * modulus) { bn_t temp; bn_new_size(temp, 2*RELIC_DIGS); bn_sqr_basic(temp, in); bn_mod_basic(out,temp, modulus); bn_clean(temp); return 0; }
int bn_add_mod(bn_st * out, bn_st * in1, bn_st * in2, bn_st * modulus) { // Temporary variable in which to store the reuslt of the addition // before appplying the modular reduction bn_st temp; bn_new_size(&temp, RELIC_DIGS+1); // Addition bn_add(&temp,in1,in2); // Modular reduction bn_mod_basic(out, &temp, modulus); bn_clean(&temp); return 0; }
/** * Divides two multiple precision integers, computing the quotient and the * remainder. * * @param[out] c - the quotient. * @param[out] d - the remainder. * @param[in] a - the dividend. * @param[in] b - the the divisor. */ static void bn_div_imp(bn_t c, bn_t d, const bn_t a, const bn_t b) { bn_t q, x, y, r; int sign; bn_null(q); bn_null(x); bn_null(y); bn_null(r); /* If a < b, we're done. */ if (bn_cmp_abs(a, b) == CMP_LT) { if (bn_sign(a) == BN_POS) { if (c != NULL) { bn_zero(c); } if (d != NULL) { bn_copy(d, a); } } else { if (c != NULL) { bn_set_dig(c, 1); if (bn_sign(b) == BN_POS) { bn_neg(c, c); } } if (d != NULL) { if (bn_sign(b) == BN_POS) { bn_add(d, a, b); } else { bn_sub(d, a, b); } } } return; } TRY { bn_new(x); bn_new(y); bn_new_size(q, a->used + 1); bn_new(r); bn_zero(q); bn_zero(r); bn_abs(x, a); bn_abs(y, b); /* Find the sign. */ sign = (a->sign == b->sign ? BN_POS : BN_NEG); bn_divn_low(q->dp, r->dp, x->dp, a->used, y->dp, b->used); /* We have the quotient in q and the remainder in r. */ if (c != NULL) { q->used = a->used - b->used + 1; q->sign = sign; bn_trim(q); if (bn_sign(a) == BN_NEG) { bn_sub_dig(c, q, 1); } else { bn_copy(c, q); } } if (d != NULL) { r->used = b->used; r->sign = a->sign; bn_trim(r); if (bn_sign(a) == BN_NEG) { bn_add(d, r, b); } else { bn_copy(d, r); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(r); bn_free(q); bn_free(x); bn_free(y); } }