/src/dropbear/libtommath/bn_mp_add_d.c
Line  | Count  | Source  | 
1  |  | #include "tommath_private.h"  | 
2  |  | #ifdef BN_MP_ADD_D_C  | 
3  |  | /* LibTomMath, multiple-precision integer library -- Tom St Denis */  | 
4  |  | /* SPDX-License-Identifier: Unlicense */  | 
5  |  |  | 
6  |  | /* single digit addition */  | 
7  |  | mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c)  | 
8  | 0  | { | 
9  | 0  |    mp_err     err;  | 
10  | 0  |    int ix, oldused;  | 
11  | 0  |    mp_digit *tmpa, *tmpc;  | 
12  |  |  | 
13  |  |    /* grow c as required */  | 
14  | 0  |    if (c->alloc < (a->used + 1)) { | 
15  | 0  |       if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { | 
16  | 0  |          return err;  | 
17  | 0  |       }  | 
18  | 0  |    }  | 
19  |  |  | 
20  |  |    /* if a is negative and |a| >= b, call c = |a| - b */  | 
21  | 0  |    if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) { | 
22  | 0  |       mp_int a_ = *a;  | 
23  |  |       /* temporarily fix sign of a */  | 
24  | 0  |       a_.sign = MP_ZPOS;  | 
25  |  |  | 
26  |  |       /* c = |a| - b */  | 
27  | 0  |       err = mp_sub_d(&a_, b, c);  | 
28  |  |  | 
29  |  |       /* fix sign  */  | 
30  | 0  |       c->sign = MP_NEG;  | 
31  |  |  | 
32  |  |       /* clamp */  | 
33  | 0  |       mp_clamp(c);  | 
34  |  | 
  | 
35  | 0  |       return err;  | 
36  | 0  |    }  | 
37  |  |  | 
38  |  |    /* old number of used digits in c */  | 
39  | 0  |    oldused = c->used;  | 
40  |  |  | 
41  |  |    /* source alias */  | 
42  | 0  |    tmpa    = a->dp;  | 
43  |  |  | 
44  |  |    /* destination alias */  | 
45  | 0  |    tmpc    = c->dp;  | 
46  |  |  | 
47  |  |    /* if a is positive */  | 
48  | 0  |    if (a->sign == MP_ZPOS) { | 
49  |  |       /* add digits, mu is carry */  | 
50  | 0  |       mp_digit mu = b;  | 
51  | 0  |       for (ix = 0; ix < a->used; ix++) { | 
52  | 0  |          *tmpc   = *tmpa++ + mu;  | 
53  | 0  |          mu      = *tmpc >> MP_DIGIT_BIT;  | 
54  | 0  |          *tmpc++ &= MP_MASK;  | 
55  | 0  |       }  | 
56  |  |       /* set final carry */  | 
57  | 0  |       ix++;  | 
58  | 0  |       *tmpc++  = mu;  | 
59  |  |  | 
60  |  |       /* setup size */  | 
61  | 0  |       c->used = a->used + 1;  | 
62  | 0  |    } else { | 
63  |  |       /* a was negative and |a| < b */  | 
64  | 0  |       c->used  = 1;  | 
65  |  |  | 
66  |  |       /* the result is a single digit */  | 
67  | 0  |       if (a->used == 1) { | 
68  | 0  |          *tmpc++  =  b - a->dp[0];  | 
69  | 0  |       } else { | 
70  | 0  |          *tmpc++  =  b;  | 
71  | 0  |       }  | 
72  |  |  | 
73  |  |       /* setup count so the clearing of oldused  | 
74  |  |        * can fall through correctly  | 
75  |  |        */  | 
76  | 0  |       ix       = 1;  | 
77  | 0  |    }  | 
78  |  |  | 
79  |  |    /* sign always positive */  | 
80  | 0  |    c->sign = MP_ZPOS;  | 
81  |  |  | 
82  |  |    /* now zero to oldused */  | 
83  | 0  |    MP_ZERO_DIGITS(tmpc, oldused - ix);  | 
84  | 0  |    mp_clamp(c);  | 
85  |  | 
  | 
86  | 0  |    return MP_OKAY;  | 
87  | 0  | }  | 
88  |  |  | 
89  |  | #endif  |