LCOV - code coverage report
Current view: top level - bn - bn_mul.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 188 476 39.5 %
Date: 2014-08-02 Functions: 5 9 55.6 %
Branches: 109 308 35.4 %

           Branch data     Line data    Source code
       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                 :      11948 : 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                 :      11948 :         c = bn_sub_words(r, a, b, cl);
      88                 :            : 
      89         [ +  + ]:      11948 :         if (dl == 0)
      90                 :            :                 return c;
      91                 :            : 
      92                 :        540 :         r += cl;
      93                 :        540 :         a += cl;
      94                 :        540 :         b += cl;
      95                 :            : 
      96         [ +  - ]:        540 :         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                 :          0 :                         t = b[0];
     104                 :          0 :                         r[0] = (0-t-c)&BN_MASK2;
     105         [ #  # ]:          0 :                         if (t != 0) c=1;
     106         [ #  # ]:          0 :                         if (++dl >= 0) break;
     107                 :            : 
     108                 :          0 :                         t = b[1];
     109                 :          0 :                         r[1] = (0-t-c)&BN_MASK2;
     110         [ #  # ]:          0 :                         if (t != 0) c=1;
     111         [ #  # ]:          0 :                         if (++dl >= 0) break;
     112                 :            : 
     113                 :          0 :                         t = b[2];
     114                 :          0 :                         r[2] = (0-t-c)&BN_MASK2;
     115         [ #  # ]:          0 :                         if (t != 0) c=1;
     116         [ #  # ]:          0 :                         if (++dl >= 0) break;
     117                 :            : 
     118                 :          0 :                         t = b[3];
     119                 :          0 :                         r[3] = (0-t-c)&BN_MASK2;
     120         [ #  # ]:          0 :                         if (t != 0) c=1;
     121         [ #  # ]:          0 :                         if (++dl >= 0) break;
     122                 :            : 
     123                 :          0 :                         b += 4;
     124                 :          0 :                         r += 4;
     125                 :          0 :                         }
     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         [ +  + ]:        600 :                 while(c)
     134                 :            :                         {
     135                 :         60 :                         t = a[0];
     136                 :         60 :                         r[0] = (t-c)&BN_MASK2;
     137         [ +  + ]:         60 :                         if (t != 0) c=0;
     138         [ +  - ]:         60 :                         if (--dl <= 0) break;
     139                 :            : 
     140                 :         60 :                         t = a[1];
     141                 :         60 :                         r[1] = (t-c)&BN_MASK2;
     142         [ +  - ]:         60 :                         if (t != 0) c=0;
     143         [ +  - ]:         60 :                         if (--dl <= 0) break;
     144                 :            : 
     145                 :         60 :                         t = a[2];
     146                 :         60 :                         r[2] = (t-c)&BN_MASK2;
     147         [ +  + ]:         60 :                         if (t != 0) c=0;
     148         [ +  - ]:         60 :                         if (--dl <= 0) break;
     149                 :            : 
     150                 :         60 :                         t = a[3];
     151                 :         60 :                         r[3] = (t-c)&BN_MASK2;
     152         [ +  - ]:         60 :                         if (t != 0) c=0;
     153         [ +  - ]:         60 :                         if (--dl <= 0) break;
     154                 :            : 
     155                 :         60 :                         save_dl = dl;
     156                 :         60 :                         a += 4;
     157                 :         60 :                         r += 4;
     158                 :            :                         }
     159         [ +  - ]:        540 :                 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         [ -  + ]:        540 :                         if (save_dl > dl)
     165                 :            :                                 {
     166   [ #  #  #  # ]:          0 :                                 switch (save_dl - dl)
     167                 :            :                                         {
     168                 :            :                                 case 1:
     169                 :          0 :                                         r[1] = a[1];
     170         [ #  # ]:          0 :                                         if (--dl <= 0) break;
     171                 :            :                                 case 2:
     172                 :          0 :                                         r[2] = a[2];
     173         [ #  # ]:          0 :                                         if (--dl <= 0) break;
     174                 :            :                                 case 3:
     175                 :          0 :                                         r[3] = a[3];
     176                 :          0 :                                         if (--dl <= 0) break;
     177                 :            :                                         }
     178                 :          0 :                                 a += 4;
     179                 :          0 :                                 r += 4;
     180                 :            :                                 }
     181                 :            :                         }
     182         [ +  - ]:        540 :                 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                 :       1758 :                                 r[0] = a[0];
     190         [ +  + ]:       1758 :                                 if (--dl <= 0) break;
     191                 :       1614 :                                 r[1] = a[1];
     192         [ +  + ]:       1614 :                                 if (--dl <= 0) break;
     193                 :       1464 :                                 r[2] = a[2];
     194         [ +  + ]:       1464 :                                 if (--dl <= 0) break;
     195                 :       1314 :                                 r[3] = a[3];
     196         [ +  + ]:       1314 :                                 if (--dl <= 0) break;
     197                 :            : 
     198                 :       1218 :                                 a += 4;
     199                 :       1218 :                                 r += 4;
     200                 :       1218 :                                 }
     201                 :            :                         }
     202                 :            :                 }
     203                 :        540 :         return c;
     204                 :            :         }
     205                 :            : #endif
     206                 :            : 
     207                 :          0 : 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                 :          0 :         c = bn_add_words(r, a, b, cl);
     215                 :            : 
     216         [ #  # ]:          0 :         if (dl == 0)
     217                 :            :                 return c;
     218                 :            : 
     219                 :          0 :         r += cl;
     220                 :          0 :         a += cl;
     221                 :          0 :         b += cl;
     222                 :            : 
     223         [ #  # ]:          0 :         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         [ #  # ]:          0 :                 while (c)
     230                 :            :                         {
     231                 :          0 :                         l=(c+b[0])&BN_MASK2;
     232                 :          0 :                         c=(l < c);
     233                 :          0 :                         r[0]=l;
     234         [ #  # ]:          0 :                         if (++dl >= 0) break;
     235                 :            : 
     236                 :          0 :                         l=(c+b[1])&BN_MASK2;
     237                 :          0 :                         c=(l < c);
     238                 :          0 :                         r[1]=l;
     239         [ #  # ]:          0 :                         if (++dl >= 0) break;
     240                 :            : 
     241                 :          0 :                         l=(c+b[2])&BN_MASK2;
     242                 :          0 :                         c=(l < c);
     243                 :          0 :                         r[2]=l;
     244         [ #  # ]:          0 :                         if (++dl >= 0) break;
     245                 :            : 
     246                 :          0 :                         l=(c+b[3])&BN_MASK2;
     247                 :          0 :                         c=(l < c);
     248                 :          0 :                         r[3]=l;
     249         [ #  # ]:          0 :                         if (++dl >= 0) break;
     250                 :            : 
     251                 :          0 :                         save_dl = dl;
     252                 :          0 :                         b+=4;
     253                 :          0 :                         r+=4;
     254                 :            :                         }
     255         [ #  # ]:          0 :                 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         [ #  # ]:          0 :                         if (save_dl < dl)
     261                 :            :                                 {
     262   [ #  #  #  # ]:          0 :                                 switch (dl - save_dl)
     263                 :            :                                         {
     264                 :            :                                 case 1:
     265                 :          0 :                                         r[1] = b[1];
     266         [ #  # ]:          0 :                                         if (++dl >= 0) break;
     267                 :            :                                 case 2:
     268                 :          0 :                                         r[2] = b[2];
     269         [ #  # ]:          0 :                                         if (++dl >= 0) break;
     270                 :            :                                 case 3:
     271                 :          0 :                                         r[3] = b[3];
     272                 :          0 :                                         if (++dl >= 0) break;
     273                 :            :                                         }
     274                 :          0 :                                 b += 4;
     275                 :          0 :                                 r += 4;
     276                 :            :                                 }
     277                 :            :                         }
     278         [ #  # ]:          0 :                 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                 :          0 :                                 r[0] = b[0];
     286         [ #  # ]:          0 :                                 if (++dl >= 0) break;
     287                 :          0 :                                 r[1] = b[1];
     288         [ #  # ]:          0 :                                 if (++dl >= 0) break;
     289                 :          0 :                                 r[2] = b[2];
     290         [ #  # ]:          0 :                                 if (++dl >= 0) break;
     291                 :          0 :                                 r[3] = b[3];
     292         [ #  # ]:          0 :                                 if (++dl >= 0) break;
     293                 :            : 
     294                 :          0 :                                 b += 4;
     295                 :          0 :                                 r += 4;
     296                 :          0 :                                 }
     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         [ #  # ]:          0 :                 while (c)
     306                 :            :                         {
     307                 :          0 :                         t=(a[0]+c)&BN_MASK2;
     308                 :          0 :                         c=(t < c);
     309                 :          0 :                         r[0]=t;
     310         [ #  # ]:          0 :                         if (--dl <= 0) break;
     311                 :            : 
     312                 :          0 :                         t=(a[1]+c)&BN_MASK2;
     313                 :          0 :                         c=(t < c);
     314                 :          0 :                         r[1]=t;
     315         [ #  # ]:          0 :                         if (--dl <= 0) break;
     316                 :            : 
     317                 :          0 :                         t=(a[2]+c)&BN_MASK2;
     318                 :          0 :                         c=(t < c);
     319                 :          0 :                         r[2]=t;
     320         [ #  # ]:          0 :                         if (--dl <= 0) break;
     321                 :            : 
     322                 :          0 :                         t=(a[3]+c)&BN_MASK2;
     323                 :          0 :                         c=(t < c);
     324                 :          0 :                         r[3]=t;
     325         [ #  # ]:          0 :                         if (--dl <= 0) break;
     326                 :            : 
     327                 :          0 :                         save_dl = dl;
     328                 :          0 :                         a+=4;
     329                 :          0 :                         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         [ #  # ]:          0 :                 if (dl > 0)
     335                 :            :                         {
     336         [ #  # ]:          0 :                         if (save_dl > dl)
     337                 :            :                                 {
     338   [ #  #  #  # ]:          0 :                                 switch (save_dl - dl)
     339                 :            :                                         {
     340                 :            :                                 case 1:
     341                 :          0 :                                         r[1] = a[1];
     342         [ #  # ]:          0 :                                         if (--dl <= 0) break;
     343                 :            :                                 case 2:
     344                 :          0 :                                         r[2] = a[2];
     345         [ #  # ]:          0 :                                         if (--dl <= 0) break;
     346                 :            :                                 case 3:
     347                 :          0 :                                         r[3] = a[3];
     348                 :          0 :                                         if (--dl <= 0) break;
     349                 :            :                                         }
     350                 :          0 :                                 a += 4;
     351                 :          0 :                                 r += 4;
     352                 :            :                                 }
     353                 :            :                         }
     354         [ #  # ]:          0 :                 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                 :          0 :                                 r[0] = a[0];
     362         [ #  # ]:          0 :                                 if (--dl <= 0) break;
     363                 :          0 :                                 r[1] = a[1];
     364         [ #  # ]:          0 :                                 if (--dl <= 0) break;
     365                 :          0 :                                 r[2] = a[2];
     366         [ #  # ]:          0 :                                 if (--dl <= 0) break;
     367                 :          0 :                                 r[3] = a[3];
     368         [ #  # ]:          0 :                                 if (--dl <= 0) break;
     369                 :            : 
     370                 :          0 :                                 a += 4;
     371                 :          0 :                                 r += 4;
     372                 :          0 :                                 }
     373                 :            :                         }
     374                 :            :                 }
     375                 :          0 :         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                 :            : /* r is 2*n2 words in size,
     383                 :            :  * a and b are both n2 words in size.
     384                 :            :  * n2 must be a power of 2.
     385                 :            :  * We multiply and return the result.
     386                 :            :  * t must be 2*n2 words in size
     387                 :            :  * We calculate
     388                 :            :  * a[0]*b[0]
     389                 :            :  * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
     390                 :            :  * a[1]*b[1]
     391                 :            :  */
     392                 :            : /* dnX may not be positive, but n2/2+dnX has to be */
     393                 :       5728 : void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
     394                 :            :         int dna, int dnb, BN_ULONG *t)
     395                 :            :         {
     396                 :       5728 :         int n=n2/2,c1,c2;
     397                 :       5728 :         int tna=n+dna, tnb=n+dnb;
     398                 :            :         unsigned int neg,zero;
     399                 :            :         BN_ULONG ln,lo,*p;
     400                 :            : 
     401                 :            : # ifdef BN_COUNT
     402                 :            :         fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
     403                 :            : # endif
     404                 :            : # ifdef BN_MUL_COMBA
     405                 :            : #  if 0
     406                 :            :         if (n2 == 4)
     407                 :            :                 {
     408                 :            :                 bn_mul_comba4(r,a,b);
     409                 :            :                 return;
     410                 :            :                 }
     411                 :            : #  endif
     412                 :            :         /* Only call bn_mul_comba 8 if n2 == 8 and the
     413                 :            :          * two arrays are complete [steve]
     414                 :            :          */
     415 [ -  + ][ #  # ]:       5728 :         if (n2 == 8 && dna == 0 && dnb == 0)
     416                 :            :                 {
     417                 :          0 :                 bn_mul_comba8(r,a,b);
     418                 :          0 :                 return; 
     419                 :            :                 }
     420                 :            : # endif /* BN_MUL_COMBA */
     421                 :            :         /* Else do normal multiply */
     422         [ +  + ]:       5728 :         if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
     423                 :            :                 {
     424                 :         24 :                 bn_mul_normal(r,a,n2+dna,b,n2+dnb);
     425         [ +  - ]:         24 :                 if ((dna + dnb) < 0)
     426                 :         24 :                         memset(&r[2*n2 + dna + dnb], 0,
     427                 :         24 :                                 sizeof(BN_ULONG) * -(dna + dnb));
     428                 :            :                 return;
     429                 :            :                 }
     430                 :            :         /* r=(a[0]-a[1])*(b[1]-b[0]) */
     431                 :       5704 :         c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
     432                 :       5704 :         c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
     433                 :       5704 :         zero=neg=0;
     434   [ +  -  +  -  :       5704 :         switch (c1*3+c2)
             +  -  +  - ]
     435                 :            :                 {
     436                 :            :         case -4:
     437                 :       1115 :                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
     438                 :       1115 :                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
     439                 :       1115 :                 break;
     440                 :            :         case -3:
     441                 :          0 :                 zero=1;
     442                 :          0 :                 break;
     443                 :            :         case -2:
     444                 :        893 :                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
     445                 :        893 :                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
     446                 :        893 :                 neg=1;
     447                 :        893 :                 break;
     448                 :            :         case -1:
     449                 :            :         case 0:
     450                 :            :         case 1:
     451                 :          0 :                 zero=1;
     452                 :          0 :                 break;
     453                 :            :         case 2:
     454                 :       2214 :                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
     455                 :       2214 :                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
     456                 :       2214 :                 neg=1;
     457                 :       2214 :                 break;
     458                 :            :         case 3:
     459                 :          0 :                 zero=1;
     460                 :          0 :                 break;
     461                 :            :         case 4:
     462                 :       1482 :                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
     463                 :       1482 :                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
     464                 :       1482 :                 break;
     465                 :            :                 }
     466                 :            : 
     467                 :            : # ifdef BN_MUL_COMBA
     468 [ -  + ][ #  # ]:       5704 :         if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
     469                 :            :                                                extra args to do this well */
     470                 :            :                 {
     471         [ #  # ]:          0 :                 if (!zero)
     472                 :          0 :                         bn_mul_comba4(&(t[n2]),t,&(t[n]));
     473                 :            :                 else
     474                 :          0 :                         memset(&(t[n2]),0,8*sizeof(BN_ULONG));
     475                 :            :                 
     476                 :          0 :                 bn_mul_comba4(r,a,b);
     477                 :          0 :                 bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
     478                 :            :                 }
     479 [ +  + ][ +  - ]:       5704 :         else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
     480                 :            :                                                     take extra args to do this
     481                 :            :                                                     well */
     482                 :            :                 {
     483         [ +  - ]:       5138 :                 if (!zero)
     484                 :       5138 :                         bn_mul_comba8(&(t[n2]),t,&(t[n]));
     485                 :            :                 else
     486                 :          0 :                         memset(&(t[n2]),0,16*sizeof(BN_ULONG));
     487                 :            :                 
     488                 :       5138 :                 bn_mul_comba8(r,a,b);
     489                 :       5138 :                 bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
     490                 :            :                 }
     491                 :            :         else
     492                 :            : # endif /* BN_MUL_COMBA */
     493                 :            :                 {
     494                 :        566 :                 p= &(t[n2*2]);
     495         [ +  - ]:        566 :                 if (!zero)
     496                 :        566 :                         bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
     497                 :            :                 else
     498                 :          0 :                         memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
     499                 :        566 :                 bn_mul_recursive(r,a,b,n,0,0,p);
     500                 :        566 :                 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
     501                 :            :                 }
     502                 :            : 
     503                 :            :         /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
     504                 :            :          * r[10] holds (a[0]*b[0])
     505                 :            :          * r[32] holds (b[1]*b[1])
     506                 :            :          */
     507                 :            : 
     508                 :       5704 :         c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
     509                 :            : 
     510         [ +  + ]:       5704 :         if (neg) /* if t[32] is negative */
     511                 :            :                 {
     512                 :       3107 :                 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
     513                 :            :                 }
     514                 :            :         else
     515                 :            :                 {
     516                 :            :                 /* Might have a carry */
     517                 :       2597 :                 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
     518                 :            :                 }
     519                 :            : 
     520                 :            :         /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
     521                 :            :          * r[10] holds (a[0]*b[0])
     522                 :            :          * r[32] holds (b[1]*b[1])
     523                 :            :          * c1 holds the carry bits
     524                 :            :          */
     525                 :       5704 :         c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
     526         [ +  + ]:       5704 :         if (c1)
     527                 :            :                 {
     528                 :       2538 :                 p= &(r[n+n2]);
     529                 :       2538 :                 lo= *p;
     530                 :       2538 :                 ln=(lo+c1)&BN_MASK2;
     531                 :       2538 :                 *p=ln;
     532                 :            : 
     533                 :            :                 /* The overflow will stop before we over write
     534                 :            :                  * words we should not overwrite */
     535         [ -  + ]:       2538 :                 if (ln < (BN_ULONG)c1)
     536                 :            :                         {
     537                 :            :                         do      {
     538                 :          0 :                                 p++;
     539                 :          0 :                                 lo= *p;
     540                 :          0 :                                 ln=(lo+1)&BN_MASK2;
     541                 :          0 :                                 *p=ln;
     542         [ #  # ]:          0 :                                 } while (ln == 0);
     543                 :            :                         }
     544                 :            :                 }
     545                 :            :         }
     546                 :            : 
     547                 :            : /* n+tn is the word length
     548                 :            :  * t needs to be n*4 is size, as does r */
     549                 :            : /* tnX may not be negative but less than n */
     550                 :        270 : void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
     551                 :            :              int tna, int tnb, BN_ULONG *t)
     552                 :            :         {
     553                 :        270 :         int i,j,n2=n*2;
     554                 :            :         int c1,c2,neg;
     555                 :            :         BN_ULONG ln,lo,*p;
     556                 :            : 
     557                 :            : # ifdef BN_COUNT
     558                 :            :         fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
     559                 :            :                 n, tna, n, tnb);
     560                 :            : # endif
     561         [ -  + ]:        270 :         if (n < 8)
     562                 :            :                 {
     563                 :          0 :                 bn_mul_normal(r,a,n+tna,b,n+tnb);
     564                 :          0 :                 return;
     565                 :            :                 }
     566                 :            : 
     567                 :            :         /* r=(a[0]-a[1])*(b[1]-b[0]) */
     568                 :        270 :         c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
     569                 :        270 :         c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
     570                 :        270 :         neg=0;
     571   [ -  -  +  -  :        270 :         switch (c1*3+c2)
                      - ]
     572                 :            :                 {
     573                 :            :         case -4:
     574                 :          0 :                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
     575                 :          0 :                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
     576                 :          0 :                 break;
     577                 :            :         case -3:
     578                 :            :                 /* break; */
     579                 :            :         case -2:
     580                 :          0 :                 bn_sub_part_words(t,      &(a[n]),a,      tna,tna-n); /* - */
     581                 :          0 :                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n); /* + */
     582                 :          0 :                 neg=1;
     583                 :          0 :                 break;
     584                 :            :         case -1:
     585                 :            :         case 0:
     586                 :            :         case 1:
     587                 :            :                 /* break; */
     588                 :            :         case 2:
     589                 :        270 :                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna); /* + */
     590                 :        270 :                 bn_sub_part_words(&(t[n]),b,      &(b[n]),tnb,n-tnb); /* - */
     591                 :        270 :                 neg=1;
     592                 :        270 :                 break;
     593                 :            :         case 3:
     594                 :            :                 /* break; */
     595                 :            :         case 4:
     596                 :          0 :                 bn_sub_part_words(t,      a,      &(a[n]),tna,n-tna);
     597                 :          0 :                 bn_sub_part_words(&(t[n]),&(b[n]),b,      tnb,tnb-n);
     598                 :          0 :                 break;
     599                 :            :                 }
     600                 :            :                 /* The zero case isn't yet implemented here. The speedup
     601                 :            :                    would probably be negligible. */
     602                 :            : # if 0
     603                 :            :         if (n == 4)
     604                 :            :                 {
     605                 :            :                 bn_mul_comba4(&(t[n2]),t,&(t[n]));
     606                 :            :                 bn_mul_comba4(r,a,b);
     607                 :            :                 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
     608                 :            :                 memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
     609                 :            :                 }
     610                 :            :         else
     611                 :            : # endif
     612         [ -  + ]:        270 :         if (n == 8)
     613                 :            :                 {
     614                 :          0 :                 bn_mul_comba8(&(t[n2]),t,&(t[n]));
     615                 :          0 :                 bn_mul_comba8(r,a,b);
     616                 :          0 :                 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
     617                 :          0 :                 memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
     618                 :            :                 }
     619                 :            :         else
     620                 :            :                 {
     621                 :        270 :                 p= &(t[n2*2]);
     622                 :        270 :                 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
     623                 :        270 :                 bn_mul_recursive(r,a,b,n,0,0,p);
     624                 :        270 :                 i=n/2;
     625                 :            :                 /* If there is only a bottom half to the number,
     626                 :            :                  * just do it */
     627         [ -  + ]:        270 :                 if (tna > tnb)
     628                 :          0 :                         j = tna - i;
     629                 :            :                 else
     630                 :        270 :                         j = tnb - i;
     631         [ +  + ]:        270 :                 if (j == 0)
     632                 :            :                         {
     633                 :         24 :                         bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
     634                 :            :                                 i,tna-i,tnb-i,p);
     635                 :         24 :                         memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
     636                 :            :                         }
     637         [ -  + ]:        246 :                 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
     638                 :            :                                 {
     639                 :          0 :                                 bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
     640                 :            :                                         i,tna-i,tnb-i,p);
     641                 :          0 :                                 memset(&(r[n2+tna+tnb]),0,
     642                 :          0 :                                         sizeof(BN_ULONG)*(n2-tna-tnb));
     643                 :            :                                 }
     644                 :            :                 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
     645                 :            :                         {
     646                 :        246 :                         memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
     647         [ +  - ]:        246 :                         if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
     648                 :        246 :                                 && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
     649                 :            :                                 {
     650                 :        246 :                                 bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
     651                 :            :                                 }
     652                 :            :                         else
     653                 :            :                                 {
     654                 :            :                                 for (;;)
     655                 :            :                                         {
     656                 :          0 :                                         i/=2;
     657                 :            :                                         /* these simplified conditions work
     658                 :            :                                          * exclusively because difference
     659                 :            :                                          * between tna and tnb is 1 or 0 */
     660         [ #  # ]:          0 :                                         if (i < tna || i < tnb)
     661                 :            :                                                 {
     662                 :          0 :                                                 bn_mul_part_recursive(&(r[n2]),
     663                 :            :                                                         &(a[n]),&(b[n]),
     664                 :            :                                                         i,tna-i,tnb-i,p);
     665                 :          0 :                                                 break;
     666                 :            :                                                 }
     667         [ #  # ]:          0 :                                         else if (i == tna || i == tnb)
     668                 :            :                                                 {
     669                 :          0 :                                                 bn_mul_recursive(&(r[n2]),
     670                 :            :                                                         &(a[n]),&(b[n]),
     671                 :            :                                                         i,tna-i,tnb-i,p);
     672                 :          0 :                                                 break;
     673                 :            :                                                 }
     674                 :            :                                         }
     675                 :            :                                 }
     676                 :            :                         }
     677                 :            :                 }
     678                 :            : 
     679                 :            :         /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
     680                 :            :          * r[10] holds (a[0]*b[0])
     681                 :            :          * r[32] holds (b[1]*b[1])
     682                 :            :          */
     683                 :            : 
     684                 :        270 :         c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
     685                 :            : 
     686         [ +  - ]:        270 :         if (neg) /* if t[32] is negative */
     687                 :            :                 {
     688                 :        270 :                 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
     689                 :            :                 }
     690                 :            :         else
     691                 :            :                 {
     692                 :            :                 /* Might have a carry */
     693                 :          0 :                 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
     694                 :            :                 }
     695                 :            : 
     696                 :            :         /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
     697                 :            :          * r[10] holds (a[0]*b[0])
     698                 :            :          * r[32] holds (b[1]*b[1])
     699                 :            :          * c1 holds the carry bits
     700                 :            :          */
     701                 :        270 :         c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
     702         [ -  + ]:        270 :         if (c1)
     703                 :            :                 {
     704                 :          0 :                 p= &(r[n+n2]);
     705                 :          0 :                 lo= *p;
     706                 :          0 :                 ln=(lo+c1)&BN_MASK2;
     707                 :          0 :                 *p=ln;
     708                 :            : 
     709                 :            :                 /* The overflow will stop before we over write
     710                 :            :                  * words we should not overwrite */
     711         [ #  # ]:          0 :                 if (ln < (BN_ULONG)c1)
     712                 :            :                         {
     713                 :            :                         do      {
     714                 :          0 :                                 p++;
     715                 :          0 :                                 lo= *p;
     716                 :          0 :                                 ln=(lo+1)&BN_MASK2;
     717                 :          0 :                                 *p=ln;
     718         [ #  # ]:          0 :                                 } while (ln == 0);
     719                 :            :                         }
     720                 :            :                 }
     721                 :            :         }
     722                 :            : 
     723                 :            : /* a and b must be the same size, which is n2.
     724                 :            :  * r needs to be n2 words and t needs to be n2*2
     725                 :            :  */
     726                 :          0 : void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
     727                 :            :              BN_ULONG *t)
     728                 :            :         {
     729                 :          0 :         int n=n2/2;
     730                 :            : 
     731                 :            : # ifdef BN_COUNT
     732                 :            :         fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
     733                 :            : # endif
     734                 :            : 
     735                 :          0 :         bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
     736         [ #  # ]:          0 :         if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
     737                 :            :                 {
     738                 :          0 :                 bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
     739                 :          0 :                 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
     740                 :          0 :                 bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
     741                 :          0 :                 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
     742                 :            :                 }
     743                 :            :         else
     744                 :            :                 {
     745                 :          0 :                 bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
     746                 :          0 :                 bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
     747                 :          0 :                 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
     748                 :          0 :                 bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
     749                 :            :                 }
     750                 :          0 :         }
     751                 :            : 
     752                 :            : /* a and b must be the same size, which is n2.
     753                 :            :  * r needs to be n2 words and t needs to be n2*2
     754                 :            :  * l is the low words of the output.
     755                 :            :  * t needs to be n2*3
     756                 :            :  */
     757                 :          0 : void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
     758                 :            :              BN_ULONG *t)
     759                 :            :         {
     760                 :            :         int i,n;
     761                 :            :         int c1,c2;
     762                 :            :         int neg,oneg,zero;
     763                 :            :         BN_ULONG ll,lc,*lp,*mp;
     764                 :            : 
     765                 :            : # ifdef BN_COUNT
     766                 :            :         fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
     767                 :            : # endif
     768                 :          0 :         n=n2/2;
     769                 :            : 
     770                 :            :         /* Calculate (al-ah)*(bh-bl) */
     771                 :          0 :         neg=zero=0;
     772                 :          0 :         c1=bn_cmp_words(&(a[0]),&(a[n]),n);
     773                 :          0 :         c2=bn_cmp_words(&(b[n]),&(b[0]),n);
     774   [ #  #  #  #  :          0 :         switch (c1*3+c2)
                      # ]
     775                 :            :                 {
     776                 :            :         case -4:
     777                 :          0 :                 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
     778                 :          0 :                 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
     779                 :          0 :                 break;
     780                 :            :         case -3:
     781                 :            :                 zero=1;
     782                 :            :                 break;
     783                 :            :         case -2:
     784                 :          0 :                 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
     785                 :          0 :                 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
     786                 :          0 :                 neg=1;
     787                 :          0 :                 break;
     788                 :            :         case -1:
     789                 :            :         case 0:
     790                 :            :         case 1:
     791                 :            :                 zero=1;
     792                 :            :                 break;
     793                 :            :         case 2:
     794                 :          0 :                 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
     795                 :          0 :                 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
     796                 :          0 :                 neg=1;
     797                 :          0 :                 break;
     798                 :            :         case 3:
     799                 :            :                 zero=1;
     800                 :            :                 break;
     801                 :            :         case 4:
     802                 :          0 :                 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
     803                 :          0 :                 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
     804                 :          0 :                 break;
     805                 :            :                 }
     806                 :            :                 
     807                 :          0 :         oneg=neg;
     808                 :            :         /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
     809                 :            :         /* r[10] = (a[1]*b[1]) */
     810                 :            : # ifdef BN_MUL_COMBA
     811         [ #  # ]:          0 :         if (n == 8)
     812                 :            :                 {
     813                 :          0 :                 bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
     814                 :          0 :                 bn_mul_comba8(r,&(a[n]),&(b[n]));
     815                 :            :                 }
     816                 :            :         else
     817                 :            : # endif
     818                 :            :                 {
     819                 :          0 :                 bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
     820                 :          0 :                 bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
     821                 :            :                 }
     822                 :            : 
     823                 :            :         /* s0 == low(al*bl)
     824                 :            :          * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
     825                 :            :          * We know s0 and s1 so the only unknown is high(al*bl)
     826                 :            :          * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
     827                 :            :          * high(al*bl) == s1 - (r[0]+l[0]+t[0])
     828                 :            :          */
     829         [ #  # ]:          0 :         if (l != NULL)
     830                 :            :                 {
     831                 :          0 :                 lp= &(t[n2+n]);
     832                 :          0 :                 c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
     833                 :            :                 }
     834                 :            :         else
     835                 :            :                 {
     836                 :            :                 c1=0;
     837                 :            :                 lp= &(r[0]);
     838                 :            :                 }
     839                 :            : 
     840         [ #  # ]:          0 :         if (neg)
     841                 :          0 :                 neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
     842                 :            :         else
     843                 :            :                 {
     844                 :          0 :                 bn_add_words(&(t[n2]),lp,&(t[0]),n);
     845                 :          0 :                 neg=0;
     846                 :            :                 }
     847                 :            : 
     848         [ #  # ]:          0 :         if (l != NULL)
     849                 :            :                 {
     850                 :          0 :                 bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
     851                 :            :                 }
     852                 :            :         else
     853                 :            :                 {
     854                 :          0 :                 lp= &(t[n2+n]);
     855                 :          0 :                 mp= &(t[n2]);
     856         [ #  # ]:          0 :                 for (i=0; i<n; i++)
     857                 :          0 :                         lp[i]=((~mp[i])+1)&BN_MASK2;
     858                 :            :                 }
     859                 :            : 
     860                 :            :         /* s[0] = low(al*bl)
     861                 :            :          * t[3] = high(al*bl)
     862                 :            :          * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
     863                 :            :          * r[10] = (a[1]*b[1])
     864                 :            :          */
     865                 :            :         /* R[10] = al*bl
     866                 :            :          * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
     867                 :            :          * R[32] = ah*bh
     868                 :            :          */
     869                 :            :         /* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
     870                 :            :          * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
     871                 :            :          * R[3]=r[1]+(carry/borrow)
     872                 :            :          */
     873         [ #  # ]:          0 :         if (l != NULL)
     874                 :            :                 {
     875                 :          0 :                 lp= &(t[n2]);
     876                 :          0 :                 c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
     877                 :            :                 }
     878                 :            :         else
     879                 :            :                 {
     880                 :          0 :                 lp= &(t[n2+n]);
     881                 :          0 :                 c1=0;
     882                 :            :                 }
     883                 :          0 :         c1+=(int)(bn_add_words(&(t[n2]),lp,  &(r[0]),n));
     884         [ #  # ]:          0 :         if (oneg)
     885                 :          0 :                 c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
     886                 :            :         else
     887                 :          0 :                 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
     888                 :            : 
     889                 :          0 :         c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
     890                 :          0 :         c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
     891         [ #  # ]:          0 :         if (oneg)
     892                 :          0 :                 c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
     893                 :            :         else
     894                 :          0 :                 c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
     895                 :            :         
     896         [ #  # ]:          0 :         if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
     897                 :            :                 {
     898                 :          0 :                 i=0;
     899         [ #  # ]:          0 :                 if (c1 > 0)
     900                 :            :                         {
     901                 :          0 :                         lc=c1;
     902                 :            :                         do      {
     903                 :          0 :                                 ll=(r[i]+lc)&BN_MASK2;
     904                 :          0 :                                 r[i++]=ll;
     905                 :          0 :                                 lc=(lc > ll);
     906         [ #  # ]:          0 :                                 } while (lc);
     907                 :            :                         }
     908                 :            :                 else
     909                 :            :                         {
     910                 :          0 :                         lc= -c1;
     911                 :            :                         do      {
     912                 :          0 :                                 ll=r[i];
     913                 :          0 :                                 r[i++]=(ll-lc)&BN_MASK2;
     914                 :          0 :                                 lc=(lc > ll);
     915         [ #  # ]:          0 :                                 } while (lc);
     916                 :            :                         }
     917                 :            :                 }
     918         [ #  # ]:          0 :         if (c2 != 0) /* Add starting at r[1] */
     919                 :            :                 {
     920                 :          0 :                 i=n;
     921         [ #  # ]:          0 :                 if (c2 > 0)
     922                 :            :                         {
     923                 :          0 :                         lc=c2;
     924                 :            :                         do      {
     925                 :          0 :                                 ll=(r[i]+lc)&BN_MASK2;
     926                 :          0 :                                 r[i++]=ll;
     927                 :          0 :                                 lc=(lc > ll);
     928         [ #  # ]:          0 :                                 } while (lc);
     929                 :            :                         }
     930                 :            :                 else
     931                 :            :                         {
     932                 :          0 :                         lc= -c2;
     933                 :            :                         do      {
     934                 :          0 :                                 ll=r[i];
     935                 :          0 :                                 r[i++]=(ll-lc)&BN_MASK2;
     936                 :          0 :                                 lc=(lc > ll);
     937         [ #  # ]:          0 :                                 } while (lc);
     938                 :            :                         }
     939                 :            :                 }
     940                 :          0 :         }
     941                 :            : #endif /* BN_RECURSION */
     942                 :            : 
     943                 :    1051303 : int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
     944                 :            :         {
     945                 :    1051303 :         int ret=0;
     946                 :            :         int top,al,bl;
     947                 :            :         BIGNUM *rr;
     948                 :            : #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
     949                 :            :         int i;
     950                 :            : #endif
     951                 :            : #ifdef BN_RECURSION
     952                 :    1051303 :         BIGNUM *t=NULL;
     953                 :    1051303 :         int j=0,k;
     954                 :            : #endif
     955                 :            : 
     956                 :            : #ifdef BN_COUNT
     957                 :            :         fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
     958                 :            : #endif
     959                 :            : 
     960                 :            :         bn_check_top(a);
     961                 :            :         bn_check_top(b);
     962                 :            :         bn_check_top(r);
     963                 :            : 
     964                 :    1051303 :         al=a->top;
     965                 :    1051303 :         bl=b->top;
     966                 :            : 
     967         [ +  + ]:    1051303 :         if ((al == 0) || (bl == 0))
     968                 :            :                 {
     969                 :      11021 :                 BN_zero(r);
     970                 :      11021 :                 return(1);
     971                 :            :                 }
     972                 :    1040282 :         top=al+bl;
     973                 :            : 
     974                 :    1040282 :         BN_CTX_start(ctx);
     975         [ +  + ]:    1040282 :         if ((r == a) || (r == b))
     976                 :            :                 {
     977         [ +  - ]:        199 :                 if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
     978                 :            :                 }
     979                 :            :         else
     980                 :            :                 rr = r;
     981                 :    1040282 :         rr->neg=a->neg^b->neg;
     982                 :            : 
     983                 :            : #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
     984                 :    1040282 :         i = al-bl;
     985                 :            : #endif
     986                 :            : #ifdef BN_MUL_COMBA
     987         [ +  + ]:    1040282 :         if (i == 0)
     988                 :            :                 {
     989                 :            : # if 0
     990                 :            :                 if (al == 4)
     991                 :            :                         {
     992                 :            :                         if (bn_wexpand(rr,8) == NULL) goto err;
     993                 :            :                         rr->top=8;
     994                 :            :                         bn_mul_comba4(rr->d,a->d,b->d);
     995                 :            :                         goto end;
     996                 :            :                         }
     997                 :            : # endif
     998         [ +  + ]:     298681 :                 if (al == 8)
     999                 :            :                         {
    1000 [ +  + ][ +  - ]:     155356 :                         if (bn_wexpand(rr,16) == NULL) goto err;
    1001                 :     155356 :                         rr->top=16;
    1002                 :     155356 :                         bn_mul_comba8(rr->d,a->d,b->d);
    1003                 :     155356 :                         goto end;
    1004                 :            :                         }
    1005                 :            :                 }
    1006                 :            : #endif /* BN_MUL_COMBA */
    1007                 :            : #ifdef BN_RECURSION
    1008         [ +  + ]:     884926 :         if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
    1009                 :            :                 {
    1010         [ +  - ]:       3736 :                 if (i >= -1 && i <= 1)
    1011                 :            :                         {
    1012                 :            :                         /* Find out the power of two lower or equal
    1013                 :            :                            to the longest of the two numbers */
    1014         [ +  + ]:       3736 :                         if (i >= 0)
    1015                 :            :                                 {
    1016                 :       3622 :                                 j = BN_num_bits_word((BN_ULONG)al);
    1017                 :            :                                 }
    1018         [ +  + ]:       3736 :                         if (i == -1)
    1019                 :            :                                 {
    1020                 :        114 :                                 j = BN_num_bits_word((BN_ULONG)bl);
    1021                 :            :                                 }
    1022                 :       3736 :                         j = 1<<(j-1);
    1023                 :            :                         assert(j <= al || j <= bl);
    1024                 :       3736 :                         k = j+j;
    1025                 :       3736 :                         t = BN_CTX_get(ctx);
    1026         [ +  - ]:       3736 :                         if (t == NULL)
    1027                 :            :                                 goto err;
    1028         [ +  + ]:       3736 :                         if (al > j || bl > j)
    1029                 :            :                                 {
    1030 [ +  + ][ +  - ]:        270 :                                 if (bn_wexpand(t,k*4) == NULL) goto err;
    1031 [ +  + ][ +  - ]:        270 :                                 if (bn_wexpand(rr,k*4) == NULL) goto err;
    1032                 :        270 :                                 bn_mul_part_recursive(rr->d,a->d,b->d,
    1033                 :            :                                         j,al-j,bl-j,t->d);
    1034                 :            :                                 }
    1035                 :            :                         else    /* al <= j || bl <= j */
    1036                 :            :                                 {
    1037 [ +  + ][ +  - ]:       3466 :                                 if (bn_wexpand(t,k*2) == NULL) goto err;
    1038 [ +  + ][ +  - ]:       3466 :                                 if (bn_wexpand(rr,k*2) == NULL) goto err;
    1039                 :       3466 :                                 bn_mul_recursive(rr->d,a->d,b->d,
    1040                 :            :                                         j,al-j,bl-j,t->d);
    1041                 :            :                                 }
    1042                 :       3736 :                         rr->top=top;
    1043                 :       3736 :                         goto end;
    1044                 :            :                         }
    1045                 :            : #if 0
    1046                 :            :                 if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
    1047                 :            :                         {
    1048                 :            :                         BIGNUM *tmp_bn = (BIGNUM *)b;
    1049                 :            :                         if (bn_wexpand(tmp_bn,al) == NULL) goto err;
    1050                 :            :                         tmp_bn->d[bl]=0;
    1051                 :            :                         bl++;
    1052                 :            :                         i--;
    1053                 :            :                         }
    1054                 :            :                 else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
    1055                 :            :                         {
    1056                 :            :                         BIGNUM *tmp_bn = (BIGNUM *)a;
    1057                 :            :                         if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
    1058                 :            :                         tmp_bn->d[al]=0;
    1059                 :            :                         al++;
    1060                 :            :                         i++;
    1061                 :            :                         }
    1062                 :            :                 if (i == 0)
    1063                 :            :                         {
    1064                 :            :                         /* symmetric and > 4 */
    1065                 :            :                         /* 16 or larger */
    1066                 :            :                         j=BN_num_bits_word((BN_ULONG)al);
    1067                 :            :                         j=1<<(j-1);
    1068                 :            :                         k=j+j;
    1069                 :            :                         t = BN_CTX_get(ctx);
    1070                 :            :                         if (al == j) /* exact multiple */
    1071                 :            :                                 {
    1072                 :            :                                 if (bn_wexpand(t,k*2) == NULL) goto err;
    1073                 :            :                                 if (bn_wexpand(rr,k*2) == NULL) goto err;
    1074                 :            :                                 bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
    1075                 :            :                                 }
    1076                 :            :                         else
    1077                 :            :                                 {
    1078                 :            :                                 if (bn_wexpand(t,k*4) == NULL) goto err;
    1079                 :            :                                 if (bn_wexpand(rr,k*4) == NULL) goto err;
    1080                 :            :                                 bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
    1081                 :            :                                 }
    1082                 :            :                         rr->top=top;
    1083                 :            :                         goto end;
    1084                 :            :                         }
    1085                 :            : #endif
    1086                 :            :                 }
    1087                 :            : #endif /* BN_RECURSION */
    1088 [ +  + ][ +  - ]:     881190 :         if (bn_wexpand(rr,top) == NULL) goto err;
    1089                 :     881190 :         rr->top=top;
    1090                 :     881190 :         bn_mul_normal(rr->d,a->d,al,b->d,bl);
    1091                 :            : 
    1092                 :            : #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
    1093                 :            : end:
    1094                 :            : #endif
    1095 [ +  - ][ +  + ]:    1893292 :         bn_correct_top(rr);
                 [ +  - ]
    1096         [ +  + ]:    1040282 :         if (r != rr) BN_copy(r,rr);
    1097                 :            :         ret=1;
    1098                 :            : err:
    1099                 :            :         bn_check_top(r);
    1100                 :    1040282 :         BN_CTX_end(ctx);
    1101                 :    1040282 :         return(ret);
    1102                 :            :         }
    1103                 :            : 
    1104                 :     881460 : void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
    1105                 :            :         {
    1106                 :            :         BN_ULONG *rr;
    1107                 :            : 
    1108                 :            : #ifdef BN_COUNT
    1109                 :            :         fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
    1110                 :            : #endif
    1111                 :            : 
    1112         [ +  + ]:     881460 :         if (na < nb)
    1113                 :            :                 {
    1114                 :            :                 int itmp;
    1115                 :            :                 BN_ULONG *ltmp;
    1116                 :            : 
    1117                 :     735327 :                 itmp=na; na=nb; nb=itmp;
    1118                 :     735327 :                 ltmp=a;   a=b;   b=ltmp;
    1119                 :            : 
    1120                 :            :                 }
    1121                 :     881460 :         rr= &(r[na]);
    1122         [ -  + ]:     881460 :         if (nb <= 0)
    1123                 :            :                 {
    1124                 :          0 :                 (void)bn_mul_words(r,a,na,0);
    1125                 :          0 :                 return;
    1126                 :            :                 }
    1127                 :            :         else
    1128                 :     881460 :                 rr[0]=bn_mul_words(r,a,na,b[0]);
    1129                 :            : 
    1130                 :            :         for (;;)
    1131                 :            :                 {
    1132         [ +  + ]:    1038706 :                 if (--nb <= 0) return;
    1133                 :     232417 :                 rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
    1134         [ +  + ]:     232417 :                 if (--nb <= 0) return;
    1135                 :     230984 :                 rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
    1136         [ +  + ]:     230984 :                 if (--nb <= 0) return;
    1137                 :     222826 :                 rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
    1138         [ +  + ]:     222826 :                 if (--nb <= 0) return;
    1139                 :     157246 :                 rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
    1140                 :     157246 :                 rr+=4;
    1141                 :     157246 :                 r+=4;
    1142                 :     157246 :                 b+=4;
    1143                 :     157246 :                 }
    1144                 :            :         }
    1145                 :            : 
    1146                 :          0 : void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
    1147                 :            :         {
    1148                 :            : #ifdef BN_COUNT
    1149                 :            :         fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
    1150                 :            : #endif
    1151                 :          0 :         bn_mul_words(r,a,n,b[0]);
    1152                 :            : 
    1153                 :            :         for (;;)
    1154                 :            :                 {
    1155         [ #  # ]:          0 :                 if (--n <= 0) return;
    1156                 :          0 :                 bn_mul_add_words(&(r[1]),a,n,b[1]);
    1157         [ #  # ]:          0 :                 if (--n <= 0) return;
    1158                 :          0 :                 bn_mul_add_words(&(r[2]),a,n,b[2]);
    1159         [ #  # ]:          0 :                 if (--n <= 0) return;
    1160                 :          0 :                 bn_mul_add_words(&(r[3]),a,n,b[3]);
    1161         [ #  # ]:          0 :                 if (--n <= 0) return;
    1162                 :          0 :                 bn_mul_add_words(&(r[4]),a,n,b[4]);
    1163                 :          0 :                 r+=4;
    1164                 :          0 :                 b+=4;
    1165                 :          0 :                 }
    1166                 :            :         }

Generated by: LCOV version 1.9