Example #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++;
	}
}
Example #2
0
int mpa_set_oct_str(mpanum dest, const uint8_t *buffer, size_t buffer_len,
		  bool negative)
{
	const uint8_t *buf = buffer;
	int bufidx = buffer_len;
	mpa_word_t *w;

	/* Strip of leading zero octets */
	while (bufidx > 0) {
		if (*buf != 0)
			break;
		bufidx--;
		buf++;
	}

	if (bufidx == 0) {
		mpa_set_word(dest, 0);
		return 0;
	}

	/*
	 * bufidx is now indexing one byte past past the last byte in the octet
	 * string relative to buf.
	 */

	if ((size_t) (bufidx - 1) > (BYTES_PER_WORD * __mpanum_alloced(dest)))
		return -1;	/* No space */

	w = dest->d;
	mpa_set_word(dest, 0);
	/* start converting */
	dest->size = 0;
	while (bufidx > 0) {
		int l = __MIN(BYTES_PER_WORD, bufidx);

		bufidx -= l;
		*w = set_word(buf + bufidx, l);
		w++;
		dest->size++;
	}

	if (negative)
		__mpanum_neg(dest);

	return 0;
}
Example #3
0
/* ---- trivial ---- */
static int set_int(void *a, unsigned long b)
{
	LTC_ARGCHK(a != NULL);
	if (b > (unsigned long) UINT32_MAX) {
		return CRYPT_INVALID_ARG;
	}
	mpa_set_word((mpanum) a, (mpa_word_t)b);
	return CRYPT_OK;
}
Example #4
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;
}
Example #5
0
/*  --------------------------------------------------------------------
 *  Function:   mpa_set_str
 *
 *  Assigns dest the value of the digitstr, where digitstr is a character
 *  string.
 *  If the digitstr starts with a valid number, the valid part will be
 *  converted and the rest of the digitstr will not be parsed further.
 *  digitstr is assumed to be in base 16.
 *  Returns -1 if the digitstr was malformed, and the number of base digits
 *  converted (not including leading zeros) if the conversion was OK.
 *  If the digitstr is a null-ptr we return -1.
 *  If the digitstr is empty, we don't touch dest and just returns 0.
 *  If the digitstr only consists of white spaces, we set dest to zero
 *  returns 0.
 */
int mpa_set_str(mpanum dest, const char *digitstr)
{
	/* length of digitstr after removal of base indicator and spaces */
	int dlen;
	int negative;		/* ==1 if number is negative, 0 otherwise */
	int c;			/* value of characters in digitstr */
	/* a buffer holding the integer values of the digits */
	static unsigned char buf[MPA_STR_MAX_SIZE];
	/* number of digits in digitstr which has been place in buf */
	int bufidx;
	const char *endp;	/* points to the end of digitstr */
	int retval;
	/*
	 * Pointer intto dest->d where we should put the next word during
	 * conversion.
	 */
	mpa_word_t *w;
	int i;			/* loop variable */

	/* some basic sanity checks first */
	if (*digitstr == 0) {
		DPRINT("digitstr was empty, leaving dest unchanged\n");
		return 0;
	}

	/* remove leading spaces */
	do {
		c = (unsigned char)*digitstr++;
	} while (__mpa_isspace(c));

	/* check negative sign */
	negative = 0;
	if (c == '-') {
		negative = 1;
		c = (unsigned char)*digitstr++;
	}
	if (c == '\0') {
		DPRINT("digitstr consisted of only white spaces and possibly a single '-' sign. Setting dest to zero\n");
		mpa_set_word(dest, 0);
		return 0;
	}

	/* see if we have a '0x' prefix */
	if (c == '0') {
		c = (unsigned char)*digitstr++;
		if (c == 'x' || c == 'X')
			c = (unsigned char)*digitstr++;
	}

	/* skip leading zeros and spaces */
	while (c == '0' || __mpa_isspace(c))
		c = (unsigned char)*digitstr++;

	/* check if we had a simple "0" string */
	if (c == '\0') {
		mpa_set_word(dest, 0);
		return 0;
	}

	/* find the end of digitstr */
	endp = digitstr;
	while (*endp != 0)
		endp++;

	/* + 1 since we have one character in 'c' */
	dlen = (int)(endp - digitstr) + 1;
	ASSERT(dlen <= MPA_STR_MAX_SIZE, "String max size is too small");
	/* convert to a buffer of bytes */
	bufidx = 0;
	while (__mpa_is_char_in_base(16, c)) {
		if (!__mpa_isspace(c))
			buf[bufidx++] = __mpa_digit_value(c);
		c = (unsigned char)*digitstr++;
	}

	if (bufidx == 0) {
		retval = -1;
		goto cleanup;
	}

	ASSERT((__mpa_digitstr_to_binary_wsize_base_16(bufidx) <=
		__mpanum_alloced(dest)), "Dest is too small.");

	retval = bufidx;
	w = dest->d;
	mpa_set_word(dest, 0);
	/* start converting */
	*w = 0;
	i = BYTES_PER_WORD;
	dest->size = 1;
	bufidx--;		/* dec to get inside buf range */
	while (bufidx > 1) {
		*w ^=
		    (((buf[bufidx - 1] << 4) ^ (buf[bufidx])) <<
		     ((BYTES_PER_WORD - i) << 3));
		i--;
		bufidx -= 2;
		if (i == 0) {
			w++;
			*w = 0;
			i = BYTES_PER_WORD;
			dest->size++;
		}
	}
	if (bufidx == 1)
		*w ^=
		    (((buf[bufidx - 1] << 4) ^ (buf[bufidx])) <<
		     ((BYTES_PER_WORD - i) << 3));
	if (bufidx == 0)
		*w ^= (buf[bufidx] << ((BYTES_PER_WORD - i) << 3));

	if (negative)
		__mpanum_neg(dest);

cleanup:
	return retval;
}