if (a->top == 1 && !a->neg)
if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) == 0))
int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,	       BN_CTX *ctx)	{	int ret;	bn_check_top(a);	bn_check_top(p);	bn_check_top(m);	/* For even modulus  m = 2^k*m_odd,  it might make sense to compute	 * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery	 * exponentiation for the odd part), using appropriate exponent	 * reductions, and combine the results using the CRT.	 *	 * For now, we use Montgomery only if the modulus is odd; otherwise,	 * exponentiation using the reciprocal-based quick remaindering	 * algorithm is used.	 *	 * (Timing obtained with expspeed.c [computations  a^p mod m	 * where  a, p, m  are of the same length: 256, 512, 1024, 2048,	 * 4096, 8192 bits], compared to the running time of the	 * standard algorithm:	 *	 *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]         *                     55 .. 77 %  [UltraSparc processor, but	 *                                  debug-solaris-sparcv8-gcc conf.]	 * 	 *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]	 *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]	 *	 * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont	 * at 2048 and more bits, but at 512 and 1024 bits, it was	 * slower even than the standard algorithm!	 *	 * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]	 * should be obtained when the new Montgomery reduction code	 * has been integrated into OpenSSL.)	 */#define MONT_MUL_MOD#define MONT_EXP_WORD#define RECP_MUL_MOD#ifdef MONT_MUL_MOD	/* I have finally been able to take out this pre-condition of	 * the top bit being set.  It was caused by an error in BN_div	 * with negatives.  There was also another problem when for a^b%m	 * a >= m.  eay 07-May-97 *//*	if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */	if (BN_is_odd(m))		{#  ifdef MONT_EXP_WORD		if (a->top == 1 && !a->neg)			{			BN_ULONG A = a->d[0];			ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);			}		else#  endif			ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);		}	else#endif#ifdef RECP_MUL_MOD		{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }#else		{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }#endif	bn_check_top(r);	return(ret);	}