Exemplo n.º 1
0
/*------------------------------------------------------------
 *
 *  is_small_prime
 *
 *  Returns 1 if n is prime,
    Returns 0 if n is composite
 *  Returns -1 if we cannot decide
 *
 */
static int is_small_prime(mpanum n)
{
	mpa_word_t v;

	/* If n is larger than a mpa_word_t, we can only decide if */
	/* n is even. If it's odd we cannot tell. */
	if (__mpanum_size(n) > 1)
		return ((mpa_parity(n) == MPA_EVEN_PARITY) ? 0 : -1);

	v = mpa_get_word(n);	/* will convert negative n:s to positive v:s. */
	if ((v | 1) == 1)	/* 0 and 1 are not prime */
		return DEF_COMPOSITE;
	if (v == 2)		/* 2 is prime */
		return DEF_PRIME;
	if ((v & 1) == 0)
		return DEF_COMPOSITE;	/* but no other even number */

#if defined(USE_PRIME_TABLE)
	if (mpa_cmp_short(n, MAX_TABULATED_PRIME) > 0)
		return -1;
	v = (v - 3) >> 1;
	return check_table(v);
#else
	return -1;
#endif
}
Exemplo n.º 2
0
/*
 *  TEE_BigIntMulMod
 */
void TEE_BigIntMulMod(TEE_BigInt *dest, const TEE_BigInt *op1,
		      const TEE_BigInt *op2, const TEE_BigInt *n)
{
	mpanum mpa_dest = (mpa_num_base *)dest;
	mpanum mpa_op1 = (mpa_num_base *)op1;
	mpanum mpa_op2 = (mpa_num_base *)op2;
	mpanum mpa_n = (mpa_num_base *)n;
	mpanum tmp_dest;

	if (TEE_BigIntCmpS32(n, 2) < 0)
		TEE_BigInt_Panic("Modulus is too short");

	/*
	 * From the spec, mpa_dest must be of magnitude "mpa_n"
	 * But internal computations in mpa do not have such assumptions
	 * (as __mpa_div_q_r, where "r" must be of magnitude "op1",
	 * whereas GP provides a magnitude of "op2")
	 * This is a tempory variable is used, before storing the
	 * final result.
	 */
	mpa_alloc_static_temp_var(&tmp_dest, mempool);
	mpa_mul_mod(tmp_dest, mpa_op1, mpa_op2, mpa_n, mempool);
	if (mpa_cmp_short(tmp_dest, 0) < 0)
		mpa_add(tmp_dest, tmp_dest, mpa_n, mempool);
	mpa_copy(mpa_dest, tmp_dest);
	mpa_free_static_temp_var(&tmp_dest, mempool);
}
Exemplo n.º 3
0
/* get size as unsigned char string */
static unsigned long unsigned_size(void *a)
{
	unsigned long t;
	LTC_ARGCHK(a != NULL);
	t = count_bits(a);
	if (mpa_cmp_short((const mpanum)a, 0) == 0) return 0;
	return (t>>3) + ((t&7)?1:0);
}
Exemplo n.º 4
0
static int mod(void *a, void *b, void *c)
{
	LTC_ARGCHK(a != NULL);
	LTC_ARGCHK(b != NULL);
	LTC_ARGCHK(c != NULL);
	mpa_mod((mpanum) c, (const mpanum) a, (const mpanum) b, external_mem_pool);
	if (mpa_cmp_short(c, 0) < 0) {
		mpa_add(c, c, b, external_mem_pool);
	}
	return CRYPT_OK;
}
Exemplo n.º 5
0
/*------------------------------------------------------------
 *
 *  has_small_factors
 *
 *  returns 1 if n has small factors
 *  returns 0 if not.
 */
static int has_small_factors(mpanum n, mpa_scratch_mem pool)
{
	const mpa_num_base *factors = &const_small_prime_factors;
	int result;
	mpanum res;

	mpa_alloc_static_temp_var(&res, pool);
	mpa_gcd(res, n, (const mpanum)factors, pool);
	result = (mpa_cmp_short(res, 1) == 0) ? 0 : 1;
	mpa_free_static_temp_var(&res, pool);

	return result;
}
Exemplo n.º 6
0
/*------------------------------------------------------------
 *
 *  mpa_inv_mod
 *
 */
int mpa_inv_mod(mpanum dest,
	       const mpanum op, const mpanum n, mpa_scratch_mem pool)
{
	mpanum gcd;
	mpanum tmp_dest;
	int mem_marker;
	int res;

	if (mpa_cmp_short(op, 1) == 0) {
		mpa_set_S32(dest, 1);
		return 0;
	}

	mem_marker = (dest == op);
	if (mem_marker)
		mpa_alloc_static_temp_var(&tmp_dest, pool);
	else
		tmp_dest = dest;

	mpa_alloc_static_temp_var(&gcd, pool);
	/* The function mpa_extended_gcd behaves badly if tmp_dest = op */
	mpa_extended_gcd(gcd, tmp_dest, NULL, op, n, pool);
	res = mpa_cmp_short(gcd, 1);

	if (mem_marker) {
		mpa_copy(dest, tmp_dest);
		mpa_free_static_temp_var(&tmp_dest, pool);
	}

	mpa_free_static_temp_var(&gcd, pool);
	if (res == 0) {
		while (mpa_cmp_short(dest, 0) < 0)
			mpa_add(dest, dest, n, pool);
		return 0;
	} else {
		return -1;
	}
}
Exemplo n.º 7
0
/*
 * TEE_BigIntSubMod
 */
void TEE_BigIntSubMod(TEE_BigInt *dest, const TEE_BigInt *op1,
		      const TEE_BigInt *op2, const TEE_BigInt *n)
{
	mpanum mpa_dest = (mpa_num_base *)dest;
	mpanum mpa_op1 = (mpa_num_base *)op1;
	mpanum mpa_op2 = (mpa_num_base *)op2;
	mpanum mpa_n = (mpa_num_base *)n;

	if (TEE_BigIntCmpS32(n, 2) < 0)
		TEE_BigInt_Panic("Modulus is too short");

	mpa_sub_mod(mpa_dest, mpa_op1, mpa_op2, mpa_n, mempool);
	if (mpa_cmp_short(mpa_dest, 0) < 0)
		mpa_add(mpa_dest, mpa_dest, mpa_n, mempool);
}
Exemplo n.º 8
0
/*
 * TEE_BigIntRelativePrime
 */
bool TEE_BigIntRelativePrime(const TEE_BigInt *op1, const TEE_BigInt *op2)
{
	mpanum mpa_op1 = (mpa_num_base *)op1;
	mpanum mpa_op2 = (mpa_num_base *)op2;
	mpanum gcd;
	uint32_t cmp;

	mpa_alloc_static_temp_var(&gcd, mempool);

	mpa_gcd(gcd, mpa_op1, mpa_op2, mempool);
	cmp = mpa_cmp_short(gcd, 1);

	mpa_free_static_temp_var(&gcd, mempool);

	return cmp == 0 ? true : false;
}
Exemplo n.º 9
0
static int compare_d(void *a, unsigned long b)
{
	int ret;
	LTC_ARGCHK(a != NULL);
	// this particular case must be handled separately...
	if (b > (unsigned long) MPA_INT_MAX) {
		mpanum tmp = (mpanum) a;
		ret = (tmp->size <= 0 ? LTC_MP_LT :
				tmp->size > 1  ? LTC_MP_GT :
						tmp->d[0] < b  ? LTC_MP_LT :
								tmp->d[0] == b ? LTC_MP_EQ : LTC_MP_GT);
	} else {
		ret = mpa_cmp_short(((const mpanum)a), b);
	}
	if (ret < 0) {
		return LTC_MP_LT;
	} else if (ret > 0) {
		return LTC_MP_GT;
	} else {
		return LTC_MP_EQ;
	}
}
Exemplo n.º 10
0
/*
 * TEE_BigIntCmpS32
 */
int32_t TEE_BigIntCmpS32(const TEE_BigInt *op, int32_t shortVal)
{
	mpanum mpa_op = (mpa_num_base *)op;

	return mpa_cmp_short(mpa_op, shortVal);
}
Exemplo n.º 11
0
/*------------------------------------------------------------
 *
 *  primality_test_miller_rabin
 *
 */
static int primality_test_miller_rabin(mpanum n, int conf_level,
				      mpa_scratch_mem pool)
{
	int result;
	bool proof_version;
	static const int32_t proof_a[7] = { 2, 3, 5, 7, 11, 13, 17 };
	int cnt;
	int idx;
	int t;
	int e = 0;
	int cmp_one;
	mpanum a;
	mpanum q;
	mpanum n_minus_1;
	mpanum b;
	mpanum r_modn;
	mpanum r2_modn;
	mpa_word_t n_inv;

	mpa_alloc_static_temp_var(&r_modn, pool);
	mpa_alloc_static_temp_var(&r2_modn, pool);

	if (mpa_compute_fmm_context(n, r_modn, r2_modn, &n_inv, pool) == -1) {
		result = DEF_COMPOSITE;
		goto cleanup_short;
	}

	mpa_alloc_static_temp_var(&a, pool);
	mpa_alloc_static_temp_var(&q, pool);
	mpa_alloc_static_temp_var(&n_minus_1, pool);
	mpa_alloc_static_temp_var(&b, pool);

	proof_version =
	    (mpa_cmp(n, (mpanum) &const_miller_rabin_proof_limit) < 0);

	if (proof_version)
		cnt = 7;
	else	/* MR has 1/4 chance in failing a composite */
		cnt = (conf_level + 1) / 2;

	mpa_sub_word(n_minus_1, n, 1, pool);
	mpa_set(q, n_minus_1);
	t = 0;
	/* calculate q such that n - 1 = 2^t * q where q is odd */
	while (mpa_is_even(q)) {
		mpa_shift_right(q, q, 1);
		t++;
	}

	result = PROB_PRIME;
	for (idx = 0; idx < cnt && result == PROB_PRIME; idx++) {
		if (proof_version) {
			mpa_set_S32(a, proof_a[idx]);
			if (mpa_cmp(n, a) == 0) {
				result = DEF_PRIME;
				continue;
			}
		} else {
			/*
			 * Get random a, 1 < a < N by
			 * asking for a random in range 0 <= x < N - 2
			 * and then add 2 to it.
			 */
			mpa_sub_word(n_minus_1, n_minus_1, 1, pool);
			/* n_minus_1 is now N - 2 ! */
			mpa_get_random(a, n_minus_1);
			mpa_add_word(n_minus_1, n_minus_1, 1, pool);
			/* and a is now 2 <= a < N */
			mpa_add_word(a, a, 2, pool);
		}

		mpa_exp_mod(b, a, q, n, r_modn, r2_modn, n_inv, pool);
		e = 0;

inner_loop:
		cmp_one = mpa_cmp_short(b, 1);
		if ((cmp_one == 0) && (e > 0)) {
			result = DEF_COMPOSITE;
			continue;
		}

		if ((mpa_cmp(b, n_minus_1) == 0) ||
		    ((cmp_one == 0) && (e == 0))) {
			/* probably prime, try another a */
			continue;
		}

		e++;
		if (e < t) {
			mpa_exp_mod(b, b, (mpanum) &const_two, n, r_modn,
				    r2_modn, n_inv, pool);
			goto inner_loop;
		}
		result = DEF_COMPOSITE;
	}

	if (result == PROB_PRIME && proof_version)
		result = DEF_PRIME;

	mpa_free_static_temp_var(&a, pool);
	mpa_free_static_temp_var(&q, pool);
	mpa_free_static_temp_var(&n_minus_1, pool);
	mpa_free_static_temp_var(&b, pool);
cleanup_short:
	mpa_free_static_temp_var(&r_modn, pool);
	mpa_free_static_temp_var(&r2_modn, pool);

	return result;
}