bn/bn_const.c: make it indent-friendly.
[openssl.git] / crypto / bn / bn_mul.c
1 /* crypto/bn/bn_mul.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #ifndef BN_DEBUG
60 # undef NDEBUG /* avoid conflicting definitions */
61 # define NDEBUG
62 #endif
63
64 #include <stdio.h>
65 #include <assert.h>
66 #include "cryptlib.h"
67 #include "bn_lcl.h"
68
69 #if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
70 /* Here follows specialised variants of bn_add_words() and
71    bn_sub_words().  They have the property performing operations on
72    arrays of different sizes.  The sizes of those arrays is expressed through
73    cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
74    which is the delta between the two lengths, calculated as len(a)-len(b).
75    All lengths are the number of BN_ULONGs...  For the operations that require
76    a result array as parameter, it must have the length cl+abs(dl).
77    These functions should probably end up in bn_asm.c as soon as there are
78    assembler counterparts for the systems that use assembler files.  */
79
80 BN_ULONG bn_sub_part_words(BN_ULONG *r,
81         const BN_ULONG *a, const BN_ULONG *b,
82         int cl, int dl)
83         {
84         BN_ULONG c, t;
85
86         assert(cl >= 0);
87         c = bn_sub_words(r, a, b, cl);
88
89         if (dl == 0)
90                 return c;
91
92         r += cl;
93         a += cl;
94         b += cl;
95
96         if (dl < 0)
97                 {
98 #ifdef BN_COUNT
99                 fprintf(stderr, "  bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
100 #endif
101                 for (;;)
102                         {
103                         t = b[0];
104                         r[0] = (0-t-c)&BN_MASK2;
105                         if (t != 0) c=1;
106                         if (++dl >= 0) break;
107
108                         t = b[1];
109                         r[1] = (0-t-c)&BN_MASK2;
110                         if (t != 0) c=1;
111                         if (++dl >= 0) break;
112
113                         t = b[2];
114                         r[2] = (0-t-c)&BN_MASK2;
115                         if (t != 0) c=1;
116                         if (++dl >= 0) break;
117
118                         t = b[3];
119                         r[3] = (0-t-c)&BN_MASK2;
120                         if (t != 0) c=1;
121                         if (++dl >= 0) break;
122
123                         b += 4;
124                         r += 4;
125                         }
126                 }
127         else
128                 {
129                 int save_dl = dl;
130 #ifdef BN_COUNT
131                 fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, dl, c);
132 #endif
133                 while(c)
134                         {
135                         t = a[0];
136                         r[0] = (t-c)&BN_MASK2;
137                         if (t != 0) c=0;
138                         if (--dl <= 0) break;
139
140                         t = a[1];
141                         r[1] = (t-c)&BN_MASK2;
142                         if (t != 0) c=0;
143                         if (--dl <= 0) break;
144
145                         t = a[2];
146                         r[2] = (t-c)&BN_MASK2;
147                         if (t != 0) c=0;
148                         if (--dl <= 0) break;
149
150                         t = a[3];
151                         r[3] = (t-c)&BN_MASK2;
152                         if (t != 0) c=0;
153                         if (--dl <= 0) break;
154
155                         save_dl = dl;
156                         a += 4;
157                         r += 4;
158                         }
159                 if (dl > 0)
160                         {
161 #ifdef BN_COUNT
162                         fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
163 #endif
164                         if (save_dl > dl)
165                                 {
166                                 switch (save_dl - dl)
167                                         {
168                                 case 1:
169                                         r[1] = a[1];
170                                         if (--dl <= 0) break;
171                                 case 2:
172                                         r[2] = a[2];
173                                         if (--dl <= 0) break;
174                                 case 3:
175                                         r[3] = a[3];
176                                         if (--dl <= 0) break;
177                                         }
178                                 a += 4;
179                                 r += 4;
180                                 }
181                         }
182                 if (dl > 0)
183                         {
184 #ifdef BN_COUNT
185                         fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, copy)\n", cl, dl);
186 #endif
187                         for(;;)
188                                 {
189                                 r[0] = a[0];
190                                 if (--dl <= 0) break;
191                                 r[1] = a[1];
192                                 if (--dl <= 0) break;
193                                 r[2] = a[2];
194                                 if (--dl <= 0) break;
195                                 r[3] = a[3];
196                                 if (--dl <= 0) break;
197
198                                 a += 4;
199                                 r += 4;
200                                 }
201                         }
202                 }
203         return c;
204         }
205 #endif
206
207 BN_ULONG bn_add_part_words(BN_ULONG *r,
208         const BN_ULONG *a, const BN_ULONG *b,
209         int cl, int dl)
210         {
211         BN_ULONG c, l, t;
212
213         assert(cl >= 0);
214         c = bn_add_words(r, a, b, cl);
215
216         if (dl == 0)
217                 return c;
218
219         r += cl;
220         a += cl;
221         b += cl;
222
223         if (dl < 0)
224                 {
225                 int save_dl = dl;
226 #ifdef BN_COUNT
227                 fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
228 #endif
229                 while (c)
230                         {
231                         l=(c+b[0])&BN_MASK2;
232                         c=(l < c);
233                         r[0]=l;
234                         if (++dl >= 0) break;
235
236                         l=(c+b[1])&BN_MASK2;
237                         c=(l < c);
238                         r[1]=l;
239                         if (++dl >= 0) break;
240
241                         l=(c+b[2])&BN_MASK2;
242                         c=(l < c);
243                         r[2]=l;
244                         if (++dl >= 0) break;
245
246                         l=(c+b[3])&BN_MASK2;
247                         c=(l < c);
248                         r[3]=l;
249                         if (++dl >= 0) break;
250
251                         save_dl = dl;
252                         b+=4;
253                         r+=4;
254                         }
255                 if (dl < 0)
256                         {
257 #ifdef BN_COUNT
258                         fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c == 0)\n", cl, dl);
259 #endif
260                         if (save_dl < dl)
261                                 {
262                                 switch (dl - save_dl)
263                                         {
264                                 case 1:
265                                         r[1] = b[1];
266                                         if (++dl >= 0) break;
267                                 case 2:
268                                         r[2] = b[2];
269                                         if (++dl >= 0) break;
270                                 case 3:
271                                         r[3] = b[3];
272                                         if (++dl >= 0) break;
273                                         }
274                                 b += 4;
275                                 r += 4;
276                                 }
277                         }
278                 if (dl < 0)
279                         {
280 #ifdef BN_COUNT
281                         fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, copy)\n", cl, dl);
282 #endif
283                         for(;;)
284                                 {
285                                 r[0] = b[0];
286                                 if (++dl >= 0) break;
287                                 r[1] = b[1];
288                                 if (++dl >= 0) break;
289                                 r[2] = b[2];
290                                 if (++dl >= 0) break;
291                                 r[3] = b[3];
292                                 if (++dl >= 0) break;
293
294                                 b += 4;
295                                 r += 4;
296                                 }
297                         }
298                 }
299         else
300                 {
301                 int save_dl = dl;
302 #ifdef BN_COUNT
303                 fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
304 #endif
305                 while (c)
306                         {
307                         t=(a[0]+c)&BN_MASK2;
308                         c=(t < c);
309                         r[0]=t;
310                         if (--dl <= 0) break;
311
312                         t=(a[1]+c)&BN_MASK2;
313                         c=(t < c);
314                         r[1]=t;
315                         if (--dl <= 0) break;
316
317                         t=(a[2]+c)&BN_MASK2;
318                         c=(t < c);
319                         r[2]=t;
320                         if (--dl <= 0) break;
321
322                         t=(a[3]+c)&BN_MASK2;
323                         c=(t < c);
324                         r[3]=t;
325                         if (--dl <= 0) break;
326
327                         save_dl = dl;
328                         a+=4;
329                         r+=4;
330                         }
331 #ifdef BN_COUNT
332                 fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
333 #endif
334                 if (dl > 0)
335                         {
336                         if (save_dl > dl)
337                                 {
338                                 switch (save_dl - dl)
339                                         {
340                                 case 1:
341                                         r[1] = a[1];
342                                         if (--dl <= 0) break;
343                                 case 2:
344                                         r[2] = a[2];
345                                         if (--dl <= 0) break;
346                                 case 3:
347                                         r[3] = a[3];
348                                         if (--dl <= 0) break;
349                                         }
350                                 a += 4;
351                                 r += 4;
352                                 }
353                         }
354                 if (dl > 0)
355                         {
356 #ifdef BN_COUNT
357                         fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, copy)\n", cl, dl);
358 #endif
359                         for(;;)
360                                 {
361                                 r[0] = a[0];
362                                 if (--dl <= 0) break;
363                                 r[1] = a[1];
364                                 if (--dl <= 0) break;
365                                 r[2] = a[2];
366                                 if (--dl <= 0) break;
367                                 r[3] = a[3];
368                                 if (--dl <= 0) break;
369
370                                 a += 4;
371                                 r += 4;
372                                 }
373                         }
374                 }
375         return c;
376         }
377
378 #ifdef BN_RECURSION
379 /* Karatsuba recursive multiplication algorithm
380  * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
381
382 /*-
383  * r is 2*n2 words in size,
384  * a and b are both n2 words in size.
385  * n2 must be a power of 2.
386  * We multiply and return the result.
387  * t must be 2*n2 words in size
388  * We calculate
389  * a[0]*b[0]
390  * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
391  * a[1]*b[1]
392  */
393 /* dnX may not be positive, but n2/2+dnX has to be */
394 void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
395         int dna, int dnb, BN_ULONG *t)
396         {
397         int n=n2/2,c1,c2;
398         int tna=n+dna, tnb=n+dnb;
399         unsigned int neg,zero;
400         BN_ULONG ln,lo,*p;
401
402 # ifdef BN_COUNT
403         fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
404 # endif
405 # ifdef BN_MUL_COMBA
406 #  if 0
407         if (n2 == 4)
408                 {
409                 bn_mul_comba4(r,a,b);
410                 return;
411                 }
412 #  endif
413         /* Only call bn_mul_comba 8 if n2 == 8 and the
414          * two arrays are complete [steve]
415          */
416         if (n2 == 8 && dna == 0 && dnb == 0)
417                 {
418                 bn_mul_comba8(r,a,b);
419                 return; 
420                 }
421 # endif /* BN_MUL_COMBA */
422         /* Else do normal multiply */
423         if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
424                 {
425                 bn_mul_normal(r,a,n2+dna,b,n2+dnb);
426                 if ((dna + dnb) < 0)
427                         memset(&r[2*n2 + dna + dnb], 0,
428                                 sizeof(BN_ULONG) * -(dna + dnb));
429                 return;
430                 }
431         /* r=(a[0]-a[1])*(b[1]-b[0]) */
432         c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
433         c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
434         zero=neg=0;
435         switch (c1*3+c2)
436                 {
437         case -4:
438                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
439                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
440                 break;
441         case -3:
442                 zero=1;
443                 break;
444         case -2:
445                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
446                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
447                 neg=1;
448                 break;
449         case -1:
450         case 0:
451         case 1:
452                 zero=1;
453                 break;
454         case 2:
455                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
456                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
457                 neg=1;
458                 break;
459         case 3:
460                 zero=1;
461                 break;
462         case 4:
463                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
464                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
465                 break;
466                 }
467
468 # ifdef BN_MUL_COMBA
469         if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
470                                                extra args to do this well */
471                 {
472                 if (!zero)
473                         bn_mul_comba4(&(t[n2]),t,&(t[n]));
474                 else
475                         memset(&(t[n2]),0,8*sizeof(BN_ULONG));
476                 
477                 bn_mul_comba4(r,a,b);
478                 bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
479                 }
480         else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
481                                                     take extra args to do this
482                                                     well */
483                 {
484                 if (!zero)
485                         bn_mul_comba8(&(t[n2]),t,&(t[n]));
486                 else
487                         memset(&(t[n2]),0,16*sizeof(BN_ULONG));
488                 
489                 bn_mul_comba8(r,a,b);
490                 bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
491                 }
492         else
493 # endif /* BN_MUL_COMBA */
494                 {
495                 p= &(t[n2*2]);
496                 if (!zero)
497                         bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
498                 else
499                         memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
500                 bn_mul_recursive(r,a,b,n,0,0,p);
501                 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
502                 }
503
504         /*-
505          * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
506          * r[10] holds (a[0]*b[0])
507          * r[32] holds (b[1]*b[1])
508          */
509
510         c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
511
512         if (neg) /* if t[32] is negative */
513                 {
514                 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
515                 }
516         else
517                 {
518                 /* Might have a carry */
519                 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
520                 }
521
522         /*-
523          * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
524          * r[10] holds (a[0]*b[0])
525          * r[32] holds (b[1]*b[1])
526          * c1 holds the carry bits
527          */
528         c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
529         if (c1)
530                 {
531                 p= &(r[n+n2]);
532                 lo= *p;
533                 ln=(lo+c1)&BN_MASK2;
534                 *p=ln;
535
536                 /* The overflow will stop before we over write
537                  * words we should not overwrite */
538                 if (ln < (BN_ULONG)c1)
539                         {
540                         do      {
541                                 p++;
542                                 lo= *p;
543                                 ln=(lo+1)&BN_MASK2;
544                                 *p=ln;
545                                 } while (ln == 0);
546                         }
547                 }
548         }
549
550 /* n+tn is the word length
551  * t needs to be n*4 is size, as does r */
552 /* tnX may not be negative but less than n */
553 void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
554              int tna, int tnb, BN_ULONG *t)
555         {
556         int i,j,n2=n*2;
557         int c1,c2,neg;
558         BN_ULONG ln,lo,*p;
559
560 # ifdef BN_COUNT
561         fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
562                 n, tna, n, tnb);
563 # endif
564         if (n < 8)
565                 {
566                 bn_mul_normal(r,a,n+tna,b,n+tnb);
567                 return;
568                 }
569
570         /* r=(a[0]-a[1])*(b[1]-b[0]) */
571         c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
572         c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
573         neg=0;
574         switch (c1*3+c2)
575                 {
576         case -4:
577                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
578                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
579                 break;
580         case -3:
581                 /* break; */
582         case -2:
583                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
584                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
585                 neg=1;
586                 break;
587         case -1:
588         case 0:
589         case 1:
590                 /* break; */
591         case 2:
592                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
593                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
594                 neg=1;
595                 break;
596         case 3:
597                 /* break; */
598         case 4:
599                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
600                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
601                 break;
602                 }
603                 /* The zero case isn't yet implemented here. The speedup
604                    would probably be negligible. */
605 # if 0
606         if (n == 4)
607                 {
608                 bn_mul_comba4(&(t[n2]),t,&(t[n]));
609                 bn_mul_comba4(r,a,b);
610                 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
611                 memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
612                 }
613         else
614 # endif
615         if (n == 8)
616                 {
617                 bn_mul_comba8(&(t[n2]),t,&(t[n]));
618                 bn_mul_comba8(r,a,b);
619                 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
620                 memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
621                 }
622         else
623                 {
624                 p= &(t[n2*2]);
625                 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
626                 bn_mul_recursive(r,a,b,n,0,0,p);
627                 i=n/2;
628                 /* If there is only a bottom half to the number,
629                  * just do it */
630                 if (tna > tnb)
631                         j = tna - i;
632                 else
633                         j = tnb - i;
634                 if (j == 0)
635                         {
636                         bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
637                                 i,tna-i,tnb-i,p);
638                         memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
639                         }
640                 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
641                                 {
642                                 bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
643                                         i,tna-i,tnb-i,p);
644                                 memset(&(r[n2+tna+tnb]),0,
645                                         sizeof(BN_ULONG)*(n2-tna-tnb));
646                                 }
647                 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
648                         {
649                         memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
650                         if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
651                                 && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
652                                 {
653                                 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
654                                 }
655                         else
656                                 {
657                                 for (;;)
658                                         {
659                                         i/=2;
660                                         /* these simplified conditions work
661                                          * exclusively because difference
662                                          * between tna and tnb is 1 or 0 */
663                                         if (i < tna || i < tnb)
664                                                 {
665                                                 bn_mul_part_recursive(&(r[n2]),
666                                                         &(a[n]),&(b[n]),
667                                                         i,tna-i,tnb-i,p);
668                                                 break;
669                                                 }
670                                         else if (i == tna || i == tnb)
671                                                 {
672                                                 bn_mul_recursive(&(r[n2]),
673                                                         &(a[n]),&(b[n]),
674                                                         i,tna-i,tnb-i,p);
675                                                 break;
676                                                 }
677                                         }
678                                 }
679                         }
680                 }
681
682         /*-
683          * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
684          * r[10] holds (a[0]*b[0])
685          * r[32] holds (b[1]*b[1])
686          */
687
688         c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
689
690         if (neg) /* if t[32] is negative */
691                 {
692                 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
693                 }
694         else
695                 {
696                 /* Might have a carry */
697                 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
698                 }
699
700         /*-
701          * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
702          * r[10] holds (a[0]*b[0])
703          * r[32] holds (b[1]*b[1])
704          * c1 holds the carry bits
705          */
706         c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
707         if (c1)
708                 {
709                 p= &(r[n+n2]);
710                 lo= *p;
711                 ln=(lo+c1)&BN_MASK2;
712                 *p=ln;
713
714                 /* The overflow will stop before we over write
715                  * words we should not overwrite */
716                 if (ln < (BN_ULONG)c1)
717                         {
718                         do      {
719                                 p++;
720                                 lo= *p;
721                                 ln=(lo+1)&BN_MASK2;
722                                 *p=ln;
723                                 } while (ln == 0);
724                         }
725                 }
726         }
727
728 /*-
729  * a and b must be the same size, which is n2.
730  * r needs to be n2 words and t needs to be n2*2
731  */
732 void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
733              BN_ULONG *t)
734         {
735         int n=n2/2;
736
737 # ifdef BN_COUNT
738         fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
739 # endif
740
741         bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
742         if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
743                 {
744                 bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
745                 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
746                 bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
747                 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
748                 }
749         else
750                 {
751                 bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
752                 bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
753                 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
754                 bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
755                 }
756         }
757
758 /*-
759  * a and b must be the same size, which is n2.
760  * r needs to be n2 words and t needs to be n2*2
761  * l is the low words of the output.
762  * t needs to be n2*3
763  */
764 void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
765              BN_ULONG *t)
766         {
767         int i,n;
768         int c1,c2;
769         int neg,oneg,zero;
770         BN_ULONG ll,lc,*lp,*mp;
771
772 # ifdef BN_COUNT
773         fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
774 # endif
775         n=n2/2;
776
777         /* Calculate (al-ah)*(bh-bl) */
778         neg=zero=0;
779         c1=bn_cmp_words(&(a[0]),&(a[n]),n);
780         c2=bn_cmp_words(&(b[n]),&(b[0]),n);
781         switch (c1*3+c2)
782                 {
783         case -4:
784                 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
785                 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
786                 break;
787         case -3:
788                 zero=1;
789                 break;
790         case -2:
791                 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
792                 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
793                 neg=1;
794                 break;
795         case -1:
796         case 0:
797         case 1:
798                 zero=1;
799                 break;
800         case 2:
801                 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
802                 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
803                 neg=1;
804                 break;
805         case 3:
806                 zero=1;
807                 break;
808         case 4:
809                 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
810                 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
811                 break;
812                 }
813                 
814         oneg=neg;
815         /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
816         /* r[10] = (a[1]*b[1]) */
817 # ifdef BN_MUL_COMBA
818         if (n == 8)
819                 {
820                 bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
821                 bn_mul_comba8(r,&(a[n]),&(b[n]));
822                 }
823         else
824 # endif
825                 {
826                 bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
827                 bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
828                 }
829
830         /*-
831          * s0 == low(al*bl)
832          * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
833          * We know s0 and s1 so the only unknown is high(al*bl)
834          * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
835          * high(al*bl) == s1 - (r[0]+l[0]+t[0])
836          */
837         if (l != NULL)
838                 {
839                 lp= &(t[n2+n]);
840                 c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
841                 }
842         else
843                 {
844                 c1=0;
845                 lp= &(r[0]);
846                 }
847
848         if (neg)
849                 neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
850         else
851                 {
852                 bn_add_words(&(t[n2]),lp,&(t[0]),n);
853                 neg=0;
854                 }
855
856         if (l != NULL)
857                 {
858                 bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
859                 }
860         else
861                 {
862                 lp= &(t[n2+n]);
863                 mp= &(t[n2]);
864                 for (i=0; i<n; i++)
865                         lp[i]=((~mp[i])+1)&BN_MASK2;
866                 }
867
868         /*-
869          * s[0] = low(al*bl)
870          * t[3] = high(al*bl)
871          * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
872          * r[10] = (a[1]*b[1])
873          */
874         /*-
875          * R[10] = al*bl
876          * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
877          * R[32] = ah*bh
878          */
879         /*-
880          * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
881          * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
882          * R[3]=r[1]+(carry/borrow)
883          */
884         if (l != NULL)
885                 {
886                 lp= &(t[n2]);
887                 c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
888                 }
889         else
890                 {
891                 lp= &(t[n2+n]);
892                 c1=0;
893                 }
894         c1+=(int)(bn_add_words(&(t[n2]),lp,  &(r[0]),n));
895         if (oneg)
896                 c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
897         else
898                 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
899
900         c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
901         c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
902         if (oneg)
903                 c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
904         else
905                 c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
906         
907         if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
908                 {
909                 i=0;
910                 if (c1 > 0)
911                         {
912                         lc=c1;
913                         do      {
914                                 ll=(r[i]+lc)&BN_MASK2;
915                                 r[i++]=ll;
916                                 lc=(lc > ll);
917                                 } while (lc);
918                         }
919                 else
920                         {
921                         lc= -c1;
922                         do      {
923                                 ll=r[i];
924                                 r[i++]=(ll-lc)&BN_MASK2;
925                                 lc=(lc > ll);
926                                 } while (lc);
927                         }
928                 }
929         if (c2 != 0) /* Add starting at r[1] */
930                 {
931                 i=n;
932                 if (c2 > 0)
933                         {
934                         lc=c2;
935                         do      {
936                                 ll=(r[i]+lc)&BN_MASK2;
937                                 r[i++]=ll;
938                                 lc=(lc > ll);
939                                 } while (lc);
940                         }
941                 else
942                         {
943                         lc= -c2;
944                         do      {
945                                 ll=r[i];
946                                 r[i++]=(ll-lc)&BN_MASK2;
947                                 lc=(lc > ll);
948                                 } while (lc);
949                         }
950                 }
951         }
952 #endif /* BN_RECURSION */
953
954 int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
955         {
956         int ret=0;
957         int top,al,bl;
958         BIGNUM *rr;
959 #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
960         int i;
961 #endif
962 #ifdef BN_RECURSION
963         BIGNUM *t=NULL;
964         int j=0,k;
965 #endif
966
967 #ifdef BN_COUNT
968         fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
969 #endif
970
971         bn_check_top(a);
972         bn_check_top(b);
973         bn_check_top(r);
974
975         al=a->top;
976         bl=b->top;
977
978         if ((al == 0) || (bl == 0))
979                 {
980                 BN_zero(r);
981                 return(1);
982                 }
983         top=al+bl;
984
985         BN_CTX_start(ctx);
986         if ((r == a) || (r == b))
987                 {
988                 if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
989                 }
990         else
991                 rr = r;
992         rr->neg=a->neg^b->neg;
993
994 #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
995         i = al-bl;
996 #endif
997 #ifdef BN_MUL_COMBA
998         if (i == 0)
999                 {
1000 # if 0
1001                 if (al == 4)
1002                         {
1003                         if (bn_wexpand(rr,8) == NULL) goto err;
1004                         rr->top=8;
1005                         bn_mul_comba4(rr->d,a->d,b->d);
1006                         goto end;
1007                         }
1008 # endif
1009                 if (al == 8)
1010                         {
1011                         if (bn_wexpand(rr,16) == NULL) goto err;
1012                         rr->top=16;
1013                         bn_mul_comba8(rr->d,a->d,b->d);
1014                         goto end;
1015                         }
1016                 }
1017 #endif /* BN_MUL_COMBA */
1018 #ifdef BN_RECURSION
1019         if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
1020                 {
1021                 if (i >= -1 && i <= 1)
1022                         {
1023                         /* Find out the power of two lower or equal
1024                            to the longest of the two numbers */
1025                         if (i >= 0)
1026                                 {
1027                                 j = BN_num_bits_word((BN_ULONG)al);
1028                                 }
1029                         if (i == -1)
1030                                 {
1031                                 j = BN_num_bits_word((BN_ULONG)bl);
1032                                 }
1033                         j = 1<<(j-1);
1034                         assert(j <= al || j <= bl);
1035                         k = j+j;
1036                         t = BN_CTX_get(ctx);
1037                         if (t == NULL)
1038                                 goto err;
1039                         if (al > j || bl > j)
1040                                 {
1041                                 if (bn_wexpand(t,k*4) == NULL) goto err;
1042                                 if (bn_wexpand(rr,k*4) == NULL) goto err;
1043                                 bn_mul_part_recursive(rr->d,a->d,b->d,
1044                                         j,al-j,bl-j,t->d);
1045                                 }
1046                         else    /* al <= j || bl <= j */
1047                                 {
1048                                 if (bn_wexpand(t,k*2) == NULL) goto err;
1049                                 if (bn_wexpand(rr,k*2) == NULL) goto err;
1050                                 bn_mul_recursive(rr->d,a->d,b->d,
1051                                         j,al-j,bl-j,t->d);
1052                                 }
1053                         rr->top=top;
1054                         goto end;
1055                         }
1056 #if 0
1057                 if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
1058                         {
1059                         BIGNUM *tmp_bn = (BIGNUM *)b;
1060                         if (bn_wexpand(tmp_bn,al) == NULL) goto err;
1061                         tmp_bn->d[bl]=0;
1062                         bl++;
1063                         i--;
1064                         }
1065                 else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
1066                         {
1067                         BIGNUM *tmp_bn = (BIGNUM *)a;
1068                         if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
1069                         tmp_bn->d[al]=0;
1070                         al++;
1071                         i++;
1072                         }
1073                 if (i == 0)
1074                         {
1075                         /* symmetric and > 4 */
1076                         /* 16 or larger */
1077                         j=BN_num_bits_word((BN_ULONG)al);
1078                         j=1<<(j-1);
1079                         k=j+j;
1080                         t = BN_CTX_get(ctx);
1081                         if (al == j) /* exact multiple */
1082                                 {
1083                                 if (bn_wexpand(t,k*2) == NULL) goto err;
1084                                 if (bn_wexpand(rr,k*2) == NULL) goto err;
1085                                 bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
1086                                 }
1087                         else
1088                                 {
1089                                 if (bn_wexpand(t,k*4) == NULL) goto err;
1090                                 if (bn_wexpand(rr,k*4) == NULL) goto err;
1091                                 bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
1092                                 }
1093                         rr->top=top;
1094                         goto end;
1095                         }
1096 #endif
1097                 }
1098 #endif /* BN_RECURSION */
1099         if (bn_wexpand(rr,top) == NULL) goto err;
1100         rr->top=top;
1101         bn_mul_normal(rr->d,a->d,al,b->d,bl);
1102
1103 #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
1104 end:
1105 #endif
1106         bn_correct_top(rr);
1107         if (r != rr) BN_copy(r,rr);
1108         ret=1;
1109 err:
1110         bn_check_top(r);
1111         BN_CTX_end(ctx);
1112         return(ret);
1113         }
1114
1115 void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
1116         {
1117         BN_ULONG *rr;
1118
1119 #ifdef BN_COUNT
1120         fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
1121 #endif
1122
1123         if (na < nb)
1124                 {
1125                 int itmp;
1126                 BN_ULONG *ltmp;
1127
1128                 itmp=na; na=nb; nb=itmp;
1129                 ltmp=a;   a=b;   b=ltmp;
1130
1131                 }
1132         rr= &(r[na]);
1133         if (nb <= 0)
1134                 {
1135                 (void)bn_mul_words(r,a,na,0);
1136                 return;
1137                 }
1138         else
1139                 rr[0]=bn_mul_words(r,a,na,b[0]);
1140
1141         for (;;)
1142                 {
1143                 if (--nb <= 0) return;
1144                 rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
1145                 if (--nb <= 0) return;
1146                 rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
1147                 if (--nb <= 0) return;
1148                 rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
1149                 if (--nb <= 0) return;
1150                 rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
1151                 rr+=4;
1152                 r+=4;
1153                 b+=4;
1154                 }
1155         }
1156
1157 void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
1158         {
1159 #ifdef BN_COUNT
1160         fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
1161 #endif
1162         bn_mul_words(r,a,n,b[0]);
1163
1164         for (;;)
1165                 {
1166                 if (--n <= 0) return;
1167                 bn_mul_add_words(&(r[1]),a,n,b[1]);
1168                 if (--n <= 0) return;
1169                 bn_mul_add_words(&(r[2]),a,n,b[2]);
1170                 if (--n <= 0) return;
1171                 bn_mul_add_words(&(r[3]),a,n,b[3]);
1172                 if (--n <= 0) return;
1173                 bn_mul_add_words(&(r[4]),a,n,b[4]);
1174                 r+=4;
1175                 b+=4;
1176                 }
1177         }