示例#1
0
/*------------------------------------------------------------
 *
 *  mpa_exp_mod
 *
 *  Calculates dest = op1 ^ op2 mod n
 *
 */
void mpa_exp_mod(mpanum dest,
		const mpanum op1,
		const mpanum op2,
		const mpanum n,
		const mpanum r_modn,
		const mpanum r2_modn,
		const mpa_word_t n_inv, mpa_scratch_mem pool)
{
	mpanum A;
	mpanum B;
	mpanum xtilde;
	mpanum *ptr_a;
	mpanum *ptr_b;
	mpanum *swapper;
	int idx;

	mpa_alloc_static_temp_var(&A, pool);
	mpa_alloc_static_temp_var(&B, pool);
	mpa_alloc_static_temp_var(&xtilde, pool);

	/* transform to Montgomery space */
	/* use internal version since xtidle is big enough */
	__mpa_montgomery_mul(xtilde, op1, r2_modn, n, n_inv);

	mpa_copy(A, r_modn);
	ptr_a = &A;
	ptr_b = &B;
	__mpa_set_unused_digits_to_zero(A);
	__mpa_set_unused_digits_to_zero(B);
	for (idx = mpa_highest_bit_index(op2); idx >= 0; idx--) {
		__mpa_montgomery_mul(*ptr_b, *ptr_a, *ptr_a, n, n_inv);
		if (mpa_get_bit(op2, idx) == 1) {
			__mpa_montgomery_mul(*ptr_a, *ptr_b, xtilde, n, n_inv);
		} else {
			swapper = ptr_a;
			ptr_a = ptr_b;
			ptr_b = swapper;
		}
	}

	/* transform back form Montgomery space */
	__mpa_montgomery_mul(*ptr_b, (const mpanum)&const_one, *ptr_a,
			     n, n_inv);

	mpa_copy(dest, *ptr_b);

	mpa_free_static_temp_var(&A, pool);
	mpa_free_static_temp_var(&B, pool);
	mpa_free_static_temp_var(&xtilde, pool);
}
/*
 * TEE_BigIntConvertFromFMM
 */
void TEE_BigIntConvertFromFMM(TEE_BigInt *dest,
			      const TEE_BigIntFMM *src,
			      const TEE_BigInt *n,
			      const TEE_BigIntFMMContext *context)
{
	mpanum mpa_dest = (mpa_num_base *)dest;
	mpanum mpa_op2 = (mpa_num_base *)src;
	mpanum mpa_n = (mpa_num_base *)n;
	mpa_fmm_context mpa_context = (mpa_fmm_context_base *)context;
	mpanum temp_dest;

	/*
	 * Since dest in BigIntFFMCompute (i.e. dest in mpa_montgomery_mul)
	 * must have alloc one word more than the size of n, we must
	 * use a temp variable during the conversion.
	 */
	mpa_alloc_static_temp_var(&temp_dest, mempool);

	/* calculate dest = Mont(1,src) */
	mpa_montgomery_mul(temp_dest, mpa_constant_one(), mpa_op2, mpa_n,
			   mpa_context->n_inv, mempool);

	mpa_copy(mpa_dest, temp_dest);
	mpa_free_static_temp_var(&temp_dest, mempool);
}
/*
 *  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);
}
示例#4
0
/*------------------------------------------------------------
 *
 *  mpa_mul_mod
 *
 */
void mpa_mul_mod(mpanum dest,
		const mpanum op1,
		const mpanum op2, const mpanum n, mpa_scratch_mem pool)
{
	mpanum tmp_dest;

	mpa_alloc_static_temp_var(&tmp_dest, pool);

	mpa_mul(tmp_dest, op1, op2, pool);
	mpa_div(NULL, dest, tmp_dest, n, pool);

	mpa_free_static_temp_var(&tmp_dest, pool);
}
示例#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;
}
示例#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;
	}
}
/*
 * 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;
}
示例#8
0
static void deinit(void *a)
{
	LTC_ARGCHKVD(a != NULL);

	mpa_free_static_temp_var((mpanum *) &a, external_mem_pool);
}
示例#9
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;
}
示例#10
0
static void deinit(void *a)
{
	LTC_ARGCHKVD(a != NULL);

	mpa_free_static_temp_var((mpanum *) &a, NULL);
}