comparison libtommath/bn_mp_sub_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_SUB_D_C 2 #ifdef BN_MP_SUB_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 subtraction */ 6 /* single digit subtraction */
16 int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) 7 mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
17 { 8 {
18 mp_digit *tmpa, *tmpc, mu; 9 mp_digit *tmpa, *tmpc;
19 int res, ix, oldused; 10 mp_err err;
11 int ix, oldused;
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 just do an unsigned 20 /* if a is negative just do an unsigned
29 * addition [with fudged signs] 21 * addition [with fudged signs]
30 */ 22 */
31 if (a->sign == MP_NEG) { 23 if (a->sign == MP_NEG) {
32 mp_int a_ = *a; 24 mp_int a_ = *a;
33 a_.sign = MP_ZPOS; 25 a_.sign = MP_ZPOS;
34 res = mp_add_d(&a_, b, c); 26 err = mp_add_d(&a_, b, c);
35 c->sign = MP_NEG; 27 c->sign = MP_NEG;
36 28
37 /* clamp */ 29 /* clamp */
38 mp_clamp(c); 30 mp_clamp(c);
39 31
40 return res; 32 return err;
41 } 33 }
42 34
43 /* setup regs */ 35 /* setup regs */
44 oldused = c->used; 36 oldused = c->used;
45 tmpa = a->dp; 37 tmpa = a->dp;
56 48
57 /* negative/1digit */ 49 /* negative/1digit */
58 c->sign = MP_NEG; 50 c->sign = MP_NEG;
59 c->used = 1; 51 c->used = 1;
60 } else { 52 } else {
53 mp_digit mu = b;
54
61 /* positive/size */ 55 /* positive/size */
62 c->sign = MP_ZPOS; 56 c->sign = MP_ZPOS;
63 c->used = a->used; 57 c->used = a->used;
64 58
65 /* subtract first digit */ 59 /* subtract digits, mu is carry */
66 *tmpc = *tmpa++ - b; 60 for (ix = 0; ix < a->used; ix++) {
67 mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u);
68 *tmpc++ &= MP_MASK;
69
70 /* handle rest of the digits */
71 for (ix = 1; ix < a->used; ix++) {
72 *tmpc = *tmpa++ - mu; 61 *tmpc = *tmpa++ - mu;
73 mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u); 62 mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
74 *tmpc++ &= MP_MASK; 63 *tmpc++ &= MP_MASK;
75 } 64 }
76 } 65 }
77 66
78 /* zero excess digits */ 67 /* zero excess digits */
79 while (ix++ < oldused) { 68 MP_ZERO_DIGITS(tmpc, oldused - ix);
80 *tmpc++ = 0; 69
81 }
82 mp_clamp(c); 70 mp_clamp(c);
83 return MP_OKAY; 71 return MP_OKAY;
84 } 72 }
85 73
86 #endif 74 #endif
87
88 /* ref: HEAD -> master, tag: v1.1.0 */
89 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */
90 /* commit time: 2019-01-28 20:32:32 +0100 */