int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
			  BN_MONT_CTX *mont, BN_CTX *ctx)
	{
	BIGNUM *tmp,*tmp2;
	int ret=0;

	BN_CTX_start(ctx);
	tmp = BN_CTX_get(ctx);
	tmp2 = BN_CTX_get(ctx);
	if (tmp == NULL || tmp2 == NULL) goto err;

	bn_check_top(tmp);
	bn_check_top(tmp2);

	if (a == b)
		{
#if 1 
		bn_wexpand(tmp,a->top*2);
		bn_wexpand(tmp2,a->top*4);
		bn_sqr_recursive(tmp->d,a->d,a->top,tmp2->d);
		tmp->top=a->top*2;
		if (tmp->top > 0 && tmp->d[tmp->top-1] == 0)
			tmp->top--;
#else
		if (!BN_sqr(tmp,a,ctx)) goto err;
#endif
		}
	else
		{
		if (!BN_mul(tmp,a,b,ctx)) goto err;
		}
	/* reduce from aRR to aR */
	if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
	ret=1;
err:
	BN_CTX_end(ctx);
	return(ret);
	}