Пример #1
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++;
	}
}
Пример #2
0
/*  --------------------------------------------------------------------
 *  Function:  __mpa_dbg_dump_mpanum
 *  Prints the internal values of a TEE_BigInt
 *
 */
void __mpa_dbg_dump_mpanum(mpanum a)
{
    int i;

    map_fprintf(logfd, " ---- Dump :\n");
    map_fprintf(logfd, " mpanum->size = %d\n", a->size);
    map_fprintf(logfd, " mpanum->alloc = %u\n", a->alloc);
    map_fprintf(logfd, " mpanum->d (MSW to LSW) :\n");
    for (i = __mpanum_alloced(a) - 1; i >= __mpanum_size(a); i--)
        map_fprintf(logfd, "%.8X ", a->d[i]);
    map_fprintf(logfd, "\n");
    for (i = __mpanum_size(a) - 1; i >= 0; i--)
        map_fprintf(logfd, "[%d] : %.8X\n", i, a->d[i]);
    map_fflush(logfd);
}
Пример #3
0
/*  --------------------------------------------------------------------
 *  Function:   mpa_SizeInBase
 *
 *  Returns the number of characters needed to print |n| in base 255.
 */
static mpa_word_t __mpa_size_in_base_255(const mpanum n)
{
	mpa_word_t totalbits;
	/* number of leading zero bits in the msw of n */
	mpa_word_t zerobits_msw;

	if (__mpanum_is_zero(n))
		return 1;

	zerobits_msw = __mpa_count_leading_zero_bits(
				n->d[__mpanum_size(n) - 1]);
	totalbits = WORD_SIZE * __mpanum_size(n) - zerobits_msw;

	return (totalbits + 7) / 8;
}
Пример #4
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
}
Пример #5
0
/*------------------------------------------------------------
 *
 *  mpa_copy
 *
 *  Copies src to dest.
 *
 *  Doesn't check if src fits into dest
 *
 */
void mpa_copy(mpanum dest, const mpanum src)
{
	if (dest == src)
		return;

	mpa_memcpy(dest->d, src->d, __mpanum_size(src) * BYTES_PER_WORD);
	dest->size = src->size;
}
Пример #6
0
/* get normalization value */
static int montgomery_normalization(void *a, void *b)
{
	LTC_ARGCHK(a != NULL);
	LTC_ARGCHK(b != NULL);
	mpa_asize_t s;
	s = __mpanum_size((mpanum) b);
	twoexpt(a, s * MPA_WORD_SIZE);
	mpa_mod((mpanum) a, (const mpanum) a, (const mpanum) b, external_mem_pool);
	return CRYPT_OK;
}
Пример #7
0
/*  --------------------------------------------------------------------
 *  Function:   __mpa_set_unused_digits_to_zero
 *
 *
 */
void __mpa_set_unused_digits_to_zero(mpanum n)
{
	int i;

	/*
	 * Pointer arithmetics on *mpa_word_t will put the
	 * pointer at the right place.
	 */
	i = __mpanum_size(n);
	mpa_memset((n->d) + i, 0, (n->alloc - i) * BYTES_PER_WORD);
}
Пример #8
0
/*------------------------------------------------------------
 *
 *  __mpa_shift_words_right
 *
 */
void __mpa_shift_words_right(mpanum op, mpa_word_t q)
{
	mpa_word_t i;

	if (q == 0 || __mpanum_is_zero(op))
		return;

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

	for (i = 0; i < __mpanum_size(op) - q; i++)
		op->d[i] = op->d[i + q];

	/* update the size of dest */
	if (op->size > 0)
		op->size -= q;
	else
		op->size += q;
}
Пример #9
0
/*------------------------------------------------------------
 *
 *  mpa_get_bit
 *
 *  Returns the value of the idx:th bit in src.
 *  if idx is larger than the number of bits in src,
 *  it returns zero.
 *
 */
uint32_t mpa_get_bit(const mpanum src, uint32_t idx)
{
	mpa_word_t w;		/* word of bitIndex */
	unsigned long b;	/* bit number in that word */

	w = idx >> LOG_OF_WORD_SIZE;
	b = idx & (WORD_SIZE - 1);

	if (w > __mpanum_size(src))
		return 0;
	b = (1 << b);
	return ((src->d[w] & b) != 0);
}
Пример #10
0
/*  --------------------------------------------------------------------
 *  Function:  mpa_highest_bit_index
 *  Returns the index of the highest 1 in |src|.
 *  The index starts at 0 for the least significant bit.
 *  If src == zero, it will return -1
 *
 */
int mpa_highest_bit_index(const mpanum src)
{
	mpa_word_t w;
	mpa_word_t b;

	if (__mpanum_is_zero(src))
		return -1;

	w = __mpanum_msw(src);

	for (b = 0; b < WORD_SIZE; b++) {
		w >>= 1;
		if (w == 0)
			break;
	}
	return (int)(__mpanum_size(src) - 1) * WORD_SIZE + b;
}
Пример #11
0
/*------------------------------------------------------------
 *
 *  __mpa_shift_words_left
 *
 */
void __mpa_shift_words_left(mpanum op, mpa_word_t q)
{
	mpa_word_t i;

	if (q == 0 || __mpanum_is_zero(op))
		return;
	for (i = __mpanum_size(op) + q - 1; i > q - 1; i--)
		op->d[i] = op->d[i - q];

	mpa_memset(op->d, 0, BYTES_PER_WORD * q);

	/* update the size of op */
	if (op->size > 0)
		op->size += q;
	else
		op->size -= q;
}
Пример #12
0
int mpa_get_oct_str(uint8_t *buffer, size_t *buffer_len, const mpanum n)
{
	size_t req_blen = __mpa_size_in_base_255(n);
	uint8_t first_word[BYTES_PER_WORD];
	size_t bufidx = 0;
	int d_idx;
	int i;

	if (*buffer_len < req_blen) {
		*buffer_len = req_blen;
		return -1;
	}
	/* get high word with data in, watch out for zero case */
	d_idx = __mpanum_size(n);
	if (d_idx == 0) {
		memset(buffer, 0, *buffer_len);
		goto out;
	}
	d_idx--;

	/* Strip of leading zero octets */
	get_word(n->d[d_idx], first_word);

	for (i = 0; i < BYTES_PER_WORD; i++) {
		if (first_word[i] != 0) {
			memcpy(buffer, first_word + i, BYTES_PER_WORD - i);
			bufidx = BYTES_PER_WORD - i;
			break;
		}
	}
	d_idx--;

	while (d_idx >= 0) {
		if (bufidx > req_blen)
			return -1;
		get_word(n->d[d_idx], buffer + bufidx);

		bufidx += BYTES_PER_WORD;
		d_idx--;
	}

out:
	*buffer_len = req_blen;
	return 0;
}
Пример #13
0
/*  --------------------------------------------------------------------
 *  Function:   __mpa_mpanum_to_hexstr
 *
 *   caseing = 1 is lower case, 0 is uppercase
 */
static int __mpa_mpanum_to_hexstr(char *str, int caseing, const mpanum n)
{
	int d_idx;
	char digits[NIBBLES_PER_WORD];
	int i;
	char *cptr;
	int hex_digits;

	/* get high word with data in, watch out for zero case */
	d_idx = __mpanum_size(n);
	if (d_idx == 0) {
		*str++ = '0';
		*str = '\0';
		return 1;
	}
	d_idx--;

	cptr = str;

	/* the msw is special, since if we should not print leading zeros.
	 */
	__mpa_word_to_hexstr(digits, n->d[d_idx], caseing);

	/* find the left-most non-zero digit */
	i = NIBBLES_PER_WORD;
	while (i-- > 0)
		if (digits[i] != '0')
			break;
	while (i >= 0)
		*str++ = digits[i--];

	/* convert each word to a hex string */
	d_idx--;
	while (d_idx >= 0) {
		__mpa_word_to_hexstr(digits, n->d[d_idx], caseing);
		i = NIBBLES_PER_WORD - 1;
		while (i >= 0)
			*str++ = digits[i--];
		d_idx--;
	}
	hex_digits = (int)(str - cptr);
	*str++ = '\0';
	return hex_digits;
}
Пример #14
0
static int get_digit_count(void *a)
{
	LTC_ARGCHK(a != NULL);
	return __mpanum_size((mpanum) a);
}
Пример #15
0
/*------------------------------------------------------------
 *
 *  mpa_CanHold
 *
 *  returns 1 if dest can hold src without overflowing, 0 otherwise
 */
int mpa_can_hold(mpanum dest, const mpanum src)
{
	return (__mpanum_alloced(dest) >= __mpanum_size(src) ? 1 : 0);
}
Пример #16
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;
}