#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 0
- 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->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_CTX_end(ctx);
- return(1);
+ ret=1;
err:
- return(0);
+ 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)
#if 0
BN_rshift(ret,r,mont->ri);
#else
+ ret->neg = r->neg;
x=ri;
rp=ret->d;
ap= &(r->d[x]);
if (BN_ucmp(ret, &(mont->N)) >= 0)
{
- BN_usub(ret,ret,&(mont->N));
+ if (!BN_usub(ret,ret,&(mont->N))) goto err;
}
retn=1;
err:
{
BN_MONT_CTX *ret;
- if ((ret=(BN_MONT_CTX *)Malloc(sizeof(BN_MONT_CTX))) == NULL)
+ if ((ret=(BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
return(NULL);
BN_MONT_CTX_init(ret);
BN_free(&(mont->N));
BN_free(&(mont->Ni));
if (mont->flags & BN_FLG_MALLOCED)
- Free(mont);
+ OPENSSL_free(mont);
}
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
BN_init(&Ri);
R= &(mont->RR); /* grab RR as a temp */
BN_copy(&(mont->N),mod); /* Set N */
+ mont->N.neg = 0;
#ifdef MONT_WORD
{
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)
goto err;
- BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */
+ if (!BN_lshift(&Ri,&Ri,BN_BITS2)) goto err; /* R*Ri */
if (!BN_is_zero(&Ri))
- BN_sub_word(&Ri,1);
+ {
+ 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];
+ {
+ 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;
BN_free(&Ri);
}
#else /* !MONT_WORD */
{ /* bignum version */
- mont->ri=BN_num_bits(mod);
- 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)
+ mont->ri=BN_num_bits(&mont->N);
+ if (!BN_zero(R)) goto err;
+ 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);
+ if (!BN_div(&(mont->Ni),NULL,&Ri,&mont->N,ctx)) goto err;
BN_free(&Ri);
}
#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_zero(&(mont->RR))) goto err;
+ 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);
err: