Example #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);
}
Example #2
0
static int copy(void *a, void *b)
{
	LTC_ARGCHK(a != NULL);
	LTC_ARGCHK(b != NULL);
	mpa_copy((mpanum)b, (const mpanum)a);
	return CRYPT_OK;
}
/*
 * 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);
}
Example #5
0
/*------------------------------------------------------------
 *
 *  mpa_shift_right
 *
 *  Shifts src right by "steps" step and put result in dest.
 *  It does not care about signs. Dest will have same sign as src.
 *
 */
void mpa_shift_right(mpanum dest, mpanum src, mpa_word_t steps)
{
	mpa_word_t q;		/* quotient of steps div WORD_SIZE */
	mpa_word_t r;		/* remainder of steps div WORD_SIZE */
	mpa_word_t i;
	/* the bits of the word which will be shifted into another word */
	mpa_word_t rbits;

	/*
	 *  Copy first, then check, since even a shifted zero should
	 *  be copied.
	 */
	mpa_copy(dest, src);
	__mpa_set_unused_digits_to_zero(dest);
	if (steps == 0 || __mpanum_is_zero(dest))
		return;

	r = steps & (WORD_SIZE - 1);	/* 0 <= r < WORD_SIZE */
	q = steps >> LOG_OF_WORD_SIZE;	/* 0 <= q */

	if (q >= __mpanum_size(dest)) {
		mpa_set_word(dest, 0);
		return;
	}

	/*
	 *  Here we have:
	 *      0 <= r < WORD_SIZE - 1
	 *      0 <= q < _mpanumSize(dest)
	 */
	if (r == 0) {		/* and q > 0 */
		/* Simple shift by words */
		for (i = 0; i < __mpanum_size(dest) - q; i++)
			dest->d[i] = dest->d[i + q];
	} else {
		/* combination of word and bit shifting */
		for (i = 0; i < __mpanum_size(dest) - q - 1; i++) {
			dest->d[i] = dest->d[i + q];
			rbits = dest->d[i + q + 1] & ((1 << r) - 1);
			dest->d[i] =
			    (dest->d[i] >> r) ^ (rbits << (WORD_SIZE - r));
		}
		/* final word is special */
		dest->d[i] = dest->d[i + q] >> r;
	}

	/* update the size of dest */
	if (dest->size > 0)
		dest->size -= q;
	else
		dest->size += q;

	/* Take care of the case when we shifted out all bits from MSW */
	if (__mpanum_msw(dest) == 0) {
		if (dest->size > 0)
			dest->size--;
		else
			dest->size++;
	}
}
Example #6
0
/* reduce */
static int montgomery_reduce(void *a, void *b, void *c)
{
	LTC_ARGCHK(a != NULL);
	LTC_ARGCHK(b != NULL);
	LTC_ARGCHK(c != NULL);
	mpanum tmp;
	init((void **)&tmp);
	// WARNING
	//  Workaround for a bug when a > b (a greater than the modulus)
	if (compare(a, b) == LTC_MP_GT) {
		mpa_mod((mpanum) a, (const mpanum) a, (const mpanum) b, external_mem_pool);
	}
	mpa_montgomery_mul(tmp,
			(mpanum) a,
			mpa_constant_one(),
			(mpanum) b,
			((mpa_fmm_context) c)->n_inv,
			external_mem_pool);
	mpa_copy(a, tmp);
	deinit(tmp);
	return CRYPT_OK;
}
Example #7
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;
	}
}
Example #8
0
/*  --------------------------------------------------------------------
 *  Function:  mpa_abs
 *  Computes the absolut value of src and puts it in dest
 *  dest and src can be the same mpanum
 */
void mpa_abs(mpanum dest, const mpanum src)
{
	mpa_copy(dest, src);
	__mpanum_set_sign(dest, MPA_POS_SIGN);
}
Example #9
0
/*  --------------------------------------------------------------------
 *  mpa_shift_left
 *
 *  Shifts src left by "steps" step and put result in dest.
 *  It does not care about signs. Dest will have same sign as src.
 */
void mpa_shift_left(mpanum dest, mpanum src, mpa_word_t steps)
{
	mpa_word_t q;		/* quotient of steps div WORD_SIZE */
	mpa_word_t r;		/* remainder of steps div WORD_SIZE */
	mpa_word_t i;
	/* the bits of the word which will be shifted into another word */
	mpa_word_t rbits;
	mpa_word_t need_extra_word;

	/*
	 *  Copy first, then check, since even a shifted zero should
	 *  be copied.
	 */
	mpa_copy(dest, src);
	__mpa_set_unused_digits_to_zero(dest);
	if (steps == 0 || __mpanum_is_zero(dest))
		return;

	r = steps & (WORD_SIZE - 1);	/* 0 <= r < WORD_SIZE */
	q = steps >> LOG_OF_WORD_SIZE;	/* 0 <= q */

	/*
	 *  The size of dest will always increase by at least q.
	 *  If we're shifting r bits and the r highest bits in
	 *  the MSW of dest is zero, we don't need the extra word
	 *  Note:
	 *  We cannot do
	 *  if (_mpanumMSW(dest) >> (WORD_SIZE - r))
	 *  since some compilers (MS) does not shift the word
	 *  if the shift quantity is larger or equal to the word size...
	 *  Otherwise it would be natural to say that (a >> b) is just zero
	 *  if b is larger than the number of bit of a, but no no...
	 */
	need_extra_word = 0;
	if (__mpanum_msw(dest) & (((1 << r) - 1) << (WORD_SIZE - r)))
		need_extra_word = 1;

	if (r == 0) {		/* and q > 0 */
		/*
		 *  We have a simple shift by words
		 */
		for (i = __mpanum_size(dest) + q - 1; i > q - 1; i--)
			dest->d[i] = dest->d[i - q];
	} else {
		/*
		 * We have a combination of word and bit shifting.
		 *
		 * If need_extra_word is 1, the MSW is special and handled
		 * here
		 */
		i = __mpanum_size(dest) + q + need_extra_word;
		if (need_extra_word) {
			rbits = dest->d[i - q - 1] >> (WORD_SIZE - r);
			dest->d[i] ^= rbits;
		}
		i--;
		dest->d[i] = dest->d[i - q] << r;
		while (i > q) {
			rbits = dest->d[i - q - 1] >> (WORD_SIZE - r);
			dest->d[i] ^= rbits;
			i--;
			dest->d[i] = dest->d[i - q] << r;
		}
	}
	mpa_memset(dest->d, 0, BYTES_PER_WORD * q);
	/* update the size of dest */
	if (dest->size > 0)
		dest->size += q + need_extra_word;
	else
		dest->size -= q + need_extra_word;
}