Example #1
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;
}
Example #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;
}
Example #3
0
int cp_phpe_gen(bn_t n, bn_t l, int bits) {
	bn_t p, q;
	int result = STS_OK;

	bn_null(p);
	bn_null(q);

	TRY {
		bn_new(p);
		bn_new(q);

		/* Generate primes p and q of equivalent length. */
		do {
			bn_gen_prime(p, bits / 2);
			bn_gen_prime(q, bits / 2);
		} while (bn_cmp(p, q) == CMP_EQ);

		/* Compute n = pq and l = \phi(n). */
		bn_mul(n, p, q);
		bn_sub_dig(p, p, 1);
		bn_sub_dig(q, q, 1);
		bn_mul(l, p, q);
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(p);
		bn_free(q);
	}

	return result;
}
Example #4
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;
}
Example #5
0
int kx_self_test()
{
    const static unsigned char test_a[] = {0x2e, 0x4e, 0x3a, 0x05, 0xd8, 0xff, 0x06, 0x2b, 0x4e, 0x46, 0xda, 0x6e, 0x12, 0x9c, 0xf3, 0x40, 0xb3, 0x07, 0x66, 0x99, 0x8a, 0x0e, 0x09, 0xe3, 0x93, 0x65, 0xa5, 0x52, 0x2d, 0x84, 0x83, 0x04},
        test_b[] = {0x6d, 0xd0, 0xae, 0x87, 0x4e, 0x86, 0xa8, 0x11, 0xf8, 0x1b, 0x2e, 0xf5, 0x25, 0x61, 0x50, 0x8d, 0x91, 0x4a, 0x43, 0x53, 0xb1, 0x24, 0x73, 0xe1, 0x18, 0xff, 0x35, 0xdb, 0x2c, 0x77, 0xbd, 0x4e, 0x24, 0x3f, 0xd8, 0x81, 0x82, 0xcd, 0x9e, 0x30, 0xf4, 0xd1, 0x62, 0xb1, 0xe5, 0x57, 0xd5, 0x09, 0x66, 0xfa, 0x9c, 0xdf, 0x97, 0xd4, 0xf6, 0x94, 0xc2, 0x68, 0xb8, 0x91, 0x7d, 0x40, 0xa5, 0x43, 0x96, 0xbe, 0xc4, 0xa9, 0x50, 0x93, 0xbf, 0x13, 0x44, 0x06, 0xaf, 0x3a, 0xb2, 0xf6, 0xf6, 0x22, 0x1f, 0x11, 0x38, 0xae, 0x7e, 0x6c, 0xa1, 0xb4, 0xb9, 0xd1, 0x07, 0x4f, 0x06, 0xf7, 0x09, 0x8d, 0x85, 0x11, 0x38, 0xd4, 0xd4, 0xb8, 0x8f, 0x4d, 0xe1, 0xce, 0x9f, 0x11, 0xb0, 0x49, 0xac, 0x5b, 0x74, 0xef, 0x8b, 0x8e, 0xa4, 0x80, 0xb3, 0xdf, 0xea, 0x85, 0x18, 0x58, 0xc0, 0x3f, 0x79, 0x31, 0x99, 0x96, 0x9f, 0x8e, 0x12, 0x08, 0xb2, 0x32, 0x3f, 0x73, 0xdb, 0x31, 0x4b, 0x19, 0x41, 0x06, 0xb9, 0x98, 0x4b, 0xe5, 0x13, 0xd8, 0xb8, 0xab, 0x4e, 0x1d, 0x0e, 0xff, 0x5a, 0x1a, 0x13, 0xa0, 0x9c, 0xa1, 0x74, 0x59, 0xce, 0x9a, 0x6e, 0x5e, 0xf5, 0xec, 0x2e, 0x3a, 0xcb, 0x76, 0x61, 0x33, 0x36, 0x59, 0x70, 0xa8, 0xcb, 0x86, 0x88, 0x24, 0xff, 0x14, 0x61, 0x8e, 0x0d, 0x2d, 0x58, 0xe2, 0x45, 0xb9, 0x8b, 0x1c, 0xb6, 0x66, 0xa7, 0xa0, 0x7d, 0xb1, 0x45, 0x93, 0x1b, 0xe6, 0xb0, 0x4c, 0xb2, 0xd4, 0xe2, 0x62, 0x0b, 0x26, 0x30, 0x91, 0x40, 0xe9, 0x1e, 0x60, 0x8e, 0xcd, 0xba, 0x19, 0x92, 0x1b, 0xdd, 0xf3, 0xd7, 0xff, 0x7b, 0x12, 0x97, 0x5c, 0x9c, 0xe9, 0x5e, 0x28, 0x82, 0x6d, 0xbc, 0xc9, 0xd8, 0x77, 0x47, 0x94, 0x04, 0xd6, 0xa7, 0x74, 0xcb, 0xc8, 0xfa, 0x78, 0x08, 0xa0},
        exp_A[] = {0x69, 0x72, 0x9a, 0x40, 0x98, 0xdc, 0x2c, 0x5c, 0xaa, 0xc5, 0xd8, 0x27, 0x9a, 0xc4, 0xa1, 0x2f, 0x24, 0x66, 0x8f, 0xd0, 0xe4, 0xf1, 0x17, 0xd3, 0x51, 0xa7, 0xb3, 0xcf, 0x00, 0x5c, 0x5e, 0x31, 0x74, 0x19, 0xca, 0xeb, 0xb1, 0x13, 0x1f, 0xd7, 0x58, 0x45, 0x29, 0x79, 0x21, 0x03, 0x88, 0x89, 0xcd, 0x31, 0x4d, 0xff, 0x9f, 0x56, 0xaf, 0xf2, 0x18, 0xcd, 0x81, 0x04, 0x0b, 0x17, 0x75, 0x63, 0x60, 0x1d, 0xfe, 0x58, 0xa0, 0xe0, 0x2b, 0x2f, 0xf3, 0x57, 0x46, 0xcb, 0xee, 0x51, 0x76, 0xcb, 0x4e, 0x69, 0x34, 0xcf, 0xa2, 0x7d, 0x59, 0xcc, 0x12, 0x08, 0x89, 0x76, 0x6b, 0x72, 0xcc, 0xe4, 0x6c, 0x09, 0x79, 0x57, 0xd0, 0x06, 0xe0, 0xf2, 0x21, 0xc3, 0xe2, 0x30, 0x3b, 0x63, 0x41, 0x6f, 0xe5, 0x84, 0xa3, 0x8a, 0x8b, 0x79, 0xb7, 0x92, 0xbc, 0xd5, 0xb6, 0xe7, 0xfe, 0xa2, 0x9a, 0x1d, 0x26, 0x00, 0x52, 0x92, 0x02, 0xb3, 0xdf, 0xf2, 0xf3, 0x41, 0x42, 0xa6, 0x82, 0xd9, 0xad, 0x0a, 0xf8, 0x32, 0x1c, 0x11, 0x14, 0x2c, 0x9d, 0xc3, 0x08, 0x6a, 0x92, 0x59, 0x3a, 0x61, 0x8a, 0xda, 0xc9, 0xbb, 0x46, 0x4f, 0xc8, 0x68, 0x3d, 0xee, 0x6a, 0xac, 0x15, 0xb0, 0x94, 0x64, 0x27, 0x74, 0xc9, 0xe4, 0xa8, 0xf6, 0xb6, 0x0e, 0x6c, 0x26, 0x0b, 0x31, 0x38, 0x9d, 0x40, 0xd7, 0x34, 0x3c, 0xd4, 0xe5, 0xf6, 0xea, 0xa0, 0xcb, 0xec, 0xfa, 0x92, 0x0a, 0x6a, 0x9d, 0x95, 0x52, 0x39, 0x22, 0x29, 0x54, 0x2d, 0x52, 0x43, 0x50, 0xab, 0x94, 0xf9, 0xda, 0x45, 0x6f, 0xa7, 0xd1, 0x64, 0x18, 0x25, 0x3e, 0xb4, 0x0a, 0xda, 0xf6, 0xb7, 0x49, 0x7d, 0xe2, 0x0c, 0x9c, 0x26, 0xed, 0xbb, 0xdc, 0x56, 0xc2, 0x7f, 0x43, 0x2e, 0xad, 0xac, 0x5e, 0x1f, 0xbc, 0x9f, 0xdf, 0x2c, 0xe8, 0x4b, 0xe6},
        exp_k[] = {0x25, 0xe1, 0xd6, 0xba, 0x1f, 0x49, 0x90, 0x47, 0x87, 0x87, 0xc8, 0x54, 0xfb, 0xed, 0xe8, 0xff, 0xe9, 0x5e, 0x2d, 0xc5, 0xed, 0xf7, 0x88, 0x36, 0x5f, 0x27, 0x98, 0x32, 0x7e, 0x10, 0x77};
    int result = FAILURE;
    kx_t kx;
    bn_t A, b, exp;
    unsigned char k[31];
    
    bn_init(&A);
    bn_init(&b);
    bn_init(&exp);

    if (kx_init_std(&kx, KX_GROUP_2048_256) != SUCCESS)
        goto fail2;

    if (bn_from_bytes(&kx.a, test_a, sizeof(test_a)) != SUCCESS)
        goto fail;

    if (kx_get_A(&kx, &A) != SUCCESS)
        goto fail;

    if (bn_from_bytes(&exp, exp_A, sizeof(exp_A)) != SUCCESS)
        goto fail;

    if (bn_cmp(&A, &exp) != 0)
        goto fail;

    if (bn_from_bytes(&b, test_b, sizeof(test_b)) != SUCCESS)
        goto fail;

    if (kx_set_b(&kx, &b) != SUCCESS)
        goto fail;

    if (kx_get_sk(&kx, k, sizeof(k) * 8) != SUCCESS)
        goto fail;

    if (memcmp(k, exp_k, sizeof(k)) != 0)
        goto fail;

    result = SUCCESS;

fail:
    kx_destroy(&kx);
fail2:
    if (result == FAILURE)
        fdprintf(STDERR, "KX self-test FAILED!\n");
    bn_destroy(&A);
    bn_destroy(&b);
    bn_destroy(&exp);
    return result;
}
Example #6
0
int cp_bdpe_dec(dig_t *out, uint8_t *in, int in_len, bdpe_t prv) {
	bn_t m, t, z;
	unsigned i;
	int size, result = STS_OK;

	size = bn_size_bin(prv->n);

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

	bn_null(m);
	bn_null(t);
	bn_null(z);

	TRY {
		bn_new(m);
		bn_new(t);
		bn_new(z);

		/* Compute t = (p-1)(q-1)/block. */
		bn_mul(t, prv->p, prv->q);
		bn_sub(t, t, prv->p);
		bn_sub(t, t, prv->q);
		bn_add_dig(t, t, 1);
		bn_div_dig(t, t, prv->t);
		bn_read_bin(m, in, in_len);
		bn_mxp(m, m, t, prv->n);
		bn_mxp(t, prv->y, t, prv->n);

		for (i = 0; i < prv->t; i++) {
			bn_mxp_dig(z, t, i, prv->n);
			if (bn_cmp(z, m) == CMP_EQ) {
				*out = i;
				break;
			}
		}

		if (i == prv->t) {
			result = STS_ERR;
		}
	} CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(t);
		bn_free(z);
	}

	return result;
}
Example #7
0
int igraph_biguint_compare(igraph_biguint_t *left, igraph_biguint_t *right) {
  /* bn_cmp requires the two numbers to have the same number of limbs,
     so we do this partially by hand here */
  long int size_left=igraph_biguint_size(left);
  long int size_right=igraph_biguint_size(right);
  while (size_left > size_right) { 
    if (VECTOR(left->v)[--size_left] > 0) { return +1; }
  }
  while (size_right > size_left) {
    if (VECTOR(right->v)[--size_right] > 0) { return -1; }
  }
  return bn_cmp( VECTOR(left->v), VECTOR(right->v), size_right );
}
Example #8
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;
}
Example #9
0
int bn_sub_mod(bn_st * out, bn_st * in1, bn_st * in2, bn_st * modulus)
{
	if (bn_cmp(in1,in2) == CMP_GT)
	{
		// If in1 > in2 we just subtract
		bn_sub(out,in1,in2);
	}
	else
	{
		// Otherwise compute mod + in1 - in2
		bn_add(out, modulus, in1);
		bn_sub(out,out,in2);
	}
	return 0;
}
Example #10
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;
}
Example #11
0
int bn_factor(bn_t c, const bn_t a) {
    bn_t t0, t1;
    int result;
    unsigned int i, tests;

    bn_null(t0);
    bn_null(t1);

    result = 1;

    if (bn_is_even(a)) {
        bn_set_dig(c, 2);
        return 1;
    }

    TRY {
        bn_new(t0);
        bn_new(t1);

        bn_set_dig(t0, 2);

#if WORD == 8
        tests = 255;
#else
        tests = 65535;
#endif
        for (i = 2; i < tests; i++) {
            bn_set_dig(t1, i);
            bn_mxp(t0, t0, t1, a);
        }

        bn_sub_dig(t0, t0, 1);
        bn_gcd(t1, t0, a);
        if (bn_cmp_dig(t1, 1) == CMP_GT && bn_cmp(t1, a) == CMP_LT) {
            bn_copy(c, t1);
        } else {
            result = 0;
        }
    } CATCH_ANY {
        THROW(ERR_CAUGHT);
    } FINALLY {
        bn_free(t0);
        bn_free(t1);
    }
    return result;
}
Example #12
0
dh_ctxt_t *dh_init(bn_t *p, bn_t *g)
{
	dh_ctxt_t *res;
	bn_t *t;

	if (p == NULL || g == NULL)
		return NULL;

	assert(p->n == g->n);

	if ((res = (dh_ctxt_t *)mem_alloc(sizeof(dh_ctxt_t))) == NULL)
		return NULL;

	res->g = g;
	res->p = p;

	t = bn_copy(bn_alloc(p->n), p);
	bn_sub_ui(t, t, 2, p);

	// Check g \in [2, p - 2].
	if (bn_cmp_ui(g, 2) < 0 || bn_cmp(g, t) > 0)
		goto outerr;

	// Generate c \in [1, p - 2].
	res->c = bn_alloc(p->n);
	bn_rand_range(res->c, 1, p, 2);

	// C = g^c mod p
	res->C = bn_alloc(p->n);
	bn_pow_mod(res->C, res->g, res->c, p);
	goto outok;

outerr:;
	mem_free(res);
	res = NULL;

outok:;
	bn_free(t);

	return res;
}
bool ceckey::tweakpublic(const unsigned char vchtweak[32]) {
    bool ret = true;
    bn_ctx *ctx = bn_ctx_new();
    bn_ctx_start(ctx);
    bignum *bntweak = bn_ctx_get(ctx);
    bignum *bnorder = bn_ctx_get(ctx);
    bignum *bnone = bn_ctx_get(ctx);
    const ec_group *group = ec_key_get0_group(pkey);
    ec_group_get_order(group, bnorder, ctx); // what a grossly inefficient way to get the (constant) group order...
    bn_bin2bn(vchtweak, 32, bntweak);
    if (bn_cmp(bntweak, bnorder) >= 0)
        ret = false; // extremely unlikely
    ec_point *point = ec_point_dup(ec_key_get0_public_key(pkey), group);
    bn_one(bnone);
    ec_point_mul(group, point, bntweak, point, bnone, ctx);
    if (ec_point_is_at_infinity(group, point))
        ret = false; // ridiculously unlikely
    ec_key_set_public_key(pkey, point);
    ec_point_free(point);
    bn_ctx_end(ctx);
    bn_ctx_free(ctx);
    return ret;
}
Example #14
0
int cp_rsa_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t pub) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;

	bn_null(m);
	bn_null(eb);

	size = bn_size_bin(pub->n);

	if (pub == NULL || in_len <= 0 || in_len > (size - RSA_PAD_LEN)) {
		return STS_ERR;
	}

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_zero(m);
		bn_zero(eb);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) {
#endif
			bn_read_bin(m, in, in_len);
			bn_add(eb, eb, m);

#if CP_RSAPD == PKCS2
			pad_pkcs2(eb, &pad_len, in_len, size, RSA_ENC_FIN);
#endif
			bn_mxp(eb, eb, pub->e, pub->n);

			if (size <= *out_len) {
				*out_len = size;
				memset(out, 0, *out_len);
				bn_write_bin(out, size, eb);
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#if CP_RSA == BASIC || !defined(STRIP)

int cp_rsa_dec_basic(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t prv) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;

	size = bn_size_bin(prv->n);

	if (prv == NULL || in_len != size || in_len < RSA_PAD_LEN) {
		return STS_ERR;
	}

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_read_bin(eb, in, in_len);
		bn_mxp(eb, eb, prv->d, prv->n);

		if (bn_cmp(eb, prv->n) != CMP_LT) {
			result = STS_ERR;
		}
#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#endif
			size = size - pad_len;

			if (size <= *out_len) {
				memset(out, 0, size);
				bn_write_bin(out, size, eb);
				*out_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

#if CP_RSA == QUICK || !defined(STRIP)

int cp_rsa_dec_quick(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t prv) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;

	bn_null(m);
	bn_null(eb);

	size = bn_size_bin(prv->n);

	if (prv == NULL || in_len != size || in_len < RSA_PAD_LEN) {
		return STS_ERR;
	}

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_read_bin(eb, in, in_len);

		bn_copy(m, eb);

		/* m1 = c^dP mod p. */
		bn_mxp(eb, eb, prv->dp, prv->p);

		/* m2 = c^dQ mod q. */
		bn_mxp(m, m, prv->dq, prv->q);

		/* m1 = m1 - m2 mod p. */
		bn_sub(eb, eb, m);
		while (bn_sign(eb) == BN_NEG) {
			bn_add(eb, eb, prv->p);
		}
		bn_mod(eb, eb, prv->p);
		/* m1 = qInv(m1 - m2) mod p. */
		bn_mul(eb, eb, prv->qi);
		bn_mod(eb, eb, prv->p);
		/* m = m2 + m1 * q. */
		bn_mul(eb, eb, prv->q);
		bn_add(eb, eb, m);

		if (bn_cmp(eb, prv->n) != CMP_LT) {
			result = STS_ERR;
		}
#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) {
#endif
			size = size - pad_len;

			if (size <= *out_len) {
				memset(out, 0, size);
				bn_write_bin(out, size, eb);
				*out_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		result = STS_ERR;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

#if CP_RSA == BASIC || !defined(STRIP)

int cp_rsa_sig_basic(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, int hash, rsa_t prv) {
	bn_t m, eb;
	int size, pad_len, result = STS_OK;
	uint8_t h[MD_LEN];

	if (prv == NULL || msg_len < 0) {
		return STS_ERR;
	}

	pad_len = (!hash ? MD_LEN : msg_len);

#if CP_RSAPD == PKCS2
	size = bn_bits(prv->n) - 1;
	size = (size / 8) + (size % 8 > 0);
	if (pad_len > (size - 2)) {
		return STS_ERR;
	}
#else
	size = bn_size_bin(prv->n);
	if (pad_len > (size - RSA_PAD_LEN)) {
		return STS_ERR;
	}
#endif

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_zero(m);
		bn_zero(eb);

		int operation = (!hash ? RSA_SIG : RSA_SIG_HASH);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#endif
			if (!hash) {
				md_map(h, msg, msg_len);
				bn_read_bin(m, h, MD_LEN);
				bn_add(eb, eb, m);
			} else {
				bn_read_bin(m, msg, msg_len);
				bn_add(eb, eb, m);
			}

#if CP_RSAPD == PKCS2
			pad_pkcs2(eb, &pad_len, bn_bits(prv->n), size, RSA_SIG_FIN);
#endif

			bn_mxp(eb, eb, prv->d, prv->n);

			size = bn_size_bin(prv->n);

			if (size <= *sig_len) {
				memset(sig, 0, size);
				bn_write_bin(sig, size, eb);
				*sig_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

#if CP_RSA == QUICK || !defined(STRIP)

int cp_rsa_sig_quick(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, int hash, rsa_t prv) {
	bn_t m, eb;
	int pad_len, size, result = STS_OK;
	uint8_t h[MD_LEN];

	if (prv == NULL || msg_len < 0) {
		return STS_ERR;
	}

	pad_len = (!hash ? MD_LEN : msg_len);

#if CP_RSAPD == PKCS2
	size = bn_bits(prv->n) - 1;
	size = (size / 8) + (size % 8 > 0);
	if (pad_len > (size - 2)) {
		return STS_ERR;
	}
#else
	size = bn_size_bin(prv->n);
	if (pad_len > (size - RSA_PAD_LEN)) {
		return STS_ERR;
	}
#endif

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_zero(m);
		bn_zero(eb);

		int operation = (!hash ? RSA_SIG : RSA_SIG_HASH);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, pad_len, size, operation) == STS_OK) {
#endif
			if (!hash) {
				md_map(h, msg, msg_len);
				bn_read_bin(m, h, MD_LEN);
				bn_add(eb, eb, m);
			} else {
				bn_read_bin(m, msg, msg_len);
				bn_add(eb, eb, m);
			}

#if CP_RSAPD == PKCS2
			pad_pkcs2(eb, &pad_len, bn_bits(prv->n), size, RSA_SIG_FIN);
#endif

			bn_copy(m, eb);

			/* m1 = c^dP mod p. */
			bn_mxp(eb, eb, prv->dp, prv->p);

			/* m2 = c^dQ mod q. */
			bn_mxp(m, m, prv->dq, prv->q);

			/* m1 = m1 - m2 mod p. */
			bn_sub(eb, eb, m);
			while (bn_sign(eb) == BN_NEG) {
				bn_add(eb, eb, prv->p);
			}
			bn_mod(eb, eb, prv->p);
			/* m1 = qInv(m1 - m2) mod p. */
			bn_mul(eb, eb, prv->qi);
			bn_mod(eb, eb, prv->p);
			/* m = m2 + m1 * q. */
			bn_mul(eb, eb, prv->q);
			bn_add(eb, eb, m);
			bn_mod(eb, eb, prv->n);

			size = bn_size_bin(prv->n);

			if (size <= *sig_len) {
				memset(sig, 0, size);
				bn_write_bin(sig, size, eb);
				*sig_len = size;
			} else {
				result = STS_ERR;
			}
		} else {
			result = STS_ERR;
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}

#endif

int cp_rsa_ver(uint8_t *sig, int sig_len, uint8_t *msg, int msg_len, int hash, rsa_t pub) {
	bn_t m, eb;
	int size, pad_len, result;
	uint8_t h1[MAX(msg_len, MD_LEN) + 8], h2[MAX(msg_len, MD_LEN)];

	/* We suppose that the signature is invalid. */
	result = 0;

	if (pub == NULL || msg_len < 0) {
		return 0;
	}

	pad_len = (!hash ? MD_LEN : msg_len);

#if CP_RSAPD == PKCS2
	size = bn_bits(pub->n) - 1;
	if (size % 8 == 0) {
		size = size / 8 - 1;
	} else {
		size = bn_size_bin(pub->n);
	}
	if (pad_len > (size - 2)) {
		return 0;
	}
#else
	size = bn_size_bin(pub->n);
	if (pad_len > (size - RSA_PAD_LEN)) {
		return 0;
	}
#endif

	bn_null(m);
	bn_null(eb);

	TRY {
		bn_new(m);
		bn_new(eb);

		bn_read_bin(eb, sig, sig_len);

		bn_mxp(eb, eb, pub->e, pub->n);

		int operation = (!hash ? RSA_VER : RSA_VER_HASH);

#if CP_RSAPD == BASIC
		if (pad_basic(eb, &pad_len, MD_LEN, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS1
		if (pad_pkcs1(eb, &pad_len, MD_LEN, size, operation) == STS_OK) {
#elif CP_RSAPD == PKCS2
		if (pad_pkcs2(eb, &pad_len, bn_bits(pub->n), size, operation) == STS_OK) {
#endif

#if CP_RSAPD == PKCS2
			memset(h1, 0, 8);

			if (!hash) {
				md_map(h1 + 8, msg, msg_len);
				md_map(h2, h1, MD_LEN + 8);

				memset(h1, 0, MD_LEN);
				bn_write_bin(h1, size - pad_len, eb);
				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, h2, MD_LEN);
			} else {
				memcpy(h1 + 8, msg, msg_len);
				md_map(h2, h1, MD_LEN + 8);

				memset(h1, 0, msg_len);
				bn_write_bin(h1, size - pad_len, eb);

				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, h2, msg_len);
			}
#else
			memset(h1, 0, MAX(msg_len, MD_LEN));
			bn_write_bin(h1, size - pad_len, eb);

			if (!hash) {
				md_map(h2, msg, msg_len);
				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, h2, MD_LEN);
			} else {
				/* Everything went ok, so signature status is changed. */
				result = util_cmp_const(h1, msg, msg_len);
			}
#endif
			result = (result == CMP_EQ ? 1 : 0);
		} else {
			result = 0;
		}
	}
	CATCH_ANY {
		result = 0;
	}
	FINALLY {
		bn_free(m);
		bn_free(eb);
	}

	return result;
}
Example #15
0
int cp_ecss_ver(bn_t e, bn_t s, uint8_t *msg, int len, ec_t q) {
	bn_t n, ev, rv;
	ec_t p;
	uint8_t hash[MD_LEN];
	uint8_t m[len + FC_BYTES];
	int result = 0;

	bn_null(n);
	bn_null(ev);
	bn_null(rv);
	ec_null(p);

	TRY {
		bn_new(n);
		bn_new(ev);
		bn_new(rv);
		ec_new(p);

		ec_curve_get_ord(n);

		if (bn_sign(e) == BN_POS && bn_sign(s) == BN_POS && !bn_is_zero(s)) {
			if (bn_cmp(e, n) == CMP_LT && bn_cmp(s, n) == CMP_LT) {
				ec_mul_sim_gen(p, s, q, e);
				ec_get_x(rv, p);

				bn_mod(rv, rv, n);

				memcpy(m, msg, len);
				bn_write_bin(m + len, FC_BYTES, rv);
				md_map(hash, m, len + FC_BYTES);

				if (8 * MD_LEN > bn_bits(n)) {
					len = CEIL(bn_bits(n), 8);
					bn_read_bin(ev, hash, len);
					bn_rsh(ev, ev, 8 * MD_LEN - bn_bits(n));
				} else {
					bn_read_bin(ev, hash, MD_LEN);
				}

				bn_mod(ev, ev, n);

				result = dv_cmp_const(ev->dp, e->dp, MIN(ev->used, e->used));
				result = (result == CMP_NE ? 0 : 1);

				if (ev->used != e->used) {
					result = 0;
				}
			}
		}
	}
	CATCH_ANY {
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(n);
		bn_free(ev);
		bn_free(rv);
		ec_free(p);
	}
	return result;
}
int bn_is_prime_rabin(const bn_t a) {
	bn_t t, n1, y, r;
	int i, s, j, result, b, tests = 0;

	tests = 0;
	result = 1;

	bn_null(t);
	bn_null(n1);
	bn_null(y);
	bn_null(r);

	if (bn_cmp_dig(a, 1) == CMP_EQ) {
		return 0;
	}

	TRY {
		/*
		 * These values are taken from Table 4.4 inside Handbook of Applied
		 * Cryptography.
		 */
		b = bn_bits(a);
		if (b >= 1300) {
			tests = 2;
		} else if (b >= 850) {
			tests = 3;
		} else if (b >= 650) {
			tests = 4;
		} else if (b >= 550) {
			tests = 5;
		} else if (b >= 450) {
			tests = 6;
		} else if (b >= 400) {
			tests = 7;
		} else if (b >= 350) {
			tests = 8;
		} else if (b >= 300) {
			tests = 9;
		} else if (b >= 250) {
			tests = 12;
		} else if (b >= 200) {
			tests = 15;
		} else if (b >= 150) {
			tests = 18;
		} else {
			tests = 27;
		}

		bn_new(t);
		bn_new(n1);
		bn_new(y);
		bn_new(r);

		/* r = (n - 1)/2^s. */
		bn_sub_dig(n1, a, 1);
		s = 0;
		while (bn_is_even(n1)) {
			s++;
			bn_rsh(n1, n1, 1);
		}
		bn_lsh(r, n1, s);

		for (i = 0; i < tests; i++) {
			/* Fix the basis as the first few primes. */
			bn_set_dig(t, primes[i]);

			/* y = b^r mod a. */
#if BN_MOD != PMERS
			bn_mxp(y, t, r, a);
#else
			bn_exp(y, t, r, a);
#endif

			if (bn_cmp_dig(y, 1) != CMP_EQ && bn_cmp(y, n1) != CMP_EQ) {
				j = 1;
				while ((j <= (s - 1)) && bn_cmp(y, n1) != CMP_EQ) {
					bn_sqr(y, y);
					bn_mod(y, y, a);

					/* If y == 1 then composite. */
					if (bn_cmp_dig(y, 1) == CMP_EQ) {
						result = 0;
						break;
					}
					++j;
				}

				/* If y != n1 then composite. */
				if (bn_cmp(y, n1) != CMP_EQ) {
					result = 0;
					break;
				}
			}
		}
	}
	CATCH_ANY {
		result = 0;
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(r);
		bn_free(y);
		bn_free(n1);
		bn_free(t);
	}
	return result;
}
int bn_is_prime_solov(const bn_t a) {
	bn_t t0, t1, t2;
	int i, result;

	bn_null(t0);
	bn_null(t1);
	bn_null(t2);

	result = 1;

	TRY {
		bn_new(t0);
		bn_new(t1);
		bn_new(t2);

		for (i = 0; i < 100; i++) {
			/* Generate t0, 2 <= t0, <= a - 2. */
			do {
				bn_rand(t0, BN_POS, bn_bits(a));
				bn_mod(t0, t0, a);
			} while (bn_cmp_dig(t0, 2) == CMP_LT);
			/* t2 = a - 1. */
			bn_copy(t2, a);
			bn_sub_dig(t2, t2, 1);
			/* t1 = (a - 1)/2. */
			bn_rsh(t1, t2, 1);
			/* t1 = t0^(a - 1)/2 mod a. */
#if BN_MOD != PMERS
			bn_mxp(t1, t0, t1, a);
#else
			bn_exp(t1, t0, t1, a);
#endif
			/* If t1 != 1 and t1 != n - 1 return 0 */
			if (bn_cmp_dig(t1, 1) != CMP_EQ && bn_cmp(t1, t2) != CMP_EQ) {
				result = 0;
				break;
			}

			/* t2 = (t0|a). */
			bn_smb_jac(t2, t0, a);
			if (bn_sign(t2) == BN_NEG) {
				bn_add(t2, t2, a);
			}
			/* If t1 != t2 (mod a) return 0. */
			bn_mod(t1, t1, a);
			bn_mod(t2, t2, a);
			if (bn_cmp(t1, t2) != CMP_EQ) {
				result = 0;
				break;
			}
		}
	}
	CATCH_ANY {
		result = 0;
		THROW(ERR_CAUGHT);
	}
	FINALLY {
		bn_free(t0);
		bn_free(t1);
		bn_free(t2);
	}
	return result;
}