| Index: openssl/crypto/bn/bn_mont.c
|
| ===================================================================
|
| --- openssl/crypto/bn/bn_mont.c (revision 105093)
|
| +++ openssl/crypto/bn/bn_mont.c (working copy)
|
| @@ -122,26 +122,10 @@
|
|
|
| #define MONT_WORD /* use the faster word-based algorithm */
|
|
|
| -#if defined(MONT_WORD) && defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
|
| -/* This condition means we have a specific non-default build:
|
| - * In the 0.9.8 branch, OPENSSL_BN_ASM_MONT is normally not set for any
|
| - * BN_BITS2<=32 platform; an explicit "enable-montasm" is required.
|
| - * I.e., if we are here, the user intentionally deviates from the
|
| - * normal stable build to get better Montgomery performance from
|
| - * the 0.9.9-dev backport.
|
| - *
|
| - * In this case only, we also enable BN_from_montgomery_word()
|
| - * (another non-stable feature from 0.9.9-dev).
|
| - */
|
| -#define MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
|
| -#endif
|
| -
|
| -#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
|
| +#ifdef MONT_WORD
|
| static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
|
| #endif
|
|
|
| -
|
| -
|
| int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
| BN_MONT_CTX *mont, BN_CTX *ctx)
|
| {
|
| @@ -153,11 +137,7 @@
|
| if (num>1 && a->top==num && b->top==num)
|
| {
|
| if (bn_wexpand(r,num) == NULL) return(0);
|
| -#if 0 /* for OpenSSL 0.9.9 mont->n0 */
|
| if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num))
|
| -#else
|
| - if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,&mont->n0,num))
|
| -#endif
|
| {
|
| r->neg = a->neg^b->neg;
|
| r->top = num;
|
| @@ -181,7 +161,7 @@
|
| if (!BN_mul(tmp,a,b,ctx)) goto err;
|
| }
|
| /* reduce from aRR to aR */
|
| -#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
|
| +#ifdef MONT_WORD
|
| if (!BN_from_montgomery_word(r,tmp,mont)) goto err;
|
| #else
|
| if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
|
| @@ -193,7 +173,7 @@
|
| return(ret);
|
| }
|
|
|
| -#ifdef MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD
|
| +#ifdef MONT_WORD
|
| static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
| {
|
| BIGNUM *n;
|
| @@ -217,15 +197,15 @@
|
| 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;
|
| -#if 0 /* for OpenSSL 0.9.9 mont->n0 */
|
| n0=mont->n0[0];
|
| -#else
|
| - n0=mont->n0;
|
| -#endif
|
|
|
| #ifdef BN_COUNT
|
| fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
|
| @@ -270,6 +250,8 @@
|
| }
|
| al=r->top-ri;
|
|
|
| +#define BRANCH_FREE 1
|
| +#if BRANCH_FREE
|
| if (bn_wexpand(ret,ri) == NULL) return(0);
|
| x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
|
| ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */
|
| @@ -295,7 +277,7 @@
|
| m1|=m2; /* (al!=ri) */
|
| m1|=(0-(size_t)v); /* (al!=ri || v) */
|
| m1&=~m2; /* (al!=ri || v) && !al>ri */
|
| - nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
|
| + nrp=(BN_ULONG *)(((PTR_SIZE_INT)rp&~m1)|((PTR_SIZE_INT)ap&m1));
|
| }
|
|
|
| /* 'i<ri' is chosen to eliminate dependency on input data, even
|
| @@ -317,164 +299,8 @@
|
| rp[i]=nrp[i], ap[i]=0;
|
| bn_correct_top(r);
|
| bn_correct_top(ret);
|
| - bn_check_top(ret);
|
| -
|
| - return(1);
|
| - }
|
| -
|
| -int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
| - BN_CTX *ctx)
|
| - {
|
| - int retn=0;
|
| - BIGNUM *t;
|
| -
|
| - BN_CTX_start(ctx);
|
| - if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
|
| - retn = BN_from_montgomery_word(ret,t,mont);
|
| - BN_CTX_end(ctx);
|
| - return retn;
|
| - }
|
| -
|
| -#else /* !MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
|
| -
|
| -int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
| - BN_CTX *ctx)
|
| - {
|
| - int retn=0;
|
| -
|
| -#ifdef MONT_WORD
|
| - BIGNUM *n,*r;
|
| - BN_ULONG *ap,*np,*rp,n0,v,*nrp;
|
| - int al,nl,max,i,x,ri;
|
| -
|
| - BN_CTX_start(ctx);
|
| - if ((r = BN_CTX_get(ctx)) == NULL) goto err;
|
| -
|
| - if (!BN_copy(r,a)) goto err;
|
| - n= &(mont->N);
|
| -
|
| - ap=a->d;
|
| - /* mont->ri is the size of mont->N in bits (rounded up
|
| - to the word size) */
|
| - 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 err;
|
| -
|
| - 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_COUNT
|
| - 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)
|
| - 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_correct_top(r);
|
| -
|
| - /* mont->ri will be a multiple of the word size and below code
|
| - * is kind of BN_rshift(ret,r,mont->ri) equivalent */
|
| - if (r->top <= ri)
|
| - {
|
| - ret->top=0;
|
| - retn=1;
|
| - goto err;
|
| - }
|
| - al=r->top-ri;
|
| -
|
| -# define BRANCH_FREE 1
|
| -# if BRANCH_FREE
|
| - if (bn_wexpand(ret,ri) == NULL) goto err;
|
| - x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
|
| - ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */
|
| - ret->neg=r->neg;
|
| -
|
| - rp=ret->d;
|
| - ap=&(r->d[ri]);
|
| -
|
| - {
|
| - size_t m1,m2;
|
| -
|
| - v=bn_sub_words(rp,ap,np,ri);
|
| - /* this ----------------^^ works even in al<ri case
|
| - * thanks to zealous zeroing of top of the vector in the
|
| - * beginning. */
|
| -
|
| - /* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
|
| - /* in other words if subtraction result is real, then
|
| - * trick unconditional memcpy below to perform in-place
|
| - * "refresh" instead of actual copy. */
|
| - m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1); /* al<ri */
|
| - m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1); /* al>ri */
|
| - m1|=m2; /* (al!=ri) */
|
| - m1|=(0-(size_t)v); /* (al!=ri || v) */
|
| - m1&=~m2; /* (al!=ri || v) && !al>ri */
|
| - nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
|
| - }
|
| -
|
| - /* 'i<ri' is chosen to eliminate dependency on input data, even
|
| - * though it results in redundant copy in al<ri case. */
|
| - for (i=0,ri-=4; i<ri; i+=4)
|
| - {
|
| - BN_ULONG t1,t2,t3,t4;
|
| -
|
| - t1=nrp[i+0];
|
| - t2=nrp[i+1];
|
| - t3=nrp[i+2]; ap[i+0]=0;
|
| - t4=nrp[i+3]; ap[i+1]=0;
|
| - rp[i+0]=t1; ap[i+2]=0;
|
| - rp[i+1]=t2; ap[i+3]=0;
|
| - rp[i+2]=t3;
|
| - rp[i+3]=t4;
|
| - }
|
| - for (ri+=4; i<ri; i++)
|
| - rp[i]=nrp[i], ap[i]=0;
|
| - bn_correct_top(r);
|
| - bn_correct_top(ret);
|
| -# else
|
| - if (bn_wexpand(ret,al) == NULL) goto err;
|
| + if (bn_wexpand(ret,al) == NULL) return(0);
|
| ret->top=al;
|
| ret->neg=r->neg;
|
|
|
| @@ -497,8 +323,30 @@
|
| al+=4;
|
| for (; i<al; i++)
|
| rp[i]=ap[i];
|
| -# endif
|
| -#else /* !MONT_WORD */
|
| +
|
| + if (BN_ucmp(ret, &(mont->N)) >= 0)
|
| + {
|
| + if (!BN_usub(ret,ret,&(mont->N))) return(0);
|
| + }
|
| +#endif
|
| + bn_check_top(ret);
|
| +
|
| + return(1);
|
| + }
|
| +#endif /* MONT_WORD */
|
| +
|
| +int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
| + BN_CTX *ctx)
|
| + {
|
| + int retn=0;
|
| +#ifdef MONT_WORD
|
| + BIGNUM *t;
|
| +
|
| + BN_CTX_start(ctx);
|
| + if ((t = BN_CTX_get(ctx)) && BN_copy(t,a))
|
| + retn = BN_from_montgomery_word(ret,t,mont);
|
| + BN_CTX_end(ctx);
|
| +#else /* !MONT_WORD */
|
| BIGNUM *t1,*t2;
|
|
|
| BN_CTX_start(ctx);
|
| @@ -515,21 +363,18 @@
|
| if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
|
| if (!BN_add(t2,a,t1)) goto err;
|
| if (!BN_rshift(ret,t2,mont->ri)) goto err;
|
| -#endif /* MONT_WORD */
|
|
|
| -#if !defined(BRANCH_FREE) || BRANCH_FREE==0
|
| if (BN_ucmp(ret, &(mont->N)) >= 0)
|
| {
|
| if (!BN_usub(ret,ret,&(mont->N))) goto err;
|
| }
|
| -#endif
|
| retn=1;
|
| bn_check_top(ret);
|
| err:
|
| BN_CTX_end(ctx);
|
| +#endif /* MONT_WORD */
|
| return(retn);
|
| }
|
| -#endif /* MONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD */
|
|
|
| BN_MONT_CTX *BN_MONT_CTX_new(void)
|
| {
|
| @@ -549,11 +394,7 @@
|
| BN_init(&(ctx->RR));
|
| BN_init(&(ctx->N));
|
| BN_init(&(ctx->Ni));
|
| -#if 0 /* for OpenSSL 0.9.9 mont->n0 */
|
| ctx->n0[0] = ctx->n0[1] = 0;
|
| -#else
|
| - ctx->n0 = 0;
|
| -#endif
|
| ctx->flags=0;
|
| }
|
|
|
| @@ -585,26 +426,22 @@
|
| BIGNUM tmod;
|
| BN_ULONG buf[2];
|
|
|
| - mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
|
| - BN_zero(R);
|
| -#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)",
|
| - only certain BN_BITS2<=32 platforms actually need this */
|
| - if (!(BN_set_bit(R,2*BN_BITS2))) goto err; /* R */
|
| -#else
|
| - if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */
|
| -#endif
|
| -
|
| - buf[0]=mod->d[0]; /* tmod = N mod word size */
|
| - buf[1]=0;
|
| -
|
| BN_init(&tmod);
|
| tmod.d=buf;
|
| - tmod.top = buf[0] != 0 ? 1 : 0;
|
| tmod.dmax=2;
|
| tmod.neg=0;
|
|
|
| -#if 0 /* for OpenSSL 0.9.9 mont->n0, would be "#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)";
|
| - only certain BN_BITS2<=32 platforms actually need this */
|
| + mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
|
| +
|
| +#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
|
| + /* Only certain BN_BITS2<=32 platforms actually make use of
|
| + * n0[1], and we could use the #else case (with a shorter R
|
| + * value) for the others. However, currently only the assembler
|
| + * files do know which is which. */
|
| +
|
| + BN_zero(R);
|
| + if (!(BN_set_bit(R,2*BN_BITS2))) goto err;
|
| +
|
| tmod.top=0;
|
| if ((buf[0] = mod->d[0])) tmod.top=1;
|
| if ((buf[1] = mod->top>1 ? mod->d[1] : 0)) tmod.top=2;
|
| @@ -632,6 +469,12 @@
|
| mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
|
| mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
|
| #else
|
| + BN_zero(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.top = buf[0] != 0 ? 1 : 0;
|
| /* Ri = R^-1 mod N*/
|
| if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
|
| goto err;
|
| @@ -647,12 +490,8 @@
|
| if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
|
| /* Ni = (R*Ri-1)/N,
|
| * keep only least significant word: */
|
| -# if 0 /* for OpenSSL 0.9.9 mont->n0 */
|
| mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
|
| mont->n0[1] = 0;
|
| -# else
|
| - mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
|
| -# endif
|
| #endif
|
| }
|
| #else /* !MONT_WORD */
|
| @@ -689,12 +528,8 @@
|
| if (!BN_copy(&(to->N),&(from->N))) return NULL;
|
| if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
|
| to->ri=from->ri;
|
| -#if 0 /* for OpenSSL 0.9.9 mont->n0 */
|
| to->n0[0]=from->n0[0];
|
| to->n0[1]=from->n0[1];
|
| -#else
|
| - to->n0=from->n0;
|
| -#endif
|
| return(to);
|
| }
|
|
|
|
|