Ejemplo n.º 1
0
status_t element_invert(element_t c, element_t a)
{
	GroupType type = a->type;
	EXIT_IF_NOT_SAME(a, c);

	if(type == ZR) {
		bn_t s;
		bn_inits(s);
		// compute c = (1 / a) mod n
		bn_gcd_ext(s, c->bn, NULL, a->bn, a->order);
		if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order);
		bn_free(s);
	}
	else if(type == G1) {
		g1_neg(c->g1, a->g1);
	}
	else if(type == G2) {
		g2_neg(c->g2, a->g2);
	}
	else if(type == GT) {
		gt_inv(c->gt, a->gt);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}
	return ELEMENT_OK;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
int cp_rsa_gen_basic(rsa_t pub, rsa_t prv, int bits) {
	bn_t t, r;
	int result = STS_OK;

	if (pub == NULL || prv == NULL || bits == 0) {
		return STS_ERR;
	}

	bn_null(t);
	bn_null(r);

	TRY {
		bn_new(t);
		bn_new(r);

		/* Generate different primes p and q. */
		do {
			bn_gen_prime(prv->p, bits / 2);
			bn_gen_prime(prv->q, bits / 2);
		} while (bn_cmp(prv->p, prv->q) == CMP_EQ);

		/* Swap p and q so that p is smaller. */
		if (bn_cmp(prv->p, prv->q) == CMP_LT) {
			bn_copy(t, prv->p);
			bn_copy(prv->p, prv->q);
			bn_copy(prv->q, t);
		}

		bn_mul(pub->n, prv->p, prv->q);
		bn_copy(prv->n, pub->n);
		bn_sub_dig(prv->p, prv->p, 1);
		bn_sub_dig(prv->q, prv->q, 1);

		bn_mul(t, prv->p, prv->q);

		bn_set_2b(pub->e, 16);
		bn_add_dig(pub->e, pub->e, 1);

		bn_gcd_ext(r, prv->d, NULL, pub->e, t);
		if (bn_sign(prv->d) == BN_NEG) {
			bn_add(prv->d, prv->d, t);
		}

		if (bn_cmp_dig(r, 1) == CMP_EQ) {
			bn_add_dig(prv->p, prv->p, 1);
			bn_add_dig(prv->q, prv->q, 1);
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(t);
		bn_free(r);
	}

	return result;
}
Ejemplo n.º 4
0
int cp_phpe_dec(uint8_t *out, int out_len, uint8_t *in, int in_len, bn_t n,
	bn_t l) {
	bn_t c, u, s;
	int size, result = STS_OK;

	size = bn_size_bin(n);

	if (in_len < 0 || in_len != 2 * size) {
		return STS_ERR;
	}

	bn_null(c);
	bn_null(u);
	bn_null(s);

	TRY {
		bn_new(c);
		bn_new(u);
		bn_new(s);

		/* Compute (c^l mod n^2) * u mod n. */
		bn_sqr(s, n);
		bn_read_bin(c, in, in_len);
		bn_mxp(c, c, l, s);
		bn_sub_dig(c, c, 1);
		bn_div(c, c, n);
		bn_gcd_ext(s, u, NULL, l, n);
		if (bn_sign(u) == BN_NEG) {
			bn_add(u, u, n);
		}
		bn_mul(c, c, u);
		bn_mod(c, c, n);

		size = bn_size_bin(c);
		if (size <= out_len) {
			memset(out, 0, out_len);
			bn_write_bin(out + (out_len - size), size, c);
		} else {
			result = STS_ERR;
		}
	} CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(c);
		bn_free(u);
		bn_free(s);
	}

	return result;
}
Ejemplo n.º 5
0
// int appears on rhs
status_t element_div_int(element_t c, element_t a, integer_t b)
{
	GroupType type = a->type;
	EXIT_IF_NOT_SAME(c, a);
	LEAVE_IF( c->isInitialized != TRUE || a->isInitialized != TRUE, "uninitialized arguments.");
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	if(type == ZR) {
		if(bn_is_zero(b)) return ELEMENT_DIV_ZERO;
//		if(bn_is_one(a->bn)) {
//			element_set_int(a, b);
//			return element_invert(c, a); // not going to work
//		}

		integer_t s;
		bn_inits(s);
		// compute c = (1 / b) mod order
		bn_gcd_ext(s, c->bn, NULL, b, a->order);
		if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order);
		if(bn_is_one(a->bn) && bn_sign(a->bn) == BN_POS) {
			bn_free(s);
			return ELEMENT_OK;
		}
		// remainder of ((a * c) / order)
		// c = (a * c) / order (remainder only)
		bn_mul(s, a->bn, c->bn);
		bn_div_rem(s, c->bn, s, a->order);
//		if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order);
		bn_free(s);
//		bn_div(c->bn, a->bn, b);
//		bn_mod(c->bn, c->bn, c->order);
	}
	else if(type == G1 || type == G2 || type == GT) {
		if(bn_is_one(b)) {
			return element_set(c, a);
		}
		// TODO: other cases: b > 1 (ZR)?
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Ejemplo n.º 6
0
int cp_bbs_sig(g1_t s, uint8_t *msg, int len, int hash, bn_t d) {
	bn_t m, n, r;
	uint8_t h[MD_LEN];
	int result = STS_OK;

	bn_null(m);
	bn_null(n);
	bn_null(r);

	TRY {
		bn_new(m);
		bn_new(n);
		bn_new(r);

		g1_get_ord(n);

		/* m = H(msg). */
		if (hash) {
			bn_read_bin(m, msg, len);
		} else {
			md_map(h, msg, len);
			bn_read_bin(m, h, MD_LEN);
		}
		bn_mod(m, m, n);

		/* m = 1/(m + d) mod n. */
		bn_add(m, m, d);
		bn_gcd_ext(r, m, NULL, m, n);
		if (bn_sign(m) == BN_NEG) {
			bn_add(m, m, n);
		}
		/* s = 1/(m+d) * g1. */
		g1_mul_gen(s, m);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(n);
		bn_free(r);
	}
	return result;
}