Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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);
	}
}
Exemplo n.º 3
0
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);
	}
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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);
	}
}