#define MONT_WORD /* use the faster word-based algorithm */
-int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_MONT_CTX *mont, BN_CTX *ctx)
{
- BIGNUM *tmp,*tmp2;
+ BIGNUM *tmp;
int ret=0;
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
- tmp2 = BN_CTX_get(ctx);
- if (tmp == NULL || tmp2 == NULL) goto err;
+ if (tmp == 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
{
}
/* reduce from aRR to aR */
if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
+ bn_check_top(r);
ret=1;
err:
BN_CTX_end(ctx);
return(ret);
}
-int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
+int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
BN_CTX *ctx)
{
int retn=0;
n0=mont->n0;
#ifdef BN_COUNT
- printf("word BN_from_montgomery %d * %d\n",nl,nl);
+ fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl);
#endif
for (i=0; i<nl; i++)
{
+#ifdef __TANDEM
+ {
+ long long t1;
+ long long t2;
+ long long t3;
+ t1 = rp[0] * (n0 & 0177777);
+ t2 = 037777600000l;
+ t2 = n0 & t2;
+ t3 = rp[0] & 0177777;
+ t2 = (t3 * t2) & BN_MASK2;
+ t1 = t1 + t2;
+ v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
+ }
+#else
v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+#endif
nrp++;
rp++;
if (((nrp[-1]+=v)&BN_MASK2) >= v)
for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
}
}
- bn_fix_top(r);
+ bn_correct_top(r);
/* mont->ri will be a multiple of the word size */
#if 0
BN_rshift(ret,r,mont->ri);
#else
+ ret->neg = r->neg;
x=ri;
rp=ret->d;
ap= &(r->d[x]);
if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
if (!BN_add(t2,a,t1)) goto err;
- BN_rshift(ret,t2,mont->ri);
+ if (!BN_rshift(ret,t2,mont->ri)) goto err;
#endif /* MONT_WORD */
if (BN_ucmp(ret, &(mont->N)) >= 0)
{
- BN_usub(ret,ret,&(mont->N));
+ if (!BN_usub(ret,ret,&(mont->N))) goto err;
}
retn=1;
+ bn_check_top(ret);
err:
BN_CTX_end(ctx);
return(retn);
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
{
- BIGNUM Ri,*R;
+ int ret = 0;
+ BIGNUM *Ri,*R;
- BN_init(&Ri);
+ BN_CTX_start(ctx);
+ if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
R= &(mont->RR); /* grab RR as a temp */
- BN_copy(&(mont->N),mod); /* Set N */
+ if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */
+ mont->N.neg = 0;
#ifdef MONT_WORD
{
mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
BN_zero(R);
- BN_set_bit(R,BN_BITS2); /* R */
+ if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */
buf[0]=mod->d[0]; /* tmod = N mod word size */
buf[1]=0;
tmod.d=buf;
tmod.top=1;
- tmod.max=2;
- tmod.neg=mod->neg;
+ tmod.dmax=2;
+ tmod.neg=0;
/* Ri = R^-1 mod N*/
- if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
+ if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
goto err;
- BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */
- if (!BN_is_zero(&Ri))
- BN_sub_word(&Ri,1);
+ if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
+ if (!BN_is_zero(Ri))
+ {
+ if (!BN_sub_word(Ri,1)) goto err;
+ }
else /* if N mod word size == 1 */
- BN_set_word(&Ri,BN_MASK2); /* Ri-- (mod word size) */
- BN_div(&Ri,NULL,&Ri,&tmod,ctx); /* Ni = (R*Ri-1)/N,
- * keep only least significant word: */
- mont->n0=Ri.d[0];
- BN_free(&Ri);
+ {
+ if (!BN_set_word(Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */
+ }
+ if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
+ /* Ni = (R*Ri-1)/N,
+ * keep only least significant word: */
+ mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
}
#else /* !MONT_WORD */
{ /* bignum version */
- mont->ri=BN_num_bits(mod);
+ mont->ri=BN_num_bits(&mont->N);
BN_zero(R);
- BN_set_bit(R,mont->ri); /* R = 2^ri */
- /* Ri = R^-1 mod N*/
- if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL)
+ if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */
+ /* Ri = R^-1 mod N*/
+ if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
goto err;
- BN_lshift(&Ri,&Ri,mont->ri); /* R*Ri */
- BN_sub_word(&Ri,1);
+ if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
+ if (!BN_sub_word(Ri,1)) goto err;
/* Ni = (R*Ri-1) / N */
- BN_div(&(mont->Ni),NULL,&Ri,mod,ctx);
- BN_free(&Ri);
+ if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
}
#endif
/* setup RR for conversions */
BN_zero(&(mont->RR));
- BN_set_bit(&(mont->RR),mont->ri*2);
- BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx);
+ if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
+ if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
- return(1);
+ ret = 1;
err:
- return(0);
+ BN_CTX_end(ctx);
+ return ret;
}
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
{
if (to == from) return(to);
- BN_copy(&(to->RR),&(from->RR));
- BN_copy(&(to->N),&(from->N));
- BN_copy(&(to->Ni),&(from->Ni));
+ if (!BN_copy(&(to->RR),&(from->RR))) return NULL;
+ if (!BN_copy(&(to->N),&(from->N))) return NULL;
+ if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
to->ri=from->ri;
to->n0=from->n0;
return(to);