Support for "multiply high" instruction, see BN_UMULT_HIGH comment in
[openssl.git] / crypto / bn / bn_exp.c
index 44f47e7eb20e89264676949fe62f155236da8156..2df1614ada17047acfcf0affab26d39169903a0c 100644 (file)
 #define TABLE_SIZE     16
 
 /* slow but works */
-int BN_mod_mul(ret, a, b, m, ctx)
-BIGNUM *ret;
-BIGNUM *a;
-BIGNUM *b;
-BIGNUM *m;
-BN_CTX *ctx;
+int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
        {
        BIGNUM *t;
        int r=0;
@@ -91,9 +86,7 @@ err:
 
 #if 0
 /* this one works - simple but works */
-int BN_mod_exp(r,a,p,m,ctx)
-BIGNUM *r,*a,*p,*m;
-BN_CTX *ctx;
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
        {
        int i,bits,ret=0;
        BIGNUM *v,*tmp;
@@ -106,7 +99,7 @@ BN_CTX *ctx;
 
        if (BN_is_odd(p))
                { if (BN_copy(r,a) == NULL) goto err; }
-       else    { if (BN_one(r)) goto err; }
+       else    { if (!BN_one(r)) goto err; }
 
        for (i=1; i<bits; i++)
                {
@@ -127,43 +120,42 @@ err:
 #endif
 
 /* this one works - simple but works */
-int BN_exp(r,a,p,ctx)
-BIGNUM *r,*a,*p;
-BN_CTX *ctx;
+int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
        {
-       int i,bits,ret=0;
-       BIGNUM *v,*tmp;
+       int i,bits,ret=0,tos;
+       BIGNUM *v,*rr;
 
+       tos=ctx->tos;
        v= &(ctx->bn[ctx->tos++]);
-       tmp= &(ctx->bn[ctx->tos++]);
+       if ((r == a) || (r == p))
+               rr= &(ctx->bn[ctx->tos++]);
+       else
+               rr=r;
 
        if (BN_copy(v,a) == NULL) goto err;
        bits=BN_num_bits(p);
 
        if (BN_is_odd(p))
-               { if (BN_copy(r,a) == NULL) goto err; }
-       else    { if (BN_one(r)) goto err; }
+               { if (BN_copy(rr,a) == NULL) goto err; }
+       else    { if (!BN_one(rr)) goto err; }
 
        for (i=1; i<bits; i++)
                {
-               if (!BN_sqr(tmp,v,ctx)) goto err;
+               if (!BN_sqr(v,v,ctx)) goto err;
                if (BN_is_bit_set(p,i))
                        {
-                       if (!BN_mul(tmp,r,v,ctx)) goto err;
+                       if (!BN_mul(rr,rr,v,ctx)) goto err;
                        }
                }
        ret=1;
 err:
-       ctx->tos-=2;
+       ctx->tos=tos;
+       if (r != rr) BN_copy(r,rr);
        return(ret);
        }
 
-int BN_mod_exp(r,a,p,m,ctx)
-BIGNUM *r;
-BIGNUM *a;
-BIGNUM *p;
-BIGNUM *m;
-BN_CTX *ctx;
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+              BN_CTX *ctx)
        {
        int ret;
 
@@ -192,12 +184,8 @@ BN_CTX *ctx;
        }
 
 /* #ifdef RECP_MUL_MOD */
-int BN_mod_exp_recp(r,a,p,m,ctx)
-BIGNUM *r;
-BIGNUM *a;
-BIGNUM *p;
-BIGNUM *m;
-BN_CTX *ctx;
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                   const BIGNUM *m, BN_CTX *ctx)
        {
        int i,j,bits,ret=0,wstart,wend,window,wvalue;
        int start=1,ts=0;
@@ -310,17 +298,13 @@ err:
 /* #endif */
 
 /* #ifdef MONT_MUL_MOD */
-int BN_mod_exp_mont(rr,a,p,m,ctx,in_mont)
-BIGNUM *rr;
-BIGNUM *a;
-BIGNUM *p;
-BIGNUM *m;
-BN_CTX *ctx;
-BN_MONT_CTX *in_mont;
+int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
+                   const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
        {
        int i,j,bits,ret=0,wstart,wend,window,wvalue;
        int start=1,ts=0;
-       BIGNUM *d,*aa,*r;
+       BIGNUM *d,*r;
+       BIGNUM *aa;
        BIGNUM val[TABLE_SIZE];
        BN_MONT_CTX *mont=NULL;
 
@@ -456,12 +440,8 @@ err:
 /* #endif */
 
 /* The old fallback, simple version :-) */
-int BN_mod_exp_simple(r,a,p,m,ctx)
-BIGNUM *r;
-BIGNUM *a;
-BIGNUM *p;
-BIGNUM *m;
-BN_CTX *ctx;
+int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
+            BN_CTX *ctx)
        {
        int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
        int start=1;