Beispiel #1
0
// int appears on lhs (1 / [ZR, G1, G2, GT])
status_t element_int_div(element_t c, integer_t a, element_t b)
{
	GroupType type = b->type;
	EXIT_IF_NOT_SAME(c, b);
	LEAVE_IF( c->isInitialized != TRUE || b->isInitialized != TRUE, "uninitialized arguments.");
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	if(type == ZR) {
		if(bn_is_zero(b->bn)) return ELEMENT_DIV_ZERO;
		element_invert(c, b);
		if(bn_is_one(a)) return ELEMENT_OK;
		integer_t s;
		bn_inits(s);
		bn_mul(s, a, c->bn);
		bn_div_rem(s, c->bn, s, c->order);
//		if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, c->order);
		bn_free(s);
//		bn_div(c->bn, a, b->bn);
//		bn_mod(c->bn, c->bn, c->order);
	}
	else if(type == G1 || type == G2 || type == GT) {
		if(bn_is_one(a)) {
			element_invert(c, b);
		}
		// TODO: other cases: a > 1 (ZR)?
	}

	return ELEMENT_OK;
}
Beispiel #2
0
status_t element_mul(element_t c, element_t a, element_t b)
{
	GroupType type = a->type;
	EXIT_IF_NOT_SAME(a, b);
	LEAVE_IF(a->isInitialized != TRUE || b->isInitialized != TRUE || c->isInitialized != TRUE, "uninitialized arguments.");
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	if(type == ZR) {
		bn_mul(c->bn, a->bn, b->bn);
		bn_mod(c->bn, c->bn, c->order);
	}
	else if(type == G1) {
		g1_add(c->g1, a->g1, b->g1);
		g1_norm(c->g1, c->g1);
	}
	else if(type == G2) {
		g2_add(c->g2, a->g2, b->g2);
		g2_norm(c->g2, c->g2);
	}
	else if(type == GT) {
		gt_mul(c->gt, a->gt, b->gt);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Beispiel #3
0
status_t element_pow_int(element_t c, element_t a, integer_t b)
{
	GroupType type = a->type;
	// TODO: c (type) = a (type) ^ b (ZR)
	LEAVE_IF( c->isInitialized != TRUE || a->isInitialized != TRUE, "uninitialized argument.");
	EXIT_IF_NOT_SAME(c, a);
	LEAVE_IF(b == NULL, "uninitialized integer.");

	status_t result = ELEMENT_OK;
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	switch(type) {
		case ZR: bn_mxp(c->bn, a->bn, b, a->order);
				 break;
		case G1: g1_mul(c->g1, a->g1, b);
				 break;
		case G2: g2_mul(c->g2, a->g2, b);
				 break;
		case GT: gt_exp(c->gt, a->gt, b);
				 break;
		default:
				 result = ELEMENT_INVALID_TYPES;
				 break;
	}

	return result;

}
Beispiel #4
0
status_t element_mul_int(element_t c, element_t a, integer_t b)
{
	GroupType type = a->type;
	// TODO: c (type) = a (type) * b (ZR)
	LEAVE_IF(a->isInitialized != TRUE, "invalid argument.");
	LEAVE_IF(c->isInitialized != TRUE || c->type != type, "result not initialized or invalid type.");

	if(type == ZR) {
		bn_mul(c->bn, a->bn, b);
		bn_mod(c->bn, c->bn, c->order);
	}
	else if(type == G1) {
		g1_mul(c->g1, a->g1, b);
	}
	else if(type == G2) {
		g2_mul(c->g2, a->g2, b);
	}
	else if(type == GT) {
		gt_exp(c->gt, a->gt, b);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Beispiel #5
0
status_t element_pow_zr(element_t c, element_t a, element_t b)
{
	GroupType type = a->type;
	// c (type) = a (type) ^ b (ZR)
	LEAVE_IF( c->isInitialized != TRUE || a->isInitialized != TRUE, "uninitialized argument.");
	EXIT_IF_NOT_SAME(c, a);
	LEAVE_IF(a->isInitialized != TRUE, "invalid argument.");
	LEAVE_IF(b->isInitialized != TRUE || b->type != ZR, "invalid type.");

	if(type == ZR) {
		bn_mxp(c->bn, a->bn, b->bn, a->order);
	}
	else if(type == G1) {
		g1_mul(c->g1, a->g1, b->bn);
	}
	else if(type == G2) {
		g2_mul(c->g2, a->g2, b->bn);
	}
	else if(type == GT) {
		gt_exp(c->gt, a->gt, b->bn);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Beispiel #6
0
status_t element_to_key(element_t e, uint8_t *data, int data_len, uint8_t label)
{
	LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument.");
	// adds an extra null byte by default - will use this last byte for the label
	int d_len = element_length(e), digest_len = SHA_LEN;

	uint8_t d[d_len + 1];
	memset(d, 0, d_len);
	// write e to a tmp buf
	if(d_len > 0 && digest_len <= data_len) {
		element_to_bytes(d, d_len, e);
		d[d_len-1] = label;
#ifdef DEBUG
		printf("%s: bytes form....\n", __FUNCTION__);
		print_as_hex(d, d_len);
#endif
		// hash buf using md_map_sh256 and store data_len bytes in data
		uint8_t digest[digest_len + 1];
		memset(digest, 0, digest_len);
		SHA_FUNC(digest, d, d_len);
		memcpy(data, digest, digest_len);
#ifdef DEBUG
		printf("%s: digest: ", __FUNCTION__);
		print_as_hex(data, digest_len);
#endif
		return ELEMENT_OK;
	}
	return ELEMENT_INVALID_ARG;
}
Beispiel #7
0
status_t element_from_hash(element_t e, unsigned char *data, int len)
{
	LEAVE_IF(e->isInitialized == FALSE, "uninitialized argument.");
	GroupType type = e->type;
	status_t result = ELEMENT_OK;
	int digest_len = SHA_LEN;
	unsigned char digest[digest_len + 1];
	memset(digest, 0, digest_len);
	SHA_FUNC(digest, data, len);

#ifdef DEBUG
	printf("%s: digest: ", __FUNCTION__);
	print_as_hex(digest, digest_len);
#endif

	switch(type) {
		case ZR: bn_read_bin(e->bn, digest, digest_len);
			 if(bn_cmp(e->bn, e->order) == CMP_GT) bn_mod(e->bn, e->bn, e->order);
//		    	 bn_print(e->bn);
				 break;
		case G1: g1_map(e->g1, digest, digest_len);
				 break;
		case G2: g2_map(e->g2, digest, digest_len);
				 break;
		default:
				 result = ELEMENT_INVALID_TYPES;
				 break;
	}

	return result;
}
Beispiel #8
0
status_t element_div(element_t c, element_t a, element_t b)
{
	GroupType type = a->type;
	EXIT_IF_NOT_SAME(a, b);
	LEAVE_IF(a->isInitialized != TRUE || b->isInitialized != TRUE || c->isInitialized != TRUE, "uninitialized arguments.");
	LEAVE_IF( c->type != type, "result initialized but invalid type.");

	if(type == ZR) {
		if(bn_is_zero(b->bn)) return ELEMENT_DIV_ZERO;
		// c = (1 / b) mod order
		element_invert(c, b);
		if(bn_is_one(a->bn))  return ELEMENT_OK;
//		bn_div(c->bn, a->bn, b->bn);
//		bn_mod(c->bn, c->bn, c->order);
		// remainder of ((a * c) / order)
		integer_t s;
		bn_inits(s);
		// 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);


	}
	else if(type == G1) {
		g1_sub(c->g1, a->g1, b->g1);
		g1_norm(c->g1, c->g1);
	}
	else if(type == G2) {
		g2_sub(c->g2, a->g2, b->g2);
		g2_norm(c->g2, c->g2);
	}
	else if(type == GT) {
		gt_t t;
		gt_inits(t);
		gt_inv(t, b->gt);
		gt_mul(c->gt, a->gt, t);
		gt_free(t);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Beispiel #9
0
status_t element_set_si(element_t e, unsigned int x)
{
	LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument.");
	if(e->type == ZR) {
		bn_set_dig(e->bn, x);
	}

	return ELEMENT_OK;
}
Beispiel #10
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;
}
Beispiel #11
0
// copy x into e
status_t element_set_int(element_t e, integer_t x)
{
	LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument.");
	if(e->type == ZR) {
		bn_copy(e->bn, x);
		return ELEMENT_OK;
	}

	return ELEMENT_INVALID_TYPES;
}
Beispiel #12
0
status_t pairing_apply(element_t et, element_t e1, element_t e2)
{
	LEAVE_IF(e1->isInitialized != TRUE || e2->isInitialized != TRUE || et->isInitialized != TRUE, "uninitialized arguments.");
	if(e1->type == G1 && e2->type == G2 && et->type == GT) {
		/* compute optimal ate pairing */
		pp_map_oatep(et->gt, e1->g1, e2->g2);
		return ELEMENT_OK;
	}
	return ELEMENT_INVALID_ARG;
}
Beispiel #13
0
/*!
 * Hash a null-terminated string to a byte array.
 *
 * @param input_buf		The input buffer.
 * @param input_len		The input buffer length (in bytes).
 * @param output_buf	A pre-allocated output buffer of size hash_len.
 * @param hash_len		Length of the output hash (in bytes). Should be approximately bit size of curve group order.
 * @param hash_prefix	prefix for hash function.
 */
status_t hash_buffer_to_bytes(uint8_t *input_buf, int input_len, uint8_t *output_buf, int hash_len, uint8_t hash_prefix)
{
	LEAVE_IF(input_buf == NULL || output_buf == NULL, "uninitialized argument.");
	int i, new_input_len = input_len + 2; // extra byte for prefix
	uint8_t first_block = 0;
	uint8_t new_input[new_input_len+1];
//	printf("orig input => \n");
//	print_as_hex(input_buf, input_len);

	memset(new_input, 0, new_input_len+1);
	new_input[0] = first_block; // block number (always 0 by default)
	new_input[1] = hash_prefix; // set hash prefix
	memcpy((uint8_t *)(new_input+2), input_buf, input_len); // copy input bytes

//	printf("new input => \n");
//	print_as_hex(new_input, new_input_len);
	// prepare output buf
	memset(output_buf, 0, hash_len);

	if (hash_len <= SHA_LEN) {
		uint8_t md[SHA_LEN+1];
		SHA_FUNC(md, new_input, new_input_len);
		memcpy(output_buf, md, hash_len);
	}
	else {
		// apply variable-size hash technique to get desired size
		// determine block count.
		int blocks = (int) ceil(((double) hash_len) / SHA_LEN);
		//debug("Num blocks needed: %d\n", blocks);
		uint8_t md[SHA_LEN+1];
		uint8_t md2[(blocks * SHA_LEN)+1];
		uint8_t *target_buf = md2;
		for(i = 0; i < blocks; i++) {
			/* compute digest = SHA-2( i || prefix || input_buf ) || ... || SHA-2( n-1 || prefix || input_buf ) */
			target_buf += (i * SHA_LEN);
			new_input[0] = (uint8_t) i;
			//debug("input %d => ", i);
			//print_as_hex(new_input, new_input_len);

			SHA_FUNC(md, new_input, new_input_len);
			memcpy(target_buf, md, hash_len);
			//debug("block %d => ", i);
			//print_as_hex(md, SHA_LEN);
			memset(md, 0, SHA_LEN);
		}
		// copy back to caller
		memcpy(output_buf, md2, hash_len);
	}

	return ELEMENT_OK;
}
Beispiel #14
0
int element_is_member(element_t e)
{
	LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument.");
	int result;

	if(e->type == ZR) {
		if(bn_cmp(e->bn, e->order) <= CMP_EQ)
			result = TRUE;
		else
			result = FALSE;
	}
	else if(e->type == G1) {
		g1_t r;
		g1_inits(r);

		g1_mul(r, e->g1, e->order);
		if(g1_is_infty(r) == 1)
			result = TRUE;
		else
			result = FALSE;
		g1_free(r);
	}
	else if(e->type == G2) {
		g2_t r;
		g2_inits(r);

		g2_mul(r, e->g2, e->order);
		if(g2_is_infty(r) == 1)
			result = TRUE;
		else
			result = FALSE;
		g2_free(r);
	}
	else if(e->type == GT) {
		gt_t r;
		gt_inits(r);

		gt_exp(r, e->gt, e->order);
		if(gt_is_unity(r) == 1)
			result = TRUE;
		else
			result = FALSE;
		gt_free(r);
	}
	else {
		result = ELEMENT_INVALID_ARG;
	}

	return result;
}
Beispiel #15
0
// x = e (copies for ZR, maps x-coordinate for G1, and not defined for G2 or GT)
status_t element_to_int(integer_t x, element_t e)
{
	LEAVE_IF(x == NULL || e->isInitialized != TRUE, "uninitialized argument.");

	if(e->type == ZR) {
		bn_copy(x, e->bn);
	}
	else if(e->type == G1) {
		fp_prime_back(x, e->g1->x);
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Beispiel #16
0
int element_cmp(element_t a, element_t b)
{
	GroupType type = a->type;
	LEAVE_IF(a->isInitialized != TRUE || b->isInitialized != TRUE, "uninitialized argument.");
	EXIT_IF_NOT_SAME(a, b);

	switch(type) {
		case ZR: return bn_cmp(a->bn, b->bn);
		case G1: return g1_cmp(a->g1, b->g1);
		case G2: return g2_cmp(a->g2, b->g2);
		case GT: return gt_cmp(a->gt, b->gt);
		default: break;
	}

	return ELEMENT_INVALID_TYPES;
}
Beispiel #17
0
status_t element_pp_pow_int(element_t o, element_pp_t e_pp, GroupType type, integer_t bn)
{
	if(e_pp->isInitialized == FALSE) return ELEMENT_UNINITIALIZED;
	LEAVE_IF(bn == NULL, "uninitialized integer.");

	if(o->type == type) {
		if(type == G1) {
			g1_mul_fix(o->g1, e_pp->t1, bn);
		}
		else if(type == G2) {
			g2_mul_fix(o->g2, e_pp->t2, bn);
		}
		return ELEMENT_OK;
	}

	return ELEMENT_INVALID_ARG;
}
Beispiel #18
0
status_t hash_buffer_to_bytes(uint8_t *input, int input_len, uint8_t *output, int output_len, uint8_t label)
{
	LEAVE_IF(input == NULL || output == NULL, "uninitialized argument.");
	// adds an extra null byte by default - will use this last byte for the label
	int digest_len = SHA_LEN;

	if(digest_len <= output_len) {
		// hash buf using md_map_sh256 and store data_len bytes in data
		uint8_t digest[digest_len + 1];
		memset(digest, 0, digest_len);
		SHA_FUNC(digest, input, input_len);
		memcpy(output, digest, digest_len);
#ifdef DEBUG
		printf("%s: digest: ", __FUNCTION__);
		print_as_hex(output, digest_len);
#endif
		return ELEMENT_OK;
	}
	return ELEMENT_INVALID_ARG;
}
Beispiel #19
0
status_t element_from_bytes(element_t e, unsigned char *data, int data_len)
{
	LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument.");
	GroupType type = e->type;
	if(type == ZR) {
		bn_read_bin(e->bn, data, data_len);
	}
	else if(type == G1) {
		return g1_read_bin(e->g1, data, data_len); // x & y
	}
	else if(type == G2) {
		return g2_read_bin(e->g2, data, data_len); // x1, y1  & x2, y2
	}
	else if(type == GT) {
		return gt_read_bin(e->gt, data, data_len); // x1-6 && y1-6
	}
	else {
		return ELEMENT_INVALID_TYPES;
	}

	return ELEMENT_OK;
}
Beispiel #20
0
// e = a
status_t element_set(element_t e, element_t a)
{
	GroupType type = a->type;
	LEAVE_IF(e->isInitialized != TRUE || a->isInitialized != TRUE, "uninitialized argument.");
	EXIT_IF_NOT_SAME(e, a);
	status_t result = ELEMENT_OK;

	switch(type) {
		case ZR: bn_copy(e->bn, a->bn);
				 break;
		case G1: g1_copy(e->g1, a->g1);
				 break;
		case G2: g2_copy(e->g2, a->g2);
				 break;
		case GT: gt_copy(e->gt, a->gt);
				 break;
		default:
				 result = ELEMENT_INVALID_TYPES;
				 break;
	}

	return result;
}
Beispiel #21
0
status_t element_from_hash(element_t e, unsigned char *data, int len)
{
	LEAVE_IF(e->isInitialized == FALSE, "uninitialized argument.");
	GroupType type = e->type;
	status_t result = ELEMENT_OK;
	int digest_len = SHA_LEN;
	unsigned char digest[digest_len + 1];
	memset(digest, 0, digest_len);
	SHA_FUNC(digest, data, len);

	switch(type) {
		case ZR: bn_read_bin(e->bn, digest, digest_len);
				 break;
		case G1: g1_map(e->g1, digest, digest_len);
				 break;
		case G2: g2_map(e->g2, digest, digest_len);
				 break;
		default:
				 result = ELEMENT_INVALID_TYPES;
				 break;
	}

	return result;
}