e3ce10792198eac39b8913a523b2ac57278515de
[openssl.git] / crypto / bn / old / bn_wmul.c
1 #include <stdio.h>
2 #include "bn_lcl.h"
3
4 #if 1
5
6 int bn_mull(BIGNUM *r,BIGNUM *a,BIGNUM *b, BN_CTX *ctx);
7
8 int bn_mull(r,a,b,ctx)
9 BIGNUM *r,*a,*b;
10 BN_CTX *ctx;
11         {
12         int top,i,j,k,al,bl;
13         BIGNUM *t;
14
15 #ifdef BN_COUNT
16 printf("bn_mull %d * %d\n",a->top,b->top);
17 #endif
18
19         bn_check_top(a);
20         bn_check_top(b);
21         bn_check_top(r);
22
23         al=a->top;
24         bl=b->top;
25         r->neg=a->neg^b->neg;
26
27         top=al+bl;
28         if ((al < 4) || (bl < 4))
29                 {
30                 if (bn_wexpand(r,top) == NULL) return(0);
31                 r->top=top;
32                 bn_mul_normal(r->d,a->d,al,b->d,bl);
33                 goto end;
34                 }
35         else if (al == bl) /* A good start, they are the same size */
36                 goto symetric;
37         else
38                 {
39                 i=(al-bl);
40                 if ((i ==  1) && !BN_get_flags(b,BN_FLG_STATIC_DATA))
41                         {
42                         bn_wexpand(b,al);
43                         b->d[bl]=0;
44                         bl++;
45                         goto symetric;
46                         }
47                 else if ((i ==  -1) && !BN_get_flags(a,BN_FLG_STATIC_DATA))
48                         {
49                         bn_wexpand(a,bl);
50                         a->d[al]=0;
51                         al++;
52                         goto symetric;
53                         }
54                 }
55
56         /* asymetric and >= 4 */ 
57         if (bn_wexpand(r,top) == NULL) return(0);
58         r->top=top;
59         bn_mul_normal(r->d,a->d,al,b->d,bl);
60
61         if (0)
62                 {
63                 /* symetric and > 4 */
64 symetric:
65                 if (al == 4)
66                         {
67                         if (bn_wexpand(r,al*2) == NULL) return(0);
68                         r->top=top;
69                         bn_mul_comba4(r->d,a->d,b->d);
70                         goto end;
71                         }
72                 if (al == 8)
73                         {
74                         if (bn_wexpand(r,al*2) == NULL) return(0);
75                         r->top=top;
76                         bn_mul_comba8(r->d,a->d,b->d);
77                         goto end;
78                         }
79                 if (al <= BN_MULL_NORMAL_SIZE)
80                         {
81                         if (bn_wexpand(r,al*2) == NULL) return(0);
82                         r->top=top;
83                         bn_mul_normal(r->d,a->d,al,b->d,bl);
84                         goto end;
85                         }
86                 /* 16 or larger */
87                 j=BN_num_bits_word((BN_ULONG)al);
88                 j=1<<(j-1);
89                 k=j+j;
90                 t= &(ctx->bn[ctx->tos]);
91                 if (al == j) /* exact multiple */
92                         {
93                         bn_wexpand(t,k*2);
94                         bn_wexpand(r,k*2);
95                         bn_mul_recursive(r->d,a->d,b->d,al,t->d);
96                         }
97                 else
98                         {
99                         bn_wexpand(a,k);
100                         bn_wexpand(b,k);
101                         bn_wexpand(t,k*4);
102                         bn_wexpand(r,k*4);
103                         for (i=a->top; i<k; i++)
104                                 a->d[i]=0;
105                         for (i=b->top; i<k; i++)
106                                 b->d[i]=0;
107                         bn_mul_part_recursive(r->d,a->d,b->d,al-j,j,t->d);
108                         }
109                 r->top=top;
110                 }
111 end:
112         bn_fix_top(r);
113         return(1);
114         }
115 #endif
116
117 void bn_mul_normal(r,a,na,b,nb)
118 BN_ULONG *r,*a;
119 int na;
120 BN_ULONG *b;
121 int nb;
122         {
123         BN_ULONG *rr;
124
125 #ifdef BN_COUNT
126 printf(" bn_mul_normal %d * %d\n",na,nb);
127 #endif
128
129         if (na < nb)
130                 {
131                 int itmp;
132                 BN_ULONG *ltmp;
133
134                 itmp=na; na=nb; nb=itmp;
135                 ltmp=a;   a=b;   b=ltmp;
136
137                 }
138         rr= &(r[na]);
139         rr[0]=bn_mul_words(r,a,na,b[0]);
140
141         for (;;)
142                 {
143                 if (--nb <= 0) return;
144                 rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
145                 if (--nb <= 0) return;
146                 rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
147                 if (--nb <= 0) return;
148                 rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
149                 if (--nb <= 0) return;
150                 rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
151                 rr+=4;
152                 r+=4;
153                 b+=4;
154                 }
155         }
156
157 #if 1
158 void bn_mul_low_normal(r,a,b,n)
159 BN_ULONG *r,*a,*b;
160 int n;
161         {
162 #ifdef BN_COUNT
163 printf(" bn_mul_low_normal %d * %d\n",n,n);
164 #endif
165         bn_mul_words(r,a,n,b[0]);
166
167         for (;;)
168                 {
169                 if (--n <= 0) return;
170                 bn_mul_add_words(&(r[1]),a,n,b[1]);
171                 if (--n <= 0) return;
172                 bn_mul_add_words(&(r[2]),a,n,b[2]);
173                 if (--n <= 0) return;
174                 bn_mul_add_words(&(r[3]),a,n,b[3]);
175                 if (--n <= 0) return;
176                 bn_mul_add_words(&(r[4]),a,n,b[4]);
177                 r+=4;
178                 b+=4;
179                 }
180         }
181 #endif