comparison libtommath/bn_mp_sub_d.c @ 1739:13d834efc376 fuzz

merge from main
author Matt Johnston <matt@ucc.asn.au>
date Thu, 15 Oct 2020 19:55:15 +0800
parents 1051e4eea25a
children
comparison
equal deleted inserted replaced
1562:768ebf737aa0 1739:13d834efc376
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 * The library is free for all purposes without any express
13 * guarantee it works.
14 *
15 * Tom St Denis, [email protected], http://libtom.org
16 */
17 5
18 /* single digit subtraction */ 6 /* single digit subtraction */
19 int 7 mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
20 mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
21 { 8 {
22 mp_digit *tmpa, *tmpc, mu; 9 mp_digit *tmpa, *tmpc;
23 int res, ix, oldused; 10 mp_err err;
11 int ix, oldused;
24 12
25 /* grow c as required */ 13 /* grow c as required */
26 if (c->alloc < (a->used + 1)) { 14 if (c->alloc < (a->used + 1)) {
27 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { 15 if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
28 return res; 16 return err;
29 } 17 }
30 } 18 }
31 19
32 /* if a is negative just do an unsigned 20 /* if a is negative just do an unsigned
33 * addition [with fudged signs] 21 * addition [with fudged signs]
34 */ 22 */
35 if (a->sign == MP_NEG) { 23 if (a->sign == MP_NEG) {
36 a->sign = MP_ZPOS; 24 mp_int a_ = *a;
37 res = mp_add_d(a, b, c); 25 a_.sign = MP_ZPOS;
38 a->sign = c->sign = MP_NEG; 26 err = mp_add_d(&a_, b, c);
27 c->sign = MP_NEG;
39 28
40 /* clamp */ 29 /* clamp */
41 mp_clamp(c); 30 mp_clamp(c);
42 31
43 return res; 32 return err;
44 } 33 }
45 34
46 /* setup regs */ 35 /* setup regs */
47 oldused = c->used; 36 oldused = c->used;
48 tmpa = a->dp; 37 tmpa = a->dp;
49 tmpc = c->dp; 38 tmpc = c->dp;
50 39
51 /* if a <= b simply fix the single digit */ 40 /* if a <= b simply fix the single digit */
52 if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { 41 if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) {
53 if (a->used == 1) { 42 if (a->used == 1) {
54 *tmpc++ = b - *tmpa; 43 *tmpc++ = b - *tmpa;
55 } else { 44 } else {
56 *tmpc++ = b; 45 *tmpc++ = b;
57 } 46 }
58 ix = 1; 47 ix = 1;
59 48
60 /* negative/1digit */ 49 /* negative/1digit */
61 c->sign = MP_NEG; 50 c->sign = MP_NEG;
62 c->used = 1; 51 c->used = 1;
63 } else { 52 } else {
64 /* positive/size */ 53 mp_digit mu = b;
65 c->sign = MP_ZPOS;
66 c->used = a->used;
67 54
68 /* subtract first digit */ 55 /* positive/size */
69 *tmpc = *tmpa++ - b; 56 c->sign = MP_ZPOS;
70 mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); 57 c->used = a->used;
71 *tmpc++ &= MP_MASK;
72 58
73 /* handle rest of the digits */ 59 /* subtract digits, mu is carry */
74 for (ix = 1; ix < a->used; ix++) { 60 for (ix = 0; ix < a->used; ix++) {
75 *tmpc = *tmpa++ - mu; 61 *tmpc = *tmpa++ - mu;
76 mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); 62 mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
77 *tmpc++ &= MP_MASK; 63 *tmpc++ &= MP_MASK;
78 } 64 }
79 } 65 }
80 66
81 /* zero excess digits */ 67 /* zero excess digits */
82 while (ix++ < oldused) { 68 MP_ZERO_DIGITS(tmpc, oldused - ix);
83 *tmpc++ = 0; 69
84 } 70 mp_clamp(c);
85 mp_clamp(c); 71 return MP_OKAY;
86 return MP_OKAY;
87 } 72 }
88 73
89 #endif 74 #endif
90
91 /* ref: $Format:%D$ */
92 /* git commit: $Format:%H$ */
93 /* commit time: $Format:%ai$ */