diff -r 000000000000 -r 6474c204b198 security/nss/lib/freebl/mpi/montmulf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/security/nss/lib/freebl/mpi/montmulf.c Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,295 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef SOLARIS +#define RF_INLINE_MACROS 1 +#endif + +static const double TwoTo16=65536.0; +static const double TwoToMinus16=1.0/65536.0; +static const double Zero=0.0; +static const double TwoTo32=65536.0*65536.0; +static const double TwoToMinus32=1.0/(65536.0*65536.0); + +#ifdef RF_INLINE_MACROS + +double upper32(double); +double lower32(double, double); +double mod(double, double, double); + +void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/, + const double * /* 2^16*/, + const double * /* 0 */, + double * /*result16*/, + double * /* result32 */, + float * /*source - should be unsigned int* + converted to float* */); + +#else +#ifdef MP_USE_FLOOR +#include +#else +#define floor(d) ((double)((unsigned long long)(d))) +#endif + +static double upper32(double x) +{ + return floor(x*TwoToMinus32); +} + +static double lower32(double x, double y) +{ + return x-TwoTo32*floor(x*TwoToMinus32); +} + +static double mod(double x, double oneoverm, double m) +{ + return x-m*floor(x*oneoverm); +} + +#endif + + +static void cleanup(double *dt, int from, int tlen) +{ + int i; + double tmp,tmp1,x,x1; + + tmp=tmp1=Zero; + /* original code ** + for(i=2*from;i<2*tlen-2;i++) + { + x=dt[i]; + dt[i]=lower32(x,Zero)+tmp1; + tmp1=tmp; + tmp=upper32(x); + } + dt[tlen-2]+=tmp1; + dt[tlen-1]+=tmp; + **end original code ***/ + /* new code ***/ + for(i=2*from;i<2*tlen;i+=2) + { + x=dt[i]; + x1=dt[i+1]; + dt[i]=lower32(x,Zero)+tmp; + dt[i+1]=lower32(x1,Zero)+tmp1; + tmp=upper32(x); + tmp1=upper32(x1); + } + /** end new code **/ +} + + +void conv_d16_to_i32(unsigned int *i32, double *d16, long long *tmp, int ilen) +{ +int i; +long long t, t1, a, b, c, d; + + t1=0; + a=(long long)d16[0]; + b=(long long)d16[1]; + for(i=0; i>32); + d=(long long)d16[2*i+3]; + t1+=(b&0xffff)<<16; + t+=(b>>16)+(t1>>32); + i32[i]=(unsigned int)t1; + t1=t; + a=c; + b=d; + } + t1+=(unsigned int)a; + t=(a>>32); + t1+=(b&0xffff)<<16; + i32[i]=(unsigned int)t1; +} + +void conv_i32_to_d32(double *d32, unsigned int *i32, int len) +{ +int i; + +#pragma pipeloop(0) + for(i=0;i>16); + } +} + + +void conv_i32_to_d32_and_d16(double *d32, double *d16, + unsigned int *i32, int len) +{ +int i = 0; +unsigned int a; + +#pragma pipeloop(0) +#ifdef RF_INLINE_MACROS + for(;i>16); + } +} + + +void adjust_montf_result(unsigned int *i32, unsigned int *nint, int len) +{ +long long acc; +int i; + + if(i32[len]>0) i=-1; + else + { + for(i=len-1; i>=0; i--) + { + if(i32[i]!=nint[i]) break; + } + } + if((i<0)||(i32[i]>nint[i])) + { + acc=0; + for(i=0;i>32; + } + } +} + + + + +/* +** the lengths of the input arrays should be at least the following: +** result[nlen+1], dm1[nlen], dm2[2*nlen+1], dt[4*nlen+2], dn[nlen], nint[nlen] +** all of them should be different from one another +** +*/ +void mont_mulf_noconv(unsigned int *result, + double *dm1, double *dm2, double *dt, + double *dn, unsigned int *nint, + int nlen, double dn0) +{ + int i, j, jj; + int tmp; + double digit, m2j, nextm2j, a, b; + double *dptmp, *pdm1, *pdm2, *pdn, *pdtj, pdn_0, pdm1_0; + + pdm1=&(dm1[0]); + pdm2=&(dm2[0]); + pdn=&(dn[0]); + pdm2[2*nlen]=Zero; + + if (nlen!=16) + { + for(i=0;i<4*nlen+2;i++) dt[i]=Zero; + + a=dt[0]=pdm1[0]*pdm2[0]; + digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16); + + pdtj=&(dt[0]); + for(j=jj=0;j<2*nlen;j++,jj++,pdtj++) + { + m2j=pdm2[j]; + a=pdtj[0]+pdn[0]*digit; + b=pdtj[1]+pdm1[0]*pdm2[j+1]+a*TwoToMinus16; + pdtj[1]=b; + +#pragma pipeloop(0) + for(i=1;i