comparison libtommath/bn_mp_add_d.c @ 1692:1051e4eea25a

Update LibTomMath to 1.2.0 (#84) * update C files * update other files * update headers * update makefiles * remove mp_set/get_double() * use ltm 1.2.0 API * update ltm_desc * use bundled tommath if system-tommath is too old * XMALLOC etc. were changed to MP_MALLOC etc.
author Steffen Jaeckel <s@jaeckel.eu>
date Tue, 26 May 2020 17:36:47 +0200
parents f52919ffd3b1
children
comparison
equal deleted inserted replaced
1691:2d3745d58843 1692:1051e4eea25a
1 #include "tommath_private.h" 1 #include "tommath_private.h"
2 #ifdef BN_MP_ADD_D_C 2 #ifdef BN_MP_ADD_D_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 * 4 /* SPDX-License-Identifier: Unlicense */
5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality.
7 *
8 * The library was designed directly after the MPI library by
9 * Michael Fromberger but has been written from scratch with
10 * additional optimizations in place.
11 *
12 * SPDX-License-Identifier: Unlicense
13 */
14 5
15 /* single digit addition */ 6 /* single digit addition */
16 int mp_add_d(const mp_int *a, mp_digit b, mp_int *c) 7 mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
17 { 8 {
18 int res, ix, oldused; 9 mp_err err;
19 mp_digit *tmpa, *tmpc, mu; 10 int ix, oldused;
11 mp_digit *tmpa, *tmpc;
20 12
21 /* grow c as required */ 13 /* grow c as required */
22 if (c->alloc < (a->used + 1)) { 14 if (c->alloc < (a->used + 1)) {
23 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { 15 if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
24 return res; 16 return err;
25 } 17 }
26 } 18 }
27 19
28 /* if a is negative and |a| >= b, call c = |a| - b */ 20 /* if a is negative and |a| >= b, call c = |a| - b */
29 if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) { 21 if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
30 mp_int a_ = *a; 22 mp_int a_ = *a;
31 /* temporarily fix sign of a */ 23 /* temporarily fix sign of a */
32 a_.sign = MP_ZPOS; 24 a_.sign = MP_ZPOS;
33 25
34 /* c = |a| - b */ 26 /* c = |a| - b */
35 res = mp_sub_d(&a_, b, c); 27 err = mp_sub_d(&a_, b, c);
36 28
37 /* fix sign */ 29 /* fix sign */
38 c->sign = MP_NEG; 30 c->sign = MP_NEG;
39 31
40 /* clamp */ 32 /* clamp */
41 mp_clamp(c); 33 mp_clamp(c);
42 34
43 return res; 35 return err;
44 } 36 }
45 37
46 /* old number of used digits in c */ 38 /* old number of used digits in c */
47 oldused = c->used; 39 oldused = c->used;
48 40
52 /* destination alias */ 44 /* destination alias */
53 tmpc = c->dp; 45 tmpc = c->dp;
54 46
55 /* if a is positive */ 47 /* if a is positive */
56 if (a->sign == MP_ZPOS) { 48 if (a->sign == MP_ZPOS) {
57 /* add digit, after this we're propagating 49 /* add digits, mu is carry */
58 * the carry. 50 mp_digit mu = b;
59 */ 51 for (ix = 0; ix < a->used; ix++) {
60 *tmpc = *tmpa++ + b;
61 mu = *tmpc >> DIGIT_BIT;
62 *tmpc++ &= MP_MASK;
63
64 /* now handle rest of the digits */
65 for (ix = 1; ix < a->used; ix++) {
66 *tmpc = *tmpa++ + mu; 52 *tmpc = *tmpa++ + mu;
67 mu = *tmpc >> DIGIT_BIT; 53 mu = *tmpc >> MP_DIGIT_BIT;
68 *tmpc++ &= MP_MASK; 54 *tmpc++ &= MP_MASK;
69 } 55 }
70 /* set final carry */ 56 /* set final carry */
71 ix++; 57 ix++;
72 *tmpc++ = mu; 58 *tmpc++ = mu;
92 78
93 /* sign always positive */ 79 /* sign always positive */
94 c->sign = MP_ZPOS; 80 c->sign = MP_ZPOS;
95 81
96 /* now zero to oldused */ 82 /* now zero to oldused */
97 while (ix++ < oldused) { 83 MP_ZERO_DIGITS(tmpc, oldused - ix);
98 *tmpc++ = 0;
99 }
100 mp_clamp(c); 84 mp_clamp(c);
101 85
102 return MP_OKAY; 86 return MP_OKAY;
103 } 87 }
104 88
105 #endif 89 #endif
106
107 /* ref: HEAD -> master, tag: v1.1.0 */
108 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */
109 /* commit time: 2019-01-28 20:32:32 +0100 */