LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/bn - bn_add.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 90 98 91.8 %
Date: 2015-10-10 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* crypto/bn/bn_add.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             : #include <stdio.h>
      60             : #include "cryptlib.h"
      61             : #include "bn_lcl.h"
      62             : 
      63             : /* r can == a or b */
      64     1786016 : int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
      65             : {
      66             :     const BIGNUM *tmp;
      67     1786016 :     int a_neg = a->neg, ret;
      68             : 
      69             :     bn_check_top(a);
      70             :     bn_check_top(b);
      71             : 
      72             :     /*-
      73             :      *  a +  b      a+b
      74             :      *  a + -b      a-b
      75             :      * -a +  b      b-a
      76             :      * -a + -b      -(a+b)
      77             :      */
      78     1786016 :     if (a_neg ^ b->neg) {
      79             :         /* only one is negative */
      80     1515059 :         if (a_neg) {
      81             :             tmp = a;
      82             :             a = b;
      83             :             b = tmp;
      84             :         }
      85             : 
      86             :         /* we are now a - b */
      87             : 
      88     1515059 :         if (BN_ucmp(a, b) < 0) {
      89           0 :             if (!BN_usub(r, b, a))
      90             :                 return (0);
      91           0 :             r->neg = 1;
      92             :         } else {
      93     1515059 :             if (!BN_usub(r, a, b))
      94             :                 return (0);
      95     1515059 :             r->neg = 0;
      96             :         }
      97             :         return (1);
      98             :     }
      99             : 
     100      270957 :     ret = BN_uadd(r, a, b);
     101      270957 :     r->neg = a_neg;
     102             :     bn_check_top(r);
     103      270957 :     return ret;
     104             : }
     105             : 
     106             : /* unsigned add of b to a */
     107     3239455 : int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
     108             : {
     109             :     int max, min, dif;
     110             :     BN_ULONG *ap, *bp, *rp, carry, t1, t2;
     111             :     const BIGNUM *tmp;
     112             : 
     113             :     bn_check_top(a);
     114             :     bn_check_top(b);
     115             : 
     116     3239455 :     if (a->top < b->top) {
     117             :         tmp = a;
     118             :         a = b;
     119             :         b = tmp;
     120             :     }
     121     3239455 :     max = a->top;
     122     3239455 :     min = b->top;
     123     3239455 :     dif = max - min;
     124             : 
     125     3239455 :     if (bn_wexpand(r, max + 1) == NULL)
     126             :         return 0;
     127             : 
     128     3239455 :     r->top = max;
     129             : 
     130     3239455 :     ap = a->d;
     131     3239455 :     bp = b->d;
     132     3239455 :     rp = r->d;
     133             : 
     134     3239455 :     carry = bn_add_words(rp, ap, bp, min);
     135     3239455 :     rp += min;
     136     3239455 :     ap += min;
     137             :     bp += min;
     138             : 
     139     3239455 :     if (carry) {
     140     1606830 :         while (dif) {
     141      418514 :             dif--;
     142      418514 :             t1 = *(ap++);
     143      418514 :             t2 = (t1 + 1) & BN_MASK2;
     144      418514 :             *(rp++) = t2;
     145      418514 :             if (t2) {
     146             :                 carry = 0;
     147             :                 break;
     148             :             }
     149             :         }
     150     1606830 :         if (carry) {
     151             :             /* carry != 0 => dif == 0 */
     152     1188316 :             *rp = 1;
     153     1188316 :             r->top++;
     154             :         }
     155             :     }
     156     3239455 :     if (dif && rp != ap)
     157      119989 :         while (dif--)
     158             :             /* copy remaining words if ap != rp */
     159       68374 :             *(rp++) = *(ap++);
     160     3239455 :     r->neg = 0;
     161             :     bn_check_top(r);
     162     3239455 :     return 1;
     163             : }
     164             : 
     165             : /* unsigned subtraction of b from a, a must be larger than b. */
     166     8666737 : int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
     167             : {
     168             :     int max, min, dif;
     169             :     register BN_ULONG t1, t2, *ap, *bp, *rp;
     170             :     int i, carry;
     171             : #if defined(IRIX_CC_BUG) && !defined(LINT)
     172             :     int dummy;
     173             : #endif
     174             : 
     175             :     bn_check_top(a);
     176             :     bn_check_top(b);
     177             : 
     178     8666737 :     max = a->top;
     179     8666737 :     min = b->top;
     180     8666737 :     dif = max - min;
     181             : 
     182     8666737 :     if (dif < 0) {              /* hmm... should not be happening */
     183           0 :         BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3);
     184           0 :         return (0);
     185             :     }
     186             : 
     187     8666737 :     if (bn_wexpand(r, max) == NULL)
     188             :         return (0);
     189             : 
     190     8666737 :     ap = a->d;
     191     8666737 :     bp = b->d;
     192     8666737 :     rp = r->d;
     193             : 
     194             : #if 1
     195             :     carry = 0;
     196    41699400 :     for (i = min; i != 0; i--) {
     197    33032663 :         t1 = *(ap++);
     198    33032663 :         t2 = *(bp++);
     199    33032663 :         if (carry) {
     200    11384976 :             carry = (t1 <= t2);
     201    11384976 :             t1 = (t1 - t2 - 1) & BN_MASK2;
     202             :         } else {
     203    21647687 :             carry = (t1 < t2);
     204    21647687 :             t1 = (t1 - t2) & BN_MASK2;
     205             :         }
     206             : # if defined(IRIX_CC_BUG) && !defined(LINT)
     207             :         dummy = t1;
     208             : # endif
     209    33032663 :         *(rp++) = t1 & BN_MASK2;
     210             :     }
     211             : #else
     212             :     carry = bn_sub_words(rp, ap, bp, min);
     213             :     ap += min;
     214             :     bp += min;
     215             :     rp += min;
     216             : #endif
     217     8666737 :     if (carry) {                /* subtracted */
     218     3195906 :         if (!dif)
     219             :             /* error: a < b */
     220             :             return 0;
     221     3195906 :         while (dif) {
     222     3195906 :             dif--;
     223     3195906 :             t1 = *(ap++);
     224     3195906 :             t2 = (t1 - 1) & BN_MASK2;
     225     3195906 :             *(rp++) = t2;
     226     3195906 :             if (t1)
     227             :                 break;
     228             :         }
     229             :     }
     230             : #if 0
     231             :     memcpy(rp, ap, sizeof(*rp) * (max - i));
     232             : #else
     233     8666737 :     if (rp != ap) {
     234             :         for (;;) {
     235     4177026 :             if (!dif--)
     236             :                 break;
     237          24 :             rp[0] = ap[0];
     238          24 :             if (!dif--)
     239             :                 break;
     240          24 :             rp[1] = ap[1];
     241          24 :             if (!dif--)
     242             :                 break;
     243          24 :             rp[2] = ap[2];
     244          24 :             if (!dif--)
     245             :                 break;
     246          12 :             rp[3] = ap[3];
     247          12 :             rp += 4;
     248          12 :             ap += 4;
     249          12 :         }
     250             :     }
     251             : #endif
     252             : 
     253     8666737 :     r->top = max;
     254     8666737 :     r->neg = 0;
     255     8666737 :     bn_correct_top(r);
     256             :     return (1);
     257             : }
     258             : 
     259     5488798 : int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
     260             : {
     261             :     int max;
     262             :     int add = 0, neg = 0;
     263             :     const BIGNUM *tmp;
     264             : 
     265             :     bn_check_top(a);
     266             :     bn_check_top(b);
     267             : 
     268             :     /*-
     269             :      *  a -  b      a-b
     270             :      *  a - -b      a+b
     271             :      * -a -  b      -(a+b)
     272             :      * -a - -b      b-a
     273             :      */
     274     5488798 :     if (a->neg) {
     275           0 :         if (b->neg) {
     276             :             tmp = a;
     277             :             a = b;
     278             :             b = tmp;
     279             :         } else {
     280             :             add = 1;
     281             :             neg = 1;
     282             :         }
     283             :     } else {
     284     5488798 :         if (b->neg) {
     285             :             add = 1;
     286             :             neg = 0;
     287             :         }
     288             :     }
     289             : 
     290     5488798 :     if (add) {
     291           0 :         if (!BN_uadd(r, a, b))
     292             :             return (0);
     293           0 :         r->neg = neg;
     294           0 :         return (1);
     295             :     }
     296             : 
     297             :     /* We are actually doing a - b :-) */
     298             : 
     299     5488798 :     max = (a->top > b->top) ? a->top : b->top;
     300     5488798 :     if (bn_wexpand(r, max) == NULL)
     301             :         return (0);
     302     5488798 :     if (BN_ucmp(a, b) < 0) {
     303     1515059 :         if (!BN_usub(r, b, a))
     304             :             return (0);
     305     1515059 :         r->neg = 1;
     306             :     } else {
     307     3973739 :         if (!BN_usub(r, a, b))
     308             :             return (0);
     309     3973739 :         r->neg = 0;
     310             :     }
     311             :     bn_check_top(r);
     312             :     return (1);
     313             : }

Generated by: LCOV version 1.10