X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbn%2Fbn_mont.c;h=3a087fdce9ee8a5ffd16758146adf9ebedbc54b9;hp=61416483cb26761b113935857fc677a5081eac4d;hb=9b4eab501a52c8bdc19a8a002e1f9d4d7ad6f4c4;hpb=a0e7c8eede26b29b09057f48b8e51f46f8811ddd diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c index 61416483cb..3a087fdce9 100644 --- a/crypto/bn/bn_mont.c +++ b/crypto/bn/bn_mont.c @@ -69,11 +69,30 @@ #define MONT_WORD /* use the faster word-based algorithm */ +#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) { BIGNUM *tmp; int ret=0; +#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) + int num = mont->N.top; + + if (num>1 && a->top==num && b->top==num) + { + if (bn_wexpand(r,num) == NULL) return(0); + if (bn_mul_mont(r->d,a->d,b->d,mont->N.d,mont->n0,num)) + { + r->neg = a->neg^b->neg; + r->top = num; + bn_correct_top(r); + return(1); + } + } +#endif BN_CTX_start(ctx); tmp = BN_CTX_get(ctx); @@ -89,7 +108,11 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (!BN_mul(tmp,a,b,ctx)) goto err; } /* reduce from aRR to aR */ +#ifdef MONT_WORD + if (!BN_from_montgomery_word(r,tmp,mont)) goto err; +#else if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; +#endif bn_check_top(r); ret=1; err: @@ -97,35 +120,25 @@ err: return(ret); } -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; +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) + { + BIGNUM *n; 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); } + if ((al == 0) || (nl == 0)) { ret->top=0; return(1); } max=(nl+al+1); /* allow for overflow (no?) XXX */ - if (bn_wexpand(r,max) == NULL) goto err; - if (bn_wexpand(ret,max) == NULL) goto err; + if (bn_wexpand(r,max) == NULL) return(0); - r->neg=a->neg^n->neg; + r->neg^=n->neg; np=n->d; rp=r->d; nrp= &(r->d[nl]); @@ -142,7 +155,7 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, n0=mont->n0; #ifdef BN_COUNT - fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl); + fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl); #endif for (i=0; iri); #else - ret->neg = r->neg; - x=ri; - rp=ret->d; - ap= &(r->d[x]); - if (r->top < x) - al=0; - else - al=r->top-x; + if (r->top < ri) + { + ret->top=0; + return(1); + } + al=r->top-ri; + if (bn_wexpand(ret,al) == NULL) return(0); + ret->neg=r->neg; ret->top=al; + + rp=ret->d; + ap=&(r->d[ri]); al-=4; for (i=0; iN)) >= 0) + { + if (!BN_usub(ret,ret,&(mont->N))) return(0); + } + 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); @@ -223,7 +261,6 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, 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 (BN_ucmp(ret, &(mont->N)) >= 0) { @@ -233,6 +270,7 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, bn_check_top(ret); err: BN_CTX_end(ctx); +#endif /* MONT_WORD */ return(retn); } @@ -292,7 +330,7 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) buf[0]=mod->d[0]; /* tmod = N mod word size */ buf[1]=0; tmod.d=buf; - tmod.top=1; + tmod.top = buf[0] != 0 ? 1 : 0; tmod.dmax=2; tmod.neg=0; /* Ri = R^-1 mod N*/ @@ -350,3 +388,21 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) return(to); } +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx) + { + if (*pmont) + return *pmont; + CRYPTO_w_lock(lock); + if (!*pmont) + { + *pmont = BN_MONT_CTX_new(); + if (*pmont && !BN_MONT_CTX_set(*pmont, mod, ctx)) + { + BN_MONT_CTX_free(*pmont); + *pmont = NULL; + } + } + CRYPTO_w_unlock(lock); + return *pmont; + }