mp_modexp_cpu.cc
/* assumes a and b are 'montgomeritized' */
assumes a and b are 'montgomeritized'
assumes a and b are ' montgomeritized '
void mp_montmul_cpu(WORD *ret, const WORD *a, const WORD *b, 
		const WORD *n, const WORD *np)
{
	WORD t[MAX_S * 2];
	WORD m[MAX_S * 2];
	WORD mn[MAX_S * 2];
	WORD u[MAX_S];
	int c = 0;
	mp_mul_cpu(t, a, b);
	mp_mul_cpu(m, t, np);
	mp_mul_cpu(mn, m, n);
	c = mp_add_cpu(u, t + MAX_S, mn + MAX_S);
	bool half_zero = true;
	for (int i = 0; i < MAX_S; i++) {
		if (t[i])
			half_zero = false;
	}
	if (!half_zero)
		c |= mp_add1_cpu(u, u);
	if (c)	
		goto u_is_bigger;
	for (int i = MAX_S - 1; i >= 0; i--) {
		if (u[i] > n[i])
			goto u_is_bigger;
		if (u[i] < n[i])
			goto n_is_bigger;
	}
u_is_bigger:
	mp_sub_cpu(ret, u, n);
	return;
n_is_bigger:
	for (int i = 0; i < MAX_S; i++)
		ret[i] = u[i];
	return;
}
void mp_montmul_cpu ( WORD * ret , const WORD * a , const WORD * b , const WORD * n , const WORD * np ) { WORD t [ MAX_S * 2 ] ; WORD m [ MAX_S * 2 ] ; WORD mn [ MAX_S * 2 ] ; WORD u [ MAX_S ] ; int c = 0 ; mp_mul_cpu ( t , a , b ) ; mp_mul_cpu ( m , t , np ) ; mp_mul_cpu ( mn , m , n ) ; c = mp_add_cpu ( u , t + MAX_S , mn + MAX_S ) ; bool half_zero = true ; for ( int i = 0 ; i < MAX_S ; i ++ ) { if ( t [ i ] ) half_zero = false ; } if ( ! half_zero ) c |= mp_add1_cpu ( u , u ) ; if ( c ) goto u_is_bigger ; for ( int i = MAX_S - 1 ; i >= 0 ; i -- ) { if ( u [ i ] > n [ i ] ) goto u_is_bigger ; if ( u [ i ] < n [ i ] ) goto n_is_bigger ; } u_is_bigger : mp_sub_cpu ( ret , u , n ) ; return ; n_is_bigger : for ( int i = 0 ; i < MAX_S ; i ++ ) ret [ i ] = u [ i ] ; return ; }
assumes a and b are 'montgomeritized'
assumes a and b are ' montgomeritized '
// c may be 0 or 1, but not 2 /* Ugly, but practical. 
	 * Can we do this much better with Fermi's ballot()? */