summaryrefslogtreecommitdiff
path: root/crypto/bn/bn_mul.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2000-12-06 18:39:09 +0000
committerDr. Stephen Henson <steve@openssl.org>2000-12-06 18:39:09 +0000
commite0004e63a5ee478fff900b8cd0418851b6e9d8a4 (patch)
treec68b0010a03eab6e4afa48f183a95655bf4831ce /crypto/bn/bn_mul.c
parentf8a5c03cdf952c047f4f76ccb3d2cf12f4704a1b (diff)
downloadopenssl-new-BRANCH_ASN1.tar.gz
Merge from main trunk: lets see if this works ;-)BRANCH_ASN1
This involved the use of some temporary macros which handle the partial constification. They cast away const but this will go away when constification is handled in the main ASN1 code.
Diffstat (limited to 'crypto/bn/bn_mul.c')
-rw-r--r--crypto/bn/bn_mul.c482
1 files changed, 417 insertions, 65 deletions
diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c
index 3e8d8b9567..eb5d525613 100644
--- a/crypto/bn/bn_mul.c
+++ b/crypto/bn/bn_mul.c
@@ -56,10 +56,323 @@
* [including the GNU Public Licence.]
*/
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
#include <stdio.h>
+#include <assert.h>
#include "cryptlib.h"
#include "bn_lcl.h"
+/* Here follows specialised variants of bn_add_words() and
+ bn_sub_words(). They have the property performing operations on
+ arrays of different sizes. The sizes of those arrays is expressed through
+ cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
+ which is the delta between the two lengths, calculated as len(a)-len(b).
+ All lengths are the number of BN_ULONGs... For the operations that require
+ a result array as parameter, it must have the length cl+abs(dl).
+ These functions should probably end up in bn_asm.c as soon as there are
+ assembler counterparts for the systems that use assembler files. */
+
+BN_ULONG bn_sub_part_words(BN_ULONG *r,
+ const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl)
+ {
+ BN_ULONG c, t;
+
+ assert(cl >= 0);
+ c = bn_sub_words(r, a, b, cl);
+
+ if (dl == 0)
+ return c;
+
+ r += cl;
+ a += cl;
+ b += cl;
+
+ if (dl < 0)
+ {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
+#endif
+ for (;;)
+ {
+ t = b[0];
+ r[0] = (0-t-c)&BN_MASK2;
+ if (t != 0) c=1;
+ if (++dl >= 0) break;
+
+ t = b[1];
+ r[1] = (0-t-c)&BN_MASK2;
+ if (t != 0) c=1;
+ if (++dl >= 0) break;
+
+ t = b[2];
+ r[2] = (0-t-c)&BN_MASK2;
+ if (t != 0) c=1;
+ if (++dl >= 0) break;
+
+ t = b[3];
+ r[3] = (0-t-c)&BN_MASK2;
+ if (t != 0) c=1;
+ if (++dl >= 0) break;
+
+ b += 4;
+ r += 4;
+ }
+ }
+ else
+ {
+ int save_dl = dl;
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, dl, c);
+#endif
+ while(c)
+ {
+ t = a[0];
+ r[0] = (t-c)&BN_MASK2;
+ if (t != 0) c=0;
+ if (--dl <= 0) break;
+
+ t = a[1];
+ r[1] = (t-c)&BN_MASK2;
+ if (t != 0) c=0;
+ if (--dl <= 0) break;
+
+ t = a[2];
+ r[2] = (t-c)&BN_MASK2;
+ if (t != 0) c=0;
+ if (--dl <= 0) break;
+
+ t = a[3];
+ r[3] = (t-c)&BN_MASK2;
+ if (t != 0) c=0;
+ if (--dl <= 0) break;
+
+ save_dl = dl;
+ a += 4;
+ r += 4;
+ }
+ if (dl > 0)
+ {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
+#endif
+ if (save_dl > dl)
+ {
+ switch (save_dl - dl)
+ {
+ case 1:
+ r[1] = a[1];
+ if (--dl <= 0) break;
+ case 2:
+ r[2] = a[2];
+ if (--dl <= 0) break;
+ case 3:
+ r[3] = a[3];
+ if (--dl <= 0) break;
+ }
+ a += 4;
+ r += 4;
+ }
+ }
+ if (dl > 0)
+ {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n", cl, dl);
+#endif
+ for(;;)
+ {
+ r[0] = a[0];
+ if (--dl <= 0) break;
+ r[1] = a[1];
+ if (--dl <= 0) break;
+ r[2] = a[2];
+ if (--dl <= 0) break;
+ r[3] = a[3];
+ if (--dl <= 0) break;
+
+ a += 4;
+ r += 4;
+ }
+ }
+ }
+ return c;
+ }
+
+BN_ULONG bn_add_part_words(BN_ULONG *r,
+ const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl)
+ {
+ BN_ULONG c, l, t;
+
+ assert(cl >= 0);
+ c = bn_add_words(r, a, b, cl);
+
+ if (dl == 0)
+ return c;
+
+ r += cl;
+ a += cl;
+ b += cl;
+
+ if (dl < 0)
+ {
+ int save_dl = dl;
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
+#endif
+ while (c)
+ {
+ l=(c+b[0])&BN_MASK2;
+ c=(l < c);
+ r[0]=l;
+ if (++dl >= 0) break;
+
+ l=(c+b[1])&BN_MASK2;
+ c=(l < c);
+ r[1]=l;
+ if (++dl >= 0) break;
+
+ l=(c+b[2])&BN_MASK2;
+ c=(l < c);
+ r[2]=l;
+ if (++dl >= 0) break;
+
+ l=(c+b[3])&BN_MASK2;
+ c=(l < c);
+ r[3]=l;
+ if (++dl >= 0) break;
+
+ save_dl = dl;
+ b+=4;
+ r+=4;
+ }
+ if (dl < 0)
+ {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n", cl, dl);
+#endif
+ if (save_dl < dl)
+ {
+ switch (dl - save_dl)
+ {
+ case 1:
+ r[1] = b[1];
+ if (++dl >= 0) break;
+ case 2:
+ r[2] = b[2];
+ if (++dl >= 0) break;
+ case 3:
+ r[3] = b[3];
+ if (++dl >= 0) break;
+ }
+ b += 4;
+ r += 4;
+ }
+ }
+ if (dl < 0)
+ {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n", cl, dl);
+#endif
+ for(;;)
+ {
+ r[0] = b[0];
+ if (++dl >= 0) break;
+ r[1] = b[1];
+ if (++dl >= 0) break;
+ r[2] = b[2];
+ if (++dl >= 0) break;
+ r[3] = b[3];
+ if (++dl >= 0) break;
+
+ b += 4;
+ r += 4;
+ }
+ }
+ }
+ else
+ {
+ int save_dl = dl;
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
+#endif
+ while (c)
+ {
+ t=(a[0]+c)&BN_MASK2;
+ c=(t < c);
+ r[0]=t;
+ if (--dl <= 0) break;
+
+ t=(a[1]+c)&BN_MASK2;
+ c=(t < c);
+ r[1]=t;
+ if (--dl <= 0) break;
+
+ t=(a[2]+c)&BN_MASK2;
+ c=(t < c);
+ r[2]=t;
+ if (--dl <= 0) break;
+
+ t=(a[3]+c)&BN_MASK2;
+ c=(t < c);
+ r[3]=t;
+ if (--dl <= 0) break;
+
+ save_dl = dl;
+ a+=4;
+ r+=4;
+ }
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
+#endif
+ if (dl > 0)
+ {
+ if (save_dl > dl)
+ {
+ switch (save_dl - dl)
+ {
+ case 1:
+ r[1] = a[1];
+ if (--dl <= 0) break;
+ case 2:
+ r[2] = a[2];
+ if (--dl <= 0) break;
+ case 3:
+ r[3] = a[3];
+ if (--dl <= 0) break;
+ }
+ a += 4;
+ r += 4;
+ }
+ }
+ if (dl > 0)
+ {
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n", cl, dl);
+#endif
+ for(;;)
+ {
+ r[0] = a[0];
+ if (--dl <= 0) break;
+ r[1] = a[1];
+ if (--dl <= 0) break;
+ r[2] = a[2];
+ if (--dl <= 0) break;
+ r[3] = a[3];
+ if (--dl <= 0) break;
+
+ a += 4;
+ r += 4;
+ }
+ }
+ }
+ return c;
+ }
+
#ifdef BN_RECURSION
/* Karatsuba recursive multiplication algorithm
* (cf. Knuth, The Art of Computer Programming, Vol. 2) */
@@ -75,14 +388,15 @@
* a[1]*b[1]
*/
void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
- BN_ULONG *t)
+ int dna, int dnb, BN_ULONG *t)
{
int n=n2/2,c1,c2;
+ int tna=n+dna, tnb=n+dnb;
unsigned int neg,zero;
BN_ULONG ln,lo,*p;
# ifdef BN_COUNT
- printf(" bn_mul_recursive %d * %d\n",n2,n2);
+ fprintf(stderr," bn_mul_recursive %d * %d\n",n2,n2);
# endif
# ifdef BN_MUL_COMBA
# if 0
@@ -105,21 +419,21 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
- c1=bn_cmp_words(a,&(a[n]),n);
- c2=bn_cmp_words(&(b[n]),b,n);
+ c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
+ c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
zero=neg=0;
switch (c1*3+c2)
{
case -4:
- bn_sub_words(t, &(a[n]),a, n); /* - */
- bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
+ bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
+ bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
break;
case -3:
zero=1;
break;
case -2:
- bn_sub_words(t, &(a[n]),a, n); /* - */
- bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */
+ bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
+ bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
neg=1;
break;
case -1:
@@ -128,16 +442,16 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
zero=1;
break;
case 2:
- bn_sub_words(t, a, &(a[n]),n); /* + */
- bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
+ bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
+ bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
neg=1;
break;
case 3:
zero=1;
break;
case 4:
- bn_sub_words(t, a, &(a[n]),n);
- bn_sub_words(&(t[n]),&(b[n]),b, n);
+ bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
+ bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
break;
}
@@ -167,11 +481,11 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
{
p= &(t[n2*2]);
if (!zero)
- bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
+ bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
else
memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
- bn_mul_recursive(r,a,b,n,p);
- bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p);
+ bn_mul_recursive(r,a,b,n,0,0,p);
+ bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
}
/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
@@ -220,39 +534,39 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
/* n+tn is the word length
* t needs to be n*4 is size, as does r */
-void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
- int n, BN_ULONG *t)
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
+ int tna, int tnb, BN_ULONG *t)
{
int i,j,n2=n*2;
unsigned int c1,c2,neg,zero;
BN_ULONG ln,lo,*p;
# ifdef BN_COUNT
- printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n);
+ fprintf(stderr," bn_mul_part_recursive (%d+%d) * (%d+%d)\n",
+ tna, n, tnb, n);
# endif
if (n < 8)
{
- i=tn+n;
- bn_mul_normal(r,a,i,b,i);
+ bn_mul_normal(r,a,n+tna,b,n+tnb);
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
- c1=bn_cmp_words(a,&(a[n]),n);
- c2=bn_cmp_words(&(b[n]),b,n);
+ c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
+ c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
zero=neg=0;
switch (c1*3+c2)
{
case -4:
- bn_sub_words(t, &(a[n]),a, n); /* - */
- bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
+ bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
+ bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
break;
case -3:
zero=1;
/* break; */
case -2:
- bn_sub_words(t, &(a[n]),a, n); /* - */
- bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */
+ bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
+ bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
neg=1;
break;
case -1:
@@ -261,16 +575,16 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
zero=1;
/* break; */
case 2:
- bn_sub_words(t, a, &(a[n]),n); /* + */
- bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
+ bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
+ bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
neg=1;
break;
case 3:
zero=1;
/* break; */
case 4:
- bn_sub_words(t, a, &(a[n]),n);
- bn_sub_words(&(t[n]),&(b[n]),b, n);
+ bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
+ bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
break;
}
/* The zero case isn't yet implemented here. The speedup
@@ -289,54 +603,59 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
{
bn_mul_comba8(&(t[n2]),t,&(t[n]));
bn_mul_comba8(r,a,b);
- bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
- memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
+ bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
+ memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
}
else
{
p= &(t[n2*2]);
- bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
- bn_mul_recursive(r,a,b,n,p);
+ bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
+ bn_mul_recursive(r,a,b,n,0,0,p);
i=n/2;
/* If there is only a bottom half to the number,
* just do it */
- j=tn-i;
+ if (tna > tnb)
+ j = tna - i;
+ else
+ j = tnb - i;
if (j == 0)
{
- bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p);
+ bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
+ i,tna-i,tnb-i,p);
memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
}
else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
{
bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
- j,i,p);
- memset(&(r[n2+tn*2]),0,
- sizeof(BN_ULONG)*(n2-tn*2));
+ i,tna-i,tnb-i,p);
+ memset(&(r[n2+tna+tnb]),0,
+ sizeof(BN_ULONG)*(n2-tna-tnb));
}
else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
{
memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
- if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL)
+ if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
+ && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
{
- bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+ bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
}
else
{
for (;;)
{
i/=2;
- if (i < tn)
+ if (i < tna && i < tnb)
{
bn_mul_part_recursive(&(r[n2]),
&(a[n]),&(b[n]),
- tn-i,i,p);
+ i,tna-i,tnb-i,p);
break;
}
- else if (i == tn)
+ else if (i <= tna && i <= tnb)
{
bn_mul_recursive(&(r[n2]),
&(a[n]),&(b[n]),
- i,p);
+ i,tna-i,tnb-i,p);
break;
}
}
@@ -397,10 +716,10 @@ void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
int n=n2/2;
# ifdef BN_COUNT
- printf(" bn_mul_low_recursive %d * %d\n",n2,n2);
+ fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
# endif
- bn_mul_recursive(r,a,b,n,&(t[0]));
+ bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
{
bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
@@ -431,7 +750,7 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
BN_ULONG ll,lc,*lp,*mp;
# ifdef BN_COUNT
- printf(" bn_mul_high %d * %d\n",n2,n2);
+ fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
# endif
n=n2/2;
@@ -484,8 +803,8 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
else
# endif
{
- bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2]));
- bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2]));
+ bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
+ bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
}
/* s0 == low(al*bl)
@@ -608,11 +927,11 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
}
#endif /* BN_RECURSION */
-int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
+ int ret=0;
int top,al,bl;
BIGNUM *rr;
- int ret = 0;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
int i;
#endif
@@ -622,7 +941,7 @@ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
#endif
#ifdef BN_COUNT
- printf("BN_mul %d * %d\n",a->top,b->top);
+ fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
#endif
bn_check_top(a);
@@ -675,17 +994,55 @@ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
#ifdef BN_RECURSION
if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
{
+ if (i >= -1 && i <= 1)
+ {
+ int sav_j =0;
+ /* Find out the power of two lower or equal
+ to the longest of the two numbers */
+ if (i >= 0)
+ {
+ j = BN_num_bits_word((BN_ULONG)al);
+ }
+ if (i == -1)
+ {
+ j = BN_num_bits_word((BN_ULONG)bl);
+ }
+ sav_j = j;
+ j = 1<<(j-1);
+ assert(j <= al || j <= bl);
+ k = j+j;
+ t = BN_CTX_get(ctx);
+ if (al > j || bl > j)
+ {
+ bn_wexpand(t,k*4);
+ bn_wexpand(rr,k*4);
+ bn_mul_part_recursive(rr->d,a->d,b->d,
+ j,al-j,bl-j,t->d);
+ }
+ else /* al <= j || bl <= j */
+ {
+ bn_wexpand(t,k*2);
+ bn_wexpand(rr,k*2);
+ bn_mul_recursive(rr->d,a->d,b->d,
+ j,al-j,bl-j,t->d);
+ }
+ rr->top=top;
+ goto end;
+ }
+#if 0
if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
{
- bn_wexpand(b,al);
- b->d[bl]=0;
+ BIGNUM *tmp_bn = (BIGNUM *)b;
+ bn_wexpand(tmp_bn,al);
+ tmp_bn->d[bl]=0;
bl++;
i--;
}
else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
{
- bn_wexpand(a,bl);
- a->d[al]=0;
+ BIGNUM *tmp_bn = (BIGNUM *)a;
+ bn_wexpand(tmp_bn,bl);
+ tmp_bn->d[al]=0;
al++;
i++;
}
@@ -705,19 +1062,14 @@ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
}
else
{
- bn_wexpand(a,k);
- bn_wexpand(b,k);
bn_wexpand(t,k*4);
bn_wexpand(rr,k*4);
- for (i=a->top; i<k; i++)
- a->d[i]=0;
- for (i=b->top; i<k; i++)
- b->d[i]=0;
bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
}
rr->top=top;
goto end;
}
+#endif
}
#endif /* BN_RECURSION */
if (bn_wexpand(rr,top) == NULL) goto err;
@@ -740,7 +1092,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
BN_ULONG *rr;
#ifdef BN_COUNT
- printf(" bn_mul_normal %d * %d\n",na,nb);
+ fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
#endif
if (na < nb)
@@ -774,7 +1126,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
{
#ifdef BN_COUNT
- printf(" bn_mul_low_normal %d * %d\n",n,n);
+ fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
#endif
bn_mul_words(r,a,n,b[0]);