/*
 * Copyright (C) 2017 Denys Vlasenko
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */
#include "tls.h"

/* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/.
 * Changes are flagged with //bbox
 */

/**
 *	@file    pstm.c
 *	@version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master)
 *
 *	Multiprecision number implementation.
 */
/*
 *	Copyright (c) 2013-2015 INSIDE Secure Corporation
 *	Copyright (c) PeerSec Networks, 2002-2011
 *	All Rights Reserved
 *
 *	The latest version of this code is available at http://www.matrixssl.org
 *
 *	This software is open source; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	This General Public License does NOT permit incorporating this software
 *	into proprietary programs.  If you are unable to comply with the GPL, a
 *	commercial license for this software may be purchased from INSIDE at
 *	http://www.insidesecure.com/eng/Company/Locations
 *
 *	This program is distributed in WITHOUT ANY WARRANTY; without even the
 *	implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *	See the GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *	http://www.gnu.org/copyleft/gpl.html
 */
/******************************************************************************/

//bbox
//#include "../cryptoApi.h"
#ifndef DISABLE_PSTM

static int32 pstm_mul_2d(pstm_int *a, int b, pstm_int *c); //bbox: was int16 b

/******************************************************************************/
/*
	init an pstm_int for a given size
 */
int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size)
{
//bbox
//	uint16		x;

/*
	alloc mem
 */
	a->dp = xzalloc(sizeof (pstm_digit) * size);//bbox
//bbox	a->pool = pool;
	a->used  = 0;
	a->alloc = size;
	a->sign  = PSTM_ZPOS;
/*
	zero the digits
 */
//bbox
//	for (x = 0; x < size; x++) {
//		a->dp[x] = 0;
//	}
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	Init a new pstm_int.
*/
int32 pstm_init(psPool_t *pool, pstm_int * a)
{
//bbox
//	int32		i;
/*
	allocate memory required and clear it
 */
	a->dp = xzalloc(sizeof (pstm_digit) * PSTM_DEFAULT_INIT);//bbox
/*
	set the digits to zero
 */
//bbox
//	for (i = 0; i < PSTM_DEFAULT_INIT; i++) {
//		a->dp[i] = 0;
//	}
/*
	set the used to zero, allocated digits to the default precision and sign
	to positive
 */
//bbox	a->pool = pool;
	a->used  = 0;
	a->alloc = PSTM_DEFAULT_INIT;
	a->sign  = PSTM_ZPOS;

	return PSTM_OKAY;
}

/******************************************************************************/
/*
	Grow as required
 */
int32 pstm_grow(pstm_int * a, int size)
{
	int			i; //bbox: was int16
	pstm_digit		*tmp;

/*
	If the alloc size is smaller alloc more ram.
 */
	if (a->alloc < size) {
/*
		Reallocate the array a->dp

		We store the return in a temporary variable in case the operation
		failed we don't want to overwrite the dp member of a.
*/
		tmp = xrealloc(a->dp, sizeof (pstm_digit) * size);//bbox
/*
		reallocation succeeded so set a->dp
 */
		a->dp = tmp;
/*
		zero excess digits
 */
		i			= a->alloc;
		a->alloc	= size;
		for (; i < a->alloc; i++) {
			a->dp[i] = 0;
		}
	}
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	copy, b = a (b must be pre-allocated)
 */
int32 pstm_copy(pstm_int * a, pstm_int * b)
{
	int32	res, n;

/*
	If dst == src do nothing
 */
	if (a == b) {
		return PSTM_OKAY;
	}
/*
	Grow dest
 */
	if (b->alloc < a->used) {
		if ((res = pstm_grow (b, a->used)) != PSTM_OKAY) {
			return res;
		}
	}
/*
	Zero b and copy the parameters over
 */
	{
		register pstm_digit *tmpa, *tmpb;

		/* pointer aliases */
		/* source */
		tmpa = a->dp;

		/* destination */
		tmpb = b->dp;

		/* copy all the digits */
		for (n = 0; n < a->used; n++) {
			*tmpb++ = *tmpa++;
		}

		/* clear high digits */
		for (; n < b->used; n++) {
			*tmpb++ = 0;
		}
	}
/*
	copy used count and sign
 */
	b->used = a->used;
	b->sign = a->sign;
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	Trim unused digits

	This is used to ensure that leading zero digits are trimed and the
	leading "used" digit will be non-zero. Typically very fast.  Also fixes
	the sign if there are no more leading digits
*/
void pstm_clamp(pstm_int * a)
{
/*	decrease used while the most significant digit is zero. */
	while (a->used > 0 && a->dp[a->used - 1] == 0) {
		--(a->used);
	}
/*	reset the sign flag if used == 0 */
	if (a->used == 0) {
		a->sign = PSTM_ZPOS;
	}
}

/******************************************************************************/
/*
	clear one (frees).
 */
void pstm_clear(pstm_int * a)
{
	int32		i;
/*
	only do anything if a hasn't been freed previously
 */
	if (a != NULL && a->dp != NULL) {
/*
		first zero the digits
 */
		for (i = 0; i < a->used; i++) {
			a->dp[i] = 0;
		}

		psFree (a->dp, a->pool);
/*
		reset members to make debugging easier
 */
		a->dp		= NULL;
		a->alloc	= a->used = 0;
		a->sign		= PSTM_ZPOS;
	}
}

/******************************************************************************/
/*
	clear many (frees).
 */
void pstm_clear_multi(pstm_int *mp0, pstm_int *mp1, pstm_int *mp2,
					pstm_int *mp3, pstm_int *mp4, pstm_int *mp5,
					pstm_int *mp6, pstm_int *mp7)
{
	int32		n;		/* Number of ok inits */

	pstm_int	*tempArray[9];

	tempArray[0] = mp0;
	tempArray[1] = mp1;
	tempArray[2] = mp2;
	tempArray[3] = mp3;
	tempArray[4] = mp4;
	tempArray[5] = mp5;
	tempArray[6] = mp6;
	tempArray[7] = mp7;
	tempArray[8] = NULL;

	for (n = 0; tempArray[n] != NULL; n++) {
		if ((tempArray[n] != NULL) && (tempArray[n]->dp != NULL)) {
			pstm_clear(tempArray[n]);
		}
	}
}

/******************************************************************************/
/*
	Set to zero.
 */
void pstm_zero(pstm_int * a)
{
	int32		n;
	pstm_digit	*tmp;

	a->sign = PSTM_ZPOS;
	a->used = 0;

	tmp = a->dp;
	for (n = 0; n < a->alloc; n++) {
		*tmp++ = 0;
	}
}


/******************************************************************************/
/*
	Compare maginitude of two ints (unsigned).
 */
int32 pstm_cmp_mag(pstm_int * a, pstm_int * b)
{
	int		n; //bbox: was int16
	pstm_digit	*tmpa, *tmpb;

/*
	compare based on # of non-zero digits
 */
	if (a->used > b->used) {
		return PSTM_GT;
	}

	if (a->used < b->used) {
		return PSTM_LT;
	}

	/* alias for a */
	tmpa = a->dp + (a->used - 1);

	/* alias for b */
	tmpb = b->dp + (a->used - 1);

/*
	compare based on digits
 */
	for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
		if (*tmpa > *tmpb) {
			return PSTM_GT;
		}
		if (*tmpa < *tmpb) {
			return PSTM_LT;
		}
	}
	return PSTM_EQ;
}

/******************************************************************************/
/*
	Compare two ints (signed)
 */
int32 pstm_cmp(pstm_int * a, pstm_int * b)
{
/*
	compare based on sign
 */
	if (a->sign != b->sign) {
		if (a->sign == PSTM_NEG) {
			return PSTM_LT;
		} else {
			return PSTM_GT;
		}
	}
/*
	compare digits
 */
	if (a->sign == PSTM_NEG) {
		/* if negative compare opposite direction */
		return pstm_cmp_mag(b, a);
	} else {
		return pstm_cmp_mag(a, b);
	}
}

/******************************************************************************/
/*
	pstm_ints can be initialized more precisely when they will populated
	using pstm_read_unsigned_bin since the length of the byte stream is known
*/
int32 pstm_init_for_read_unsigned_bin(psPool_t *pool, pstm_int *a, uint32 len)
{
	int32 size;
/*
	Need to set this based on how many words max it will take to store the bin.
	The magic + 2:
		1 to round up for the remainder of this integer math
		1 for the initial carry of '1' bits that fall between DIGIT_BIT and 8
*/
	size = (((len / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
		/ DIGIT_BIT) + 2;
	return pstm_init_size(pool, a, size);
}


/******************************************************************************/
/*
	Reads a unsigned char array into pstm_int format.  User should have
	called pstm_init_for_read_unsigned_bin first.  There is some grow logic
	here if the default pstm_init was used but we don't really want to hit it.
*/
int32 pstm_read_unsigned_bin(pstm_int *a, unsigned char *b, int32 c)
{
	/* zero the int */
	pstm_zero (a);

/*
	If we know the endianness of this architecture, and we're using
	32-bit pstm_digits, we can optimize this
*/
#if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(PSTM_64BIT)
  /* But not for both simultaneously */
#if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG)
#error Both ENDIAN_LITTLE and ENDIAN_BIG defined.
#endif
	{
		unsigned char *pd;
		if ((unsigned)c > (PSTM_MAX_SIZE * sizeof(pstm_digit))) {
			uint32 excess = c - (PSTM_MAX_SIZE * sizeof(pstm_digit));
			c -= excess;
			b += excess;
		}
		a->used = ((c + sizeof(pstm_digit) - 1)/sizeof(pstm_digit));
		if (a->alloc < a->used) {
			if (pstm_grow(a, a->used) != PSTM_OKAY) {
				return PSTM_MEM;
			}
		}
		pd = (unsigned char *)a->dp;
		/* read the bytes in */
#ifdef ENDIAN_BIG
		{
			/* Use Duff's device to unroll the loop. */
			int32 idx = (c - 1) & ~3;
			switch (c % 4) {
				case 0:	do { pd[idx+0] = *b++;
					case 3:	     pd[idx+1] = *b++;
					case 2:	     pd[idx+2] = *b++;
					case 1:	     pd[idx+3] = *b++;
					idx -= 4;
				} while ((c -= 4) > 0);
			}
		}
#else
		for (c -= 1; c >= 0; c -= 1) {
			pd[c] = *b++;
		}
#endif
	}
#else
	/* Big enough based on the len? */
	a->used = (((c / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
		/ DIGIT_BIT) + 2;

	if (a->alloc < a->used) {
		if (pstm_grow(a, a->used) != PSTM_OKAY) {
			return PSTM_MEM;
		}
	}
	/* read the bytes in */
	for (; c > 0; c--) {
		if (pstm_mul_2d (a, 8, a) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
		a->dp[0] |= *b++;
		a->used += 1;
	}
#endif

	pstm_clamp (a);
	return PS_SUCCESS;
}

/******************************************************************************/
/*
*/
int pstm_count_bits (pstm_int * a)
{
	int     r; //bbox: was int16
	pstm_digit q;

	if (a->used == 0) {
		return 0;
	}

	/* get number of digits and add that */
	r = (a->used - 1) * DIGIT_BIT;

	/* take the last digit and count the bits in it */
	q = a->dp[a->used - 1];
	while (q > ((pstm_digit) 0)) {
		++r;
		q >>= ((pstm_digit) 1);
	}
	return r;
}

/******************************************************************************/
int32 pstm_unsigned_bin_size(pstm_int *a)
{
	int32     size = pstm_count_bits (a);
	return (size / 8 + ((size & 7) != 0 ? 1 : 0));
}

/******************************************************************************/
void pstm_set(pstm_int *a, pstm_digit b)
{
   pstm_zero(a);
   a->dp[0] = b;
   a->used  = a->dp[0] ? 1 : 0;
}

/******************************************************************************/
/*
	Right shift
*/
void pstm_rshd(pstm_int *a, int x)
{
	int y; //bbox: was int16

	/* too many digits just zero and return */
	if (x >= a->used) {
		pstm_zero(a);
		return;
	}

	/* shift */
	for (y = 0; y < a->used - x; y++) {
		a->dp[y] = a->dp[y+x];
	}

	/* zero rest */
	for (; y < a->used; y++) {
		a->dp[y] = 0;
	}

	/* decrement count */
	a->used -= x;
	pstm_clamp(a);
}

/******************************************************************************/
/*
	Shift left a certain amount of digits.
 */
int32 pstm_lshd(pstm_int * a, int b)
{
	int	x; //bbox: was int16
	int32	res;

/*
	If its less than zero return.
 */
	if (b <= 0) {
		return PSTM_OKAY;
	}
/*
	Grow to fit the new digits.
 */
	if (a->alloc < a->used + b) {
		if ((res = pstm_grow (a, a->used + b)) != PSTM_OKAY) {
			return res;
		}
	}

	{
		register pstm_digit *top, *bottom;
/*
		Increment the used by the shift amount then copy upwards.
 */
		a->used += b;

		/* top */
		top = a->dp + a->used - 1;

		/* base */
		bottom = a->dp + a->used - 1 - b;
/*
		This is implemented using a sliding window except the window goes the
		other way around.  Copying from the bottom to the top.
 */
		for (x = a->used - 1; x >= b; x--) {
			*top-- = *bottom--;
		}

		/* zero the lower digits */
		top = a->dp;
		for (x = 0; x < b; x++) {
			*top++ = 0;
		}
	}
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	computes a = 2**b
*/
int32 pstm_2expt(pstm_int *a, int b)
{
	int     z; //bbox: was int16

   /* zero a as per default */
	pstm_zero (a);

	if (b < 0) {
		return PSTM_OKAY;
	}

	z = b / DIGIT_BIT;
	if (z >= PSTM_MAX_SIZE) {
		return PS_LIMIT_FAIL;
	}

	/* set the used count of where the bit will go */
	a->used = z + 1;

	if (a->used > a->alloc) {
		if (pstm_grow(a, a->used) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
	}

	/* put the single bit in its place */
	a->dp[z] = ((pstm_digit)1) << (b % DIGIT_BIT);
	return PSTM_OKAY;
}

/******************************************************************************/
/*

*/
int32 pstm_mul_2(pstm_int * a, pstm_int * b)
{
	int32	res;
	int	x, oldused; //bbox: was int16

/*
	grow to accomodate result
 */
	if (b->alloc < a->used + 1) {
		if ((res = pstm_grow (b, a->used + 1)) != PSTM_OKAY) {
			return res;
		}
	}
	oldused = b->used;
	b->used = a->used;

	{
		register pstm_digit r, rr, *tmpa, *tmpb;

		/* alias for source */
		tmpa = a->dp;

		/* alias for dest */
		tmpb = b->dp;

		/* carry */
		r = 0;
		for (x = 0; x < a->used; x++) {
/*
			get what will be the *next* carry bit from the
			MSB of the current digit
*/
			rr = *tmpa >> ((pstm_digit)(DIGIT_BIT - 1));
/*
			now shift up this digit, add in the carry [from the previous]
*/
			*tmpb++ = ((*tmpa++ << ((pstm_digit)1)) | r);
/*
			copy the carry that would be from the source
			digit into the next iteration
*/
			r = rr;
		}

		/* new leading digit? */
		if (r != 0 && b->used != (PSTM_MAX_SIZE-1)) {
			/* add a MSB which is always 1 at this point */
			*tmpb = 1;
			++(b->used);
		}
/*
		now zero any excess digits on the destination that we didn't write to
*/
		tmpb = b->dp + b->used;
		for (x = b->used; x < oldused; x++) {
			*tmpb++ = 0;
		}
	}
	b->sign = a->sign;
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	unsigned subtraction ||a|| >= ||b|| ALWAYS!
*/
int32 s_pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c)
{
	int		oldbused, oldused; //bbox: was int16
	int32		x;
	pstm_word	t;

	if (b->used > a->used) {
		return PS_LIMIT_FAIL;
	}
	if (c->alloc < a->used) {
		if ((x = pstm_grow (c, a->used)) != PSTM_OKAY) {
			return x;
		}
	}
	oldused  = c->used;
	oldbused = b->used;
	c->used  = a->used;
	t = 0;

	for (x = 0; x < oldbused; x++) {
		t = ((pstm_word)a->dp[x]) - (((pstm_word)b->dp[x]) + t);
		c->dp[x] = (pstm_digit)t;
		t = (t >> DIGIT_BIT)&1;
	}
	for (; x < a->used; x++) {
		t = ((pstm_word)a->dp[x]) - t;
		c->dp[x] = (pstm_digit)t;
		t = (t >> DIGIT_BIT);
	}
	for (; x < oldused; x++) {
		c->dp[x] = 0;
	}
	pstm_clamp(c);
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	unsigned addition
*/
static int32 s_pstm_add(pstm_int *a, pstm_int *b, pstm_int *c)
{
	int				x, y, oldused; //bbox: was int16
	register pstm_word	t, adp, bdp;

	y = a->used;
	if (b->used > y) {
		y = b->used;
	}
	oldused = c->used;
	c->used = y;

	if (c->used > c->alloc) {
		if (pstm_grow(c, c->used) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
	}

	t = 0;
	for (x = 0; x < y; x++) {
		if (a->used < x) {
			adp = 0;
		} else {
			adp = (pstm_word)a->dp[x];
		}
		if (b->used < x) {
			bdp = 0;
		} else {
			bdp = (pstm_word)b->dp[x];
		}
		t         += (adp) + (bdp);
		c->dp[x]   = (pstm_digit)t;
		t        >>= DIGIT_BIT;
	}
	if (t != 0 && x < PSTM_MAX_SIZE) {
		if (c->used == c->alloc) {
			if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) {
				return PS_MEM_FAIL;
			}
		}
		c->dp[c->used++] = (pstm_digit)t;
		++x;
	}

	c->used = x;
	for (; x < oldused; x++) {
		c->dp[x] = 0;
	}
	pstm_clamp(c);
	return PSTM_OKAY;
}


/******************************************************************************/
/*

*/
int32 pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c)
{
	int32	res;
	int	sa, sb; //bbox: was int16

	sa = a->sign;
	sb = b->sign;

	if (sa != sb) {
/*
		subtract a negative from a positive, OR a positive from a negative.
		For both, ADD their magnitudes, and use the sign of the first number.
 */
		c->sign = sa;
		if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) {
			return res;
		}
	} else {
/*
		subtract a positive from a positive, OR a negative from a negative.
		First, take the difference between their magnitudes, then...
 */
		if (pstm_cmp_mag (a, b) != PSTM_LT) {
			/* Copy the sign from the first */
			c->sign = sa;
			/* The first has a larger or equal magnitude */
			if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) {
				return res;
			}
		} else {
			/* The result has the _opposite_ sign from the first number. */
			c->sign = (sa == PSTM_ZPOS) ? PSTM_NEG : PSTM_ZPOS;
			/* The second has a larger magnitude */
			if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) {
				return res;
			}
		}
	}
	return PS_SUCCESS;
}

/******************************************************************************/
/*
	c = a - b
*/
int32 pstm_sub_d(psPool_t *pool, pstm_int *a, pstm_digit b, pstm_int *c)
{
	pstm_int	tmp;
	int32		res;

	if (pstm_init_size(pool, &tmp, sizeof(pstm_digit)) != PSTM_OKAY) {
		return PS_MEM_FAIL;
	}
	pstm_set(&tmp, b);
	res = pstm_sub(a, &tmp, c);
	pstm_clear(&tmp);
	return res;
}

/******************************************************************************/
/*
	setups the montgomery reduction
*/
int32 pstm_montgomery_setup(pstm_int *a, pstm_digit *rho)
{
	pstm_digit x, b;

/*
	fast inversion mod 2**k
	Based on the fact that
	XA = 1 (mod 2**n)	=>  (X(2-XA)) A = 1 (mod 2**2n)
						=>  2*X*A - X*X*A*A = 1
						=>  2*(1) - (1)     = 1
 */
	b = a->dp[0];

	if ((b & 1) == 0) {
		psTraceCrypto("pstm_montogomery_setup failure\n");
		return PS_ARG_FAIL;
	}

	x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
	x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
	x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
	x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
#ifdef PSTM_64BIT
	x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
#endif
	/* rho = -1/m mod b */
	*rho = (pstm_digit)(((pstm_word) 1 << ((pstm_word) DIGIT_BIT)) -
		((pstm_word)x));
	return PSTM_OKAY;
}

/******************************************************************************/
/*
 *	computes a = B**n mod b without division or multiplication useful for
 *	normalizing numbers in a Montgomery system.
 */
int32 pstm_montgomery_calc_normalization(pstm_int *a, pstm_int *b)
{
	int32     x;
	int	bits; //bbox: was int16

	/* how many bits of last digit does b use */
	bits = pstm_count_bits (b) % DIGIT_BIT;
	if (!bits) bits = DIGIT_BIT;

	/* compute A = B^(n-1) * 2^(bits-1) */
	if (b->used > 1) {
		if ((x = pstm_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) !=
				PSTM_OKAY) {
			return x;
		}
	} else {
		pstm_set(a, 1);
		bits = 1;
	}

	/* now compute C = A * B mod b */
	for (x = bits - 1; x < (int32)DIGIT_BIT; x++) {
		if (pstm_mul_2 (a, a) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
		if (pstm_cmp_mag (a, b) != PSTM_LT) {
			if (s_pstm_sub (a, b, a) != PSTM_OKAY) {
				return PS_MEM_FAIL;
			}
		}
	}
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	c = a * 2**d
*/
static int32 pstm_mul_2d(pstm_int *a, int b, pstm_int *c)
{
	pstm_digit	carry, carrytmp, shift;
	int		x; //bbox: was int16

	/* copy it */
	if (pstm_copy(a, c) != PSTM_OKAY) {
		return PS_MEM_FAIL;
	}

	/* handle whole digits */
	if (b >= DIGIT_BIT) {
		if (pstm_lshd(c, b/DIGIT_BIT) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
	}
	b %= DIGIT_BIT;

	/* shift the digits */
	if (b != 0) {
		carry = 0;
		shift = DIGIT_BIT - b;
		for (x = 0; x < c->used; x++) {
			carrytmp = c->dp[x] >> shift;
			c->dp[x] = (c->dp[x] << b) + carry;
			carry = carrytmp;
		}
		/* store last carry if room */
		if (carry && x < PSTM_MAX_SIZE) {
			if (c->used == c->alloc) {
				if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) {
					return PS_MEM_FAIL;
				}
			}
			c->dp[c->used++] = carry;
		}
	}
	pstm_clamp(c);
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	c = a mod 2**d
*/
static int32 pstm_mod_2d(pstm_int *a, int b, pstm_int *c) //bbox: was int16 b
{
	int	x; //bbox: was int16

	/* zero if count less than or equal to zero */
	if (b <= 0) {
		pstm_zero(c);
		return PSTM_OKAY;
	}

	/* get copy of input */
	if (pstm_copy(a, c) != PSTM_OKAY) {
		return PS_MEM_FAIL;
	}

	/* if 2**d is larger than we just return */
	if (b >= (DIGIT_BIT * a->used)) {
		return PSTM_OKAY;
	}

	/* zero digits above the last digit of the modulus */
	for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++)
	{
		c->dp[x] = 0;
	}
	/* clear the digit that is not completely outside/inside the modulus */
	c->dp[b / DIGIT_BIT] &= ~((pstm_digit)0) >> (DIGIT_BIT - b);
	pstm_clamp (c);
	return PSTM_OKAY;
}


/******************************************************************************/
/*
	c = a * b
*/
int32 pstm_mul_d(pstm_int *a, pstm_digit b, pstm_int *c)
{
	pstm_word	w;
	int32		res;
	int		x, oldused; //bbox: was int16

	if (c->alloc < a->used + 1) {
		if ((res = pstm_grow (c, a->used + 1)) != PSTM_OKAY) {
			return res;
		}
	}
	oldused = c->used;
	c->used = a->used;
	c->sign = a->sign;
	w       = 0;
	for (x = 0; x < a->used; x++) {
		w         = ((pstm_word)a->dp[x]) * ((pstm_word)b) + w;
		c->dp[x]  = (pstm_digit)w;
		w         = w >> DIGIT_BIT;
	}
	if (w != 0 && (a->used != PSTM_MAX_SIZE)) {
		c->dp[c->used++] = (pstm_digit)w;
		++x;
	}
	for (; x < oldused; x++) {
		c->dp[x] = 0;
	}
	pstm_clamp(c);
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	c = a / 2**b
*/
int32 pstm_div_2d(psPool_t *pool, pstm_int *a, int b, pstm_int *c,
					pstm_int *d)
{
	pstm_digit	D, r, rr;
	int32		res;
	int		x; //bbox: was int16
	pstm_int	t;

	/* if the shift count is <= 0 then we do no work */
	if (b <= 0) {
		if (pstm_copy (a, c) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
		if (d != NULL) {
			pstm_zero (d);
		}
		return PSTM_OKAY;
	}

	/* get the remainder */
	if (d != NULL) {
		if (pstm_init(pool, &t) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
		if (pstm_mod_2d (a, b, &t) != PSTM_OKAY) {
			res = PS_MEM_FAIL;
			goto LBL_DONE;
		}
	}

	/* copy */
	if (pstm_copy(a, c) != PSTM_OKAY) {
		res = PS_MEM_FAIL;
		goto LBL_DONE;
	}

	/* shift by as many digits in the bit count */
	if (b >= (int32)DIGIT_BIT) {
		pstm_rshd (c, b / DIGIT_BIT);
	}

	/* shift any bit count < DIGIT_BIT */
	D = (pstm_digit) (b % DIGIT_BIT);
	if (D != 0) {
		register pstm_digit *tmpc, mask, shift;

		/* mask */
		mask = (((pstm_digit)1) << D) - 1;

		/* shift for lsb */
		shift = DIGIT_BIT - D;

		/* alias */
		tmpc = c->dp + (c->used - 1);

		/* carry */
		r = 0;
		for (x = c->used - 1; x >= 0; x--) {
			/* get the lower  bits of this word in a temp */
			rr = *tmpc & mask;

			/* shift the current word and mix in the carry bits from previous */
			*tmpc = (*tmpc >> D) | (r << shift);
			--tmpc;

			/* set the carry to the carry bits of the current word above */
			r = rr;
		}
	}
	pstm_clamp (c);

	res = PSTM_OKAY;
LBL_DONE:
	if (d != NULL) {
		if (pstm_copy(&t, d) != PSTM_OKAY) {
			res = PS_MEM_FAIL;
		}
		pstm_clear(&t);
	}
	return res;
}

/******************************************************************************/
/*
	b = a/2
*/
int32 pstm_div_2(pstm_int * a, pstm_int * b)
{
	int	x, oldused; //bbox: was int16

	if (b->alloc < a->used) {
		if (pstm_grow(b, a->used) != PSTM_OKAY) {
			return PS_MEM_FAIL;
		}
	}
	oldused = b->used;
	b->used = a->used;
	{
		register pstm_digit r, rr, *tmpa, *tmpb;

		/* source alias */
		tmpa = a->dp + b->used - 1;

		/* dest alias */
		tmpb = b->dp + b->used - 1;

		/* carry */
		r = 0;
		for (x = b->used - 1; x >= 0; x--) {
			/* get the carry for the next iteration */
			rr = *tmpa & 1;

			/* shift the current digit, add in carry and store */
			*tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));

			/* forward carry to next iteration */
			r = rr;
		}

		/* zero excess digits */
		tmpb = b->dp + b->used;
		for (x = b->used; x < oldused; x++) {
			*tmpb++ = 0;
		}
	}
	b->sign = a->sign;
	pstm_clamp (b);
	return PSTM_OKAY;
}

/******************************************************************************/
/*
	Creates "a" then copies b into it
 */
int32 pstm_init_copy(psPool_t *pool, pstm_int * a, pstm_int * b, int toSqr)
{
	int	x; //bbox: was int16
	int32	res;

	if (a == b) {
		return PSTM_OKAY;
	}
	x = b->alloc;

	if (toSqr) {
/*
		Smart-size:  Increasing size of a if b->used is roughly half
		of b->alloc because usage has shown that a lot of these copies
		go on to be squared and need these extra digits
*/
		if ((b->used * 2) + 2 >= x) {
			x = (b->used * 2) + 3;
		}
	}
	if ((res = pstm_init_size(pool, a, x)) != PSTM_OKAY) {
		return res;
	}
	return pstm_copy(b, a);
}

/******************************************************************************/
/*
	With some compilers, we have seen issues linking with the builtin
	64 bit division routine. The issues with either manifest in a failure
	to find 'udivdi3' at link time, or a runtime invalid instruction fault
	during an RSA operation.
	The routine below divides a 64 bit unsigned int by a 32 bit unsigned int
	explicitly, rather than using the division operation
		The 64 bit result is placed in the 'numerator' parameter
		The 32 bit mod (remainder) of the division is the return parameter
	Based on implementations by:
		Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
		Copyright (C) 1999 Hewlett-Packard Co
		Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
*/
#if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
static uint32 psDiv64(uint64 *numerator, uint32 denominator)
{
	uint64	rem = *numerator;
	uint64	b = denominator;
	uint64	res = 0;
	uint64	d = 1;
	uint32	high = rem >> 32;

	if (high >= denominator) {
		high /= denominator;
		res = (uint64) high << 32;
		rem -= (uint64) (high * denominator) << 32;
	}
	while ((int64)b > 0 && b < rem) {
		b = b+b;
		d = d+d;
	}
	do {
		if (rem >= b) {
			rem -= b;
			res += d;
		}
		b >>= 1;
		d >>= 1;
	} while (d);
	*numerator = res;
	return rem;
}
#endif /* USE_MATRIX_DIV64 */

#if defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
typedef unsigned long	uint128 __attribute__ ((mode(TI)));
static uint64 psDiv128(uint128 *numerator, uint64 denominator)
{
	uint128	rem = *numerator;
	uint128	b = denominator;
	uint128	res = 0;
	uint128	d = 1;
	uint64	high = rem >> 64;

	if (high >= denominator) {
		high /= denominator;
		res = (uint128) high << 64;
		rem -= (uint128) (high * denominator) << 64;
	}
	while ((uint128)b > 0 && b < rem) {
		b = b+b;
		d = d+d;
	}
	do {
		if (rem >= b) {
			rem -= b;
			res += d;
		}
		b >>= 1;
		d >>= 1;
	} while (d);
	*numerator = res;
	return rem;
}
#endif /* USE_MATRIX_DIV128 */

/******************************************************************************/
/*
	a/b => cb + d == a
*/
int32 pstm_div(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c,
				pstm_int *d)
{
	pstm_int	q, x, y, t1, t2;
	int32		res;
	int		n, t, i, norm, neg; //bbox: was int16

	/* is divisor zero ? */
	if (pstm_iszero (b) == 1) {
		return PS_LIMIT_FAIL;
	}

	/* if a < b then q=0, r = a */
	if (pstm_cmp_mag (a, b) == PSTM_LT) {
		if (d != NULL) {
			if (pstm_copy(a, d) != PSTM_OKAY) {
				return PS_MEM_FAIL;
			}
		}
		if (c != NULL) {
			pstm_zero (c);
		}
		return PSTM_OKAY;
	}
/*
	Smart-size inits
*/
	if ((res = pstm_init_size(pool, &t1, a->alloc)) != PSTM_OKAY) {
		return res;
	}
	if ((res = pstm_init_size(pool, &t2, 3)) != PSTM_OKAY) {
		goto LBL_T1;
	}
	if ((res = pstm_init_copy(pool, &x, a, 0)) != PSTM_OKAY) {
		goto LBL_T2;
	}
/*
	Used to be an init_copy on b but pstm_grow was always hit with triple size
*/
	if ((res = pstm_init_size(pool, &y, b->used * 3)) != PSTM_OKAY) {
		goto LBL_X;
	}
	if ((res = pstm_copy(b, &y)) != PSTM_OKAY) {
		goto LBL_Y;
	}

	/* fix the sign */
	neg = (a->sign == b->sign) ? PSTM_ZPOS : PSTM_NEG;
	x.sign = y.sign = PSTM_ZPOS;

	/* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
	norm = pstm_count_bits(&y) % DIGIT_BIT;
	if (norm < (int32)(DIGIT_BIT-1)) {
		norm = (DIGIT_BIT-1) - norm;
		if ((res = pstm_mul_2d(&x, norm, &x)) != PSTM_OKAY) {
			goto LBL_Y;
		}
		if ((res = pstm_mul_2d(&y, norm, &y)) != PSTM_OKAY) {
			goto LBL_Y;
		}
	} else {
		norm = 0;
	}

	/* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
	n = x.used - 1;
	t = y.used - 1;

	if ((res = pstm_init_size(pool, &q, n - t + 1)) != PSTM_OKAY) {
		goto LBL_Y;
	}
	q.used = n - t + 1;

	/* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
	if ((res = pstm_lshd(&y, n - t)) != PSTM_OKAY) { /* y = y*b**{n-t} */
		goto LBL_Q;
	}

	while (pstm_cmp (&x, &y) != PSTM_LT) {
		++(q.dp[n - t]);
		if ((res = pstm_sub(&x, &y, &x)) != PSTM_OKAY) {
			goto LBL_Q;
		}
	}

	/* reset y by shifting it back down */
	pstm_rshd (&y, n - t);

	/* step 3. for i from n down to (t + 1) */
	for (i = n; i >= (t + 1); i--) {
		if (i > x.used) {
			continue;
		}

		/* step 3.1 if xi == yt then set q{i-t-1} to b-1,
		 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
		if (x.dp[i] == y.dp[t]) {
			q.dp[i - t - 1] = (pstm_digit)((((pstm_word)1) << DIGIT_BIT) - 1);
		} else {
			pstm_word tmp;
			tmp = ((pstm_word) x.dp[i]) << ((pstm_word) DIGIT_BIT);
			tmp |= ((pstm_word) x.dp[i - 1]);
#if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
			psDiv64(&tmp, y.dp[t]);
#elif defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
			psDiv128(&tmp, y.dp[t]);
#else
			tmp /= ((pstm_word) y.dp[t]);
#endif /* USE_MATRIX_DIV64 */
			q.dp[i - t - 1] = (pstm_digit) (tmp);
		}

		/* while (q{i-t-1} * (yt * b + y{t-1})) >
			 xi * b**2 + xi-1 * b + xi-2

			do q{i-t-1} -= 1;
		*/
		q.dp[i - t - 1] = (q.dp[i - t - 1] + 1);
		do {
			q.dp[i - t - 1] = (q.dp[i - t - 1] - 1);

			/* find left hand */
			pstm_zero (&t1);
			t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
			t1.dp[1] = y.dp[t];
			t1.used = 2;
			if ((res = pstm_mul_d (&t1, q.dp[i - t - 1], &t1)) != PSTM_OKAY) {
				goto LBL_Q;
			}

			/* find right hand */
			t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
			t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
			t2.dp[2] = x.dp[i];
			t2.used = 3;
		} while (pstm_cmp_mag(&t1, &t2) == PSTM_GT);

		/* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
		if ((res = pstm_mul_d(&y, q.dp[i - t - 1], &t1)) != PSTM_OKAY) {
			goto LBL_Q;
		}

		if ((res = pstm_lshd(&t1, i - t - 1)) != PSTM_OKAY) {
			goto LBL_Q;
		}

		if ((res = pstm_sub(&x, &t1, &x)) != PSTM_OKAY) {
			goto LBL_Q;
		}

		/* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
		if (x.sign == PSTM_NEG) {
			if ((res = pstm_copy(&y, &t1)) != PSTM_OKAY) {
				goto LBL_Q;
			}
			if ((res = pstm_lshd (&t1, i - t - 1)) != PSTM_OKAY) {
				goto LBL_Q;
			}
			if ((res = pstm_add (&x, &t1, &x)) != PSTM_OKAY) {
				goto LBL_Q;
			}
			q.dp[i - t - 1] = q.dp[i - t - 1] - 1;
		}
	}
/*
	now q is the quotient and x is the remainder (which we have to normalize)
*/
	/* get sign before writing to c */
	x.sign = x.used == 0 ? PSTM_ZPOS : a->sign;

	if (c != NULL) {
		pstm_clamp (&q);
		if (pstm_copy (&q, c) != PSTM_OKAY) {
			res = PS_MEM_FAIL;
			goto LBL_Q;
		}
		c->sign = neg;
	}

	if (d != NULL) {
		if ((res = pstm_div_2d (pool, &x, norm, &x, NULL)) != PSTM_OKAY) {
			goto LBL_Q;
		}
/*
		the following is a kludge, essentially we were seeing the right
		remainder but with excess digits that should have been zero
 */
		for (i = b->used; i < x.used; i++) {
			x.dp[i] = 0;
		}
		pstm_clamp(&x);
		if (pstm_copy (&x, d) != PSTM_OKAY) {
			res = PS_MEM_FAIL;
			goto LBL_Q;
		}
	}

	res = PSTM_OKAY;

LBL_Q:pstm_clear (&q);
LBL_Y:pstm_clear (&y);
LBL_X:pstm_clear (&x);
LBL_T2:pstm_clear (&t2);
LBL_T1:pstm_clear (&t1);

	return res;
}

/******************************************************************************/
/*
	Swap the elements of two integers, for cases where you can't simply swap
	the pstm_int pointers around
*/
void pstm_exch(pstm_int * a, pstm_int * b)
{
	pstm_int		t;

	t	= *a;
	*a	= *b;
	*b	= t;
}

/******************************************************************************/
/*
	c = a mod b, 0 <= c < b
*/
int32 pstm_mod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c)
{
	pstm_int	t;
	int32		err;
/*
	Smart-size
*/
	if ((err = pstm_init_size(pool, &t, b->alloc)) != PSTM_OKAY) {
		return err;
	}
	if ((err = pstm_div(pool, a, b, NULL, &t)) != PSTM_OKAY) {
		pstm_clear (&t);
		return err;
	}
	if (t.sign != b->sign) {
		err = pstm_add(&t, b, c);
	} else {
		pstm_exch (&t, c);
	}
	pstm_clear (&t);
	return err;
}

/******************************************************************************/
/*
	d = a * b (mod c)
*/
int32 pstm_mulmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c,
			pstm_int *d)
{
	int32		res;
	int		size; //bbox: was int16
	pstm_int	tmp;

/*
	Smart-size pstm_inits.  d is an output that is influenced by this local 't'
	so don't shrink 'd' if it wants to becuase this will lead to an pstm_grow
	in RSA operations
*/
	size = a->used + b->used + 1;
	if ((a == d) && (size < a->alloc)) {
		size = a->alloc;
	}
	if ((res = pstm_init_size(pool, &tmp, size)) != PSTM_OKAY) {
		return res;
	}
	if ((res = pstm_mul_comba(pool, a, b, &tmp, NULL, 0)) != PSTM_OKAY) {
		pstm_clear(&tmp);
		return res;
	}
	res = pstm_mod(pool, &tmp, c, d);
	pstm_clear(&tmp);
	return res;
}

/******************************************************************************/
/*
 *	y = g**x (mod b)
 *	Some restrictions... x must be positive and < b
 */
int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P,
			pstm_int *Y)
{
	pstm_int	M[32], res; /* Keep this winsize based: (1 << max_winsize) */
	pstm_digit	buf, mp;
	pstm_digit	*paD;
	int32		err, bitbuf;
	int		bitcpy, bitcnt, mode, digidx, x, y, winsize; //bbox: was int16
	uint32		paDlen;

	/* set window size from what user set as optimization */
	x = pstm_count_bits(X);
	if (x < 50) {
		winsize = 2;
	} else {
		winsize = PS_EXPTMOD_WINSIZE;
	}

	/* now setup montgomery  */
	if ((err = pstm_montgomery_setup (P, &mp)) != PSTM_OKAY) {
		return err;
	}

	/* setup result */
	if ((err = pstm_init_size(pool, &res, (P->used * 2) + 1)) != PSTM_OKAY) {
		return err;
	}
/*
	create M table
	The M table contains powers of the input base, e.g. M[x] = G^x mod P
	The first half of the table is not computed though except for M[0] and M[1]
 */
	/* now we need R mod m */
	if ((err = pstm_montgomery_calc_normalization (&res, P)) != PSTM_OKAY) {
		goto LBL_RES;
	}
/*
	init M array
	init first cell
 */
	if ((err = pstm_init_size(pool, &M[1], res.used)) != PSTM_OKAY) {
		goto LBL_RES;
	}

	/* now set M[1] to G * R mod m */
	if (pstm_cmp_mag(P, G) != PSTM_GT) {
		/* G > P so we reduce it first */
		if ((err = pstm_mod(pool, G, P, &M[1])) != PSTM_OKAY) {
			goto LBL_M;
		}
	} else {
		if ((err = pstm_copy(G, &M[1])) != PSTM_OKAY) {
			goto LBL_M;
		}
	}
	if ((err = pstm_mulmod (pool, &M[1], &res, P, &M[1])) != PSTM_OKAY) {
		goto LBL_M;
	}
/*
	Pre-allocated digit.  Used for mul, sqr, AND reduce
*/
	paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit);
	paD = xzalloc(paDlen);//bbox
/*
	compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times
 */
	if (pstm_init_copy(pool, &M[1 << (winsize - 1)], &M[1], 1) != PSTM_OKAY) {
		err = PS_MEM_FAIL;
		goto LBL_PAD;
	}
	for (x = 0; x < (winsize - 1); x++) {
		if ((err = pstm_sqr_comba (pool, &M[1 << (winsize - 1)],
				&M[1 << (winsize - 1)], paD, paDlen)) != PSTM_OKAY) {
			goto LBL_PAD;
		}
		if ((err = pstm_montgomery_reduce(pool, &M[1 << (winsize - 1)], P, mp,
				paD, paDlen)) != PSTM_OKAY) {
			goto LBL_PAD;
		}
	}
/*
	now init the second half of the array
*/
	for (x = (1<<(winsize-1)) + 1; x < (1 << winsize); x++) {
		if ((err = pstm_init_size(pool, &M[x], M[1<<(winsize-1)].alloc + 1))
				!= PSTM_OKAY) {
			for (y = 1<<(winsize-1); y < x; y++) {
				pstm_clear(&M[y]);
			}
			goto LBL_PAD;
		}
	}

	/* create upper table */
	for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
		if ((err = pstm_mul_comba(pool, &M[x - 1], &M[1], &M[x], paD, paDlen))
				!= PSTM_OKAY) {
			goto LBL_MARRAY;
		}
		if ((err = pstm_montgomery_reduce(pool, &M[x], P, mp, paD, paDlen)) !=
				PSTM_OKAY) {
			goto LBL_MARRAY;
		}
	}

	/* set initial mode and bit cnt */
	mode   = 0;
	bitcnt = 1;
	buf    = 0;
	digidx = X->used - 1;
	bitcpy = 0;
	bitbuf = 0;

	for (;;) {
		/* grab next digit as required */
		if (--bitcnt == 0) {
			/* if digidx == -1 we are out of digits so break */
			if (digidx == -1) {
				break;
			}
			/* read next digit and reset bitcnt */
			buf    = X->dp[digidx--];
			bitcnt = (int32)DIGIT_BIT;
		}

		/* grab the next msb from the exponent */
		y     = (pstm_digit)(buf >> (DIGIT_BIT - 1)) & 1;
		buf <<= (pstm_digit)1;
/*
		 If the bit is zero and mode == 0 then we ignore it.
		 These represent the leading zero bits before the first 1 bit
		 in the exponent.  Technically this opt is not required but it
		 does lower the # of trivial squaring/reductions used
*/
		if (mode == 0 && y == 0) {
			continue;
		}

		/* if the bit is zero and mode == 1 then we square */
		if (mode == 1 && y == 0) {
			if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
					PSTM_OKAY) {
				goto LBL_MARRAY;
			}
			if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
					!= PSTM_OKAY) {
				goto LBL_MARRAY;
			}
			continue;
		}

		/* else we add it to the window */
		bitbuf |= (y << (winsize - ++bitcpy));
		mode    = 2;

		if (bitcpy == winsize) {
			/* ok window is filled so square as required and mul square first */
			for (x = 0; x < winsize; x++) {
				if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
						PSTM_OKAY) {
					goto LBL_MARRAY;
				}
				if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
						paDlen)) != PSTM_OKAY) {
					goto LBL_MARRAY;
				}
			}

			/* then multiply */
			if ((err = pstm_mul_comba(pool, &res, &M[bitbuf], &res, paD,
					paDlen)) != PSTM_OKAY) {
				goto LBL_MARRAY;
			}
			if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
					!= PSTM_OKAY) {
				goto LBL_MARRAY;
			}

			/* empty window and reset */
			bitcpy = 0;
			bitbuf = 0;
			mode   = 1;
		}
	}

	/* if bits remain then square/multiply */
	if (mode == 2 && bitcpy > 0) {
		/* square then multiply if the bit is set */
		for (x = 0; x < bitcpy; x++) {
			if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
					PSTM_OKAY) {
				goto LBL_MARRAY;
			}
			if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
					!= PSTM_OKAY) {
				goto LBL_MARRAY;
			}

			/* get next bit of the window */
			bitbuf <<= 1;
			if ((bitbuf & (1 << winsize)) != 0) {
			/* then multiply */
				if ((err = pstm_mul_comba(pool, &res, &M[1], &res, paD, paDlen))
						!= PSTM_OKAY) {
					goto LBL_MARRAY;
				}
				if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
						paDlen)) != PSTM_OKAY) {
					goto LBL_MARRAY;
				}
			}
		}
	}
/*
	Fix up result if Montgomery reduction is used recall that any value in a
	Montgomery system is actually multiplied by R mod n.  So we have to reduce
	one more time to cancel out the factor of R.
*/
	if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) !=
			PSTM_OKAY) {
		goto LBL_MARRAY;
	}
	/* swap res with Y */
	if ((err = pstm_copy (&res, Y)) != PSTM_OKAY) {
		goto LBL_MARRAY;
	}
	err = PSTM_OKAY;
LBL_MARRAY:
	for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
		pstm_clear(&M[x]);
	}
LBL_PAD:psFree(paD, pool);
LBL_M: pstm_clear(&M[1]);
LBL_RES:pstm_clear(&res);
	return err;
}

/******************************************************************************/
/*

*/
int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c)
{
	int32	res;
	int	sa, sb; //bbox: was int16

	/* get sign of both inputs */
	sa = a->sign;
	sb = b->sign;

	/* handle two cases, not four */
	if (sa == sb) {
		/* both positive or both negative, add their mags, copy the sign */
		c->sign = sa;
		if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) {
			return res;
		}
	} else {
/*
		one positive, the other negative
		subtract the one with the greater magnitude from the one of the lesser
		magnitude. The result gets the sign of the one with the greater mag.
 */
		if (pstm_cmp_mag (a, b) == PSTM_LT) {
			c->sign = sb;
			if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) {
				return res;
			}
		} else {
			c->sign = sa;
			if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) {
				return res;
			}
		}
	}
	return PS_SUCCESS;
}

/******************************************************************************/
/*
	reverse an array, used for radix code
*/
static void pstm_reverse (unsigned char *s, int len) //bbox: was int16 len
{
	int32     ix, iy;
	unsigned char t;

	ix = 0;
	iy = len - 1;
	while (ix < iy) {
		t     = s[ix];
		s[ix] = s[iy];
		s[iy] = t;
		++ix;
		--iy;
	}
}
/******************************************************************************/
/*
	No reverse.  Useful in some of the EIP-154 PKA stuff where special byte
	order seems to come into play more often
*/
int32 pstm_to_unsigned_bin_nr(psPool_t *pool, pstm_int *a, unsigned char *b)
{
	int32     res;
	int     x; //bbox: was int16
	pstm_int  t = { 0 };

	if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) {
		return res;
	}

	x = 0;
	while (pstm_iszero (&t) == 0) {
		b[x++] = (unsigned char) (t.dp[0] & 255);
		if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) {
			pstm_clear(&t);
			return res;
		}
	}
	pstm_clear(&t);
	return PS_SUCCESS;
}
/******************************************************************************/
/*

*/
int32 pstm_to_unsigned_bin(psPool_t *pool, pstm_int *a, unsigned char *b)
{
	int32     res;
	int	x; //bbox: was int16
	pstm_int  t = { 0 };

	if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) {
		return res;
	}

	x = 0;
	while (pstm_iszero (&t) == 0) {
		b[x++] = (unsigned char) (t.dp[0] & 255);
		if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) {
			pstm_clear(&t);
			return res;
		}
	}
	pstm_reverse (b, x);
	pstm_clear(&t);
	return PS_SUCCESS;
}

/******************************************************************************/
/*
	compare against a single digit
*/
int32 pstm_cmp_d(pstm_int *a, pstm_digit b)
{
	/* compare based on sign */
	if ((b && a->used == 0) || a->sign == PSTM_NEG) {
		return PSTM_LT;
	}

	/* compare based on magnitude */
	if (a->used > 1) {
		return PSTM_GT;
	}

	/* compare the only digit of a to b */
	if (a->dp[0] > b) {
		return PSTM_GT;
	} else if (a->dp[0] < b) {
		return PSTM_LT;
	} else {
		return PSTM_EQ;
	}
}

/*
	Need invmod for ECC and also private key loading for hardware crypto
	in cases where dQ > dP.  The values must be switched and a new qP must be
	calculated using this function
*/
//bbox: pool unused
#define pstm_invmod_slow(pool, a, b, c) \
        pstm_invmod_slow(      a, b, c)
static int32 pstm_invmod_slow(psPool_t *pool, pstm_int * a, pstm_int * b,
				pstm_int * c)
{
	pstm_int  x, y, u, v, A, B, C, D;
	int32     res;

	/* b cannot be negative */
	if (b->sign == PSTM_NEG || pstm_iszero(b) == 1) {
		return PS_LIMIT_FAIL;
	}

	/* init temps */
	if (pstm_init_size(pool, &x, b->used) != PSTM_OKAY) {
		return PS_MEM_FAIL;
	}

	/* x = a, y = b */
	if ((res = pstm_mod(pool, a, b, &x)) != PSTM_OKAY) {
		goto LBL_X;
	}

	if (pstm_init_copy(pool, &y, b, 0) != PSTM_OKAY) {
		goto LBL_X;
	}

	/* 2. [modified] if x,y are both even then return an error! */
	if (pstm_iseven (&x) == 1 && pstm_iseven (&y) == 1) {
		res = PS_FAILURE;
		goto LBL_Y;
	}

	/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
	if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) {
		goto LBL_Y;
	}
	if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) {
		goto LBL_U;
	}

	if ((res = pstm_init_size(pool, &A, sizeof(pstm_digit))) != PSTM_OKAY) {
		goto LBL_V;
	}

	if ((res = pstm_init_size(pool, &D, sizeof(pstm_digit))) != PSTM_OKAY) {
		goto LBL_A;
	}
	pstm_set (&A, 1);
	pstm_set (&D, 1);

	if ((res = pstm_init(pool, &B)) != PSTM_OKAY) {
		goto LBL_D;
	}
	if ((res = pstm_init(pool, &C)) != PSTM_OKAY) {
		goto LBL_B;
	}

top:
	/* 4.  while u is even do */
	while (pstm_iseven (&u) == 1) {
		/* 4.1 u = u/2 */
		if ((res = pstm_div_2 (&u, &u)) != PSTM_OKAY) {
			goto LBL_C;
		}

		/* 4.2 if A or B is odd then */
		if (pstm_isodd (&A) == 1 || pstm_isodd (&B) == 1) {
			/* A = (A+y)/2, B = (B-x)/2 */
			if ((res = pstm_add (&A, &y, &A)) != PSTM_OKAY) {
				goto LBL_C;
			}
			if ((res = pstm_sub (&B, &x, &B)) != PSTM_OKAY) {
				goto LBL_C;
			}
		}
		/* A = A/2, B = B/2 */
		if ((res = pstm_div_2 (&A, &A)) != PSTM_OKAY) {
			goto LBL_C;
		}
		if ((res = pstm_div_2 (&B, &B)) != PSTM_OKAY) {
			goto LBL_C;
		}
	}

	/* 5.  while v is even do */
	while (pstm_iseven (&v) == 1) {
		/* 5.1 v = v/2 */
		if ((res = pstm_div_2 (&v, &v)) != PSTM_OKAY) {
			goto LBL_C;
		}

		/* 5.2 if C or D is odd then */
		if (pstm_isodd (&C) == 1 || pstm_isodd (&D) == 1) {
			/* C = (C+y)/2, D = (D-x)/2 */
			if ((res = pstm_add (&C, &y, &C)) != PSTM_OKAY) {
				goto LBL_C;
			}
			if ((res = pstm_sub (&D, &x, &D)) != PSTM_OKAY) {
				goto LBL_C;
			}
		}
		/* C = C/2, D = D/2 */
		if ((res = pstm_div_2 (&C, &C)) != PSTM_OKAY) {
			goto LBL_C;
		}
		if ((res = pstm_div_2 (&D, &D)) != PSTM_OKAY) {
			goto LBL_C;
		}
	}

	/* 6.  if u >= v then */
	if (pstm_cmp (&u, &v) != PSTM_LT) {
		/* u = u - v, A = A - C, B = B - D */
		if ((res = pstm_sub (&u, &v, &u)) != PSTM_OKAY) {
				goto LBL_C;
		}
		if ((res = pstm_sub (&A, &C, &A)) != PSTM_OKAY) {
				goto LBL_C;
		}
		if ((res = pstm_sub (&B, &D, &B)) != PSTM_OKAY) {
				goto LBL_C;
		}
	} else {
		/* v - v - u, C = C - A, D = D - B */
		if ((res = pstm_sub (&v, &u, &v)) != PSTM_OKAY) {
				goto LBL_C;
		}
		if ((res = pstm_sub (&C, &A, &C)) != PSTM_OKAY) {
				goto LBL_C;
		}
		if ((res = pstm_sub (&D, &B, &D)) != PSTM_OKAY) {
				goto LBL_C;
		}
	}

	/* if not zero goto step 4 */
	if (pstm_iszero (&u) == 0)
		goto top;

	/* now a = C, b = D, gcd == g*v */

	/* if v != 1 then there is no inverse */
	if (pstm_cmp_d (&v, 1) != PSTM_EQ) {
		res = PS_FAILURE;
		goto LBL_C;
	}

	/* if its too low */
	while (pstm_cmp_d(&C, 0) == PSTM_LT) {
		if ((res = pstm_add(&C, b, &C)) != PSTM_OKAY) {
			goto LBL_C;
		}
	}

	/* too big */
	while (pstm_cmp_mag(&C, b) != PSTM_LT) {
		if ((res = pstm_sub(&C, b, &C)) != PSTM_OKAY) {
			goto LBL_C;
		}
	}

	/* C is now the inverse */
	if ((res = pstm_copy(&C, c)) != PSTM_OKAY) {
		goto LBL_C;
	}
	res = PSTM_OKAY;

LBL_C: pstm_clear(&C);
LBL_D: pstm_clear(&D);
LBL_B: pstm_clear(&B);
LBL_A: pstm_clear(&A);
LBL_V: pstm_clear(&v);
LBL_U: pstm_clear(&u);
LBL_Y: pstm_clear(&y);
LBL_X: pstm_clear(&x);

	return res;
}

/* c = 1/a (mod b) for odd b only */
int32 pstm_invmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c)
{
	pstm_int	x, y, u, v, B, D;
	int32		res;
	uint16		neg, sanity;

	/* 2. [modified] b must be odd   */
	if (pstm_iseven (b) == 1) {
		return pstm_invmod_slow(pool, a,b,c);
	}

	/* x == modulus, y == value to invert */
	if ((res = pstm_init_copy(pool, &x, b, 0)) != PSTM_OKAY) {
		return res;
	}

	if ((res = pstm_init_size(pool, &y, a->alloc)) != PSTM_OKAY) {
		goto LBL_X;
	}

	/* we need y = |a| */
	pstm_abs(a, &y);

	/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
	if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) {
		goto LBL_Y;
	}
	if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) {
		goto LBL_U;
	}
	if ((res = pstm_init(pool, &B)) != PSTM_OKAY) {
		goto LBL_V;
	}
	if ((res = pstm_init(pool, &D)) != PSTM_OKAY) {
		goto LBL_B;
	}

	pstm_set (&D, 1);

	sanity = 0;
top:
	/* 4.  while u is even do */
	while (pstm_iseven (&u) == 1) {
		/* 4.1 u = u/2 */
		if ((res = pstm_div_2 (&u, &u)) != PSTM_OKAY) {
			goto LBL_D;
		}

		/* 4.2 if B is odd then */
		if (pstm_isodd (&B) == 1) {
			if ((res = pstm_sub (&B, &x, &B)) != PSTM_OKAY) {
				goto LBL_D;
			}
		}
		/* B = B/2 */
		if ((res = pstm_div_2 (&B, &B)) !=  PSTM_OKAY) {
			goto LBL_D;
		}
	}

	/* 5.  while v is even do */
	while (pstm_iseven (&v) == 1) {
		/* 5.1 v = v/2 */
		if ((res = pstm_div_2 (&v, &v)) != PSTM_OKAY) {
			goto LBL_D;
		}
		/* 5.2 if D is odd then */
		if (pstm_isodd (&D) == 1) {
			/* D = (D-x)/2 */
			if ((res = pstm_sub (&D, &x, &D)) != PSTM_OKAY) {
				goto LBL_D;
			}
		}
		/* D = D/2 */
		if ((res = pstm_div_2 (&D, &D)) !=  PSTM_OKAY) {
			goto LBL_D;
		}
	}

	/* 6.  if u >= v then */
	if (pstm_cmp (&u, &v) != PSTM_LT) {
		/* u = u - v, B = B - D */
		if ((res = pstm_sub (&u, &v, &u)) != PSTM_OKAY) {
				goto LBL_D;
		}
		if ((res = pstm_sub (&B, &D, &B)) != PSTM_OKAY) {
				goto LBL_D;
		}
	} else {
		/* v - v - u, D = D - B */
		if ((res = pstm_sub (&v, &u, &v)) != PSTM_OKAY) {
				goto LBL_D;
		}
		if ((res = pstm_sub (&D, &B, &D)) != PSTM_OKAY) {
				goto LBL_D;
		}
	}

	/* if not zero goto step 4 */
	if (sanity++ > 1000) {
		res = PS_LIMIT_FAIL;
		goto LBL_D;
	}
	if (pstm_iszero (&u) == 0) {
		goto top;
	}

	/* now a = C, b = D, gcd == g*v */

	/* if v != 1 then there is no inverse */
	if (pstm_cmp_d (&v, 1) != PSTM_EQ) {
		res = PS_FAILURE;
		goto LBL_D;
	}

	/* b is now the inverse */
	neg = a->sign;
	while (D.sign == PSTM_NEG) {
		if ((res = pstm_add (&D, b, &D)) != PSTM_OKAY) {
			goto LBL_D;
		}
	}
	if ((res = pstm_copy (&D, c)) != PSTM_OKAY) {
		goto LBL_D;
	}
	c->sign = neg;
	res = PSTM_OKAY;

LBL_D: pstm_clear(&D);
LBL_B: pstm_clear(&B);
LBL_V: pstm_clear(&v);
LBL_U: pstm_clear(&u);
LBL_Y: pstm_clear(&y);
LBL_X: pstm_clear(&x);
	return res;
}
#endif /* !DISABLE_PSTM */
/******************************************************************************/
