j=bn_add_words(ret->d,ret->d,&(a->d[i]),i);
j=(int)(bn_add_words(ret->d,ret->d,&(a->d[i]),i));
int BN_from_montgomery(ret,a,mont,ctx)BIGNUM *ret;BIGNUM *a;BN_MONT_CTX *mont;BN_CTX *ctx;	{#ifdef BN_RECURSION	if (mont->use_word)#endif		{		BIGNUM *n,*r;		BN_ULONG *ap,*np,*rp,n0,v,*nrp;		int al,nl,max,i,x,ri;		int retn=0;		r= &(ctx->bn[ctx->tos]);		if (!BN_copy(r,a)) goto err1;		n= &(mont->N);		ap=a->d;		/* mont->ri is the size of mont->N in bits/words */		al=ri=mont->ri/BN_BITS2;		nl=n->top;		if ((al == 0) || (nl == 0)) { r->top=0; return(1); }		max=(nl+al+1); /* allow for overflow (no?) XXX */		if (bn_wexpand(r,max) == NULL) goto err1;		if (bn_wexpand(ret,max) == NULL) goto err1;		r->neg=a->neg^n->neg;		np=n->d;		rp=r->d;		nrp= &(r->d[nl]);		/* clear the top words of T */#if 1		for (i=r->top; i<max; i++) /* memset? XXX */			r->d[i]=0;#else		memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); #endif		r->top=max;		n0=mont->n0;#ifdef BN_COUNTprintf("word BN_from_montgomery %d * %d\n",nl,nl);#endif		for (i=0; i<nl; i++)			{			v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);			nrp++;			rp++;			if (((nrp[-1]+=v)&BN_MASK2) >= v)				continue;			else				{				if (((++nrp[0])&BN_MASK2) != 0) continue;				if (((++nrp[1])&BN_MASK2) != 0) continue;				for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;				}			}		bn_fix_top(r);		/* mont->ri will be a multiple of the word size */#if 0		BN_rshift(ret,r,mont->ri);#else		x=ri;		rp=ret->d;		ap= &(r->d[x]);		if (r->top < x)			al=0;		else			al=r->top-x;		ret->top=al;		al-=4;		for (i=0; i<al; i+=4)			{			BN_ULONG t1,t2,t3,t4;			t1=ap[i+0];			t2=ap[i+1];			t3=ap[i+2];			t4=ap[i+3];			rp[i+0]=t1;			rp[i+1]=t2;			rp[i+2]=t3;			rp[i+3]=t4;			}		al+=4;		for (; i<al; i++)			rp[i]=ap[i];#endif		if (BN_ucmp(ret, &(mont->N)) >= 0)			{			BN_usub(ret,ret,&(mont->N)); /* XXX */			}		retn=1;err1:		return(retn);		}#ifdef BN_RECURSION	else /* bignum version */ 		{		BIGNUM *t1,*t2,*t3;		int j,i;#ifdef BN_COUNTprintf("number BN_from_montgomery\n");#endif		t1= &(ctx->bn[ctx->tos]);		t2= &(ctx->bn[ctx->tos+1]);		t3= &(ctx->bn[ctx->tos+2]);		i=mont->Ni.top;		bn_wexpand(ret,i); /* perhaps only i*2 */		bn_wexpand(t1,i*4); /* perhaps only i*2 */		bn_wexpand(t2,i*2); /* perhaps only i   */		bn_mul_low_recursive(t2->d,a->d,mont->Ni.d,i,t1->d);		BN_zero(t3);		BN_set_bit(t3,mont->N.top*BN_BITS2);		bn_sub_words(t3->d,t3->d,a->d,i);		bn_mul_high(ret->d,t2->d,mont->N.d,t3->d,i,t1->d);		/* hmm... if a is between i and 2*i, things are bad */		if (a->top > i)			{			j=bn_add_words(ret->d,ret->d,&(a->d[i]),i);			if (j) /* overflow */				bn_sub_words(ret->d,ret->d,mont->N.d,i);			}		ret->top=i;		bn_fix_top(ret);		if (a->d[0])			BN_add_word(ret,1); /* Always? */		else	/* Very very rare */			{			for (i=1; i<mont->N.top-1; i++)				{				if (a->d[i])					{					BN_add_word(ret,1); /* Always? */					break;					}				}			}		if (BN_ucmp(ret,&(mont->N)) >= 0)			BN_usub(ret,ret,&(mont->N));		return(1);		}#endif	}