diff options
author | Matt Johnston <matt@ucc.asn.au> | 2020-10-15 19:55:15 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2020-10-15 19:55:15 +0800 |
commit | 0e3e8db5bfca0c579be55e7580a46c593c1384be (patch) | |
tree | 2b1a718f633fb95c1f2d689a591cf9e8642697f3 /libtommath/bn_mp_sub_d.c | |
parent | 78e17f6ee9a944430da3e517ee1fe384fd6b275b (diff) | |
parent | 17873e8c922eded2cec86184673a6d110df6403f (diff) |
merge from main
--HG--
branch : fuzz
Diffstat (limited to 'libtommath/bn_mp_sub_d.c')
-rw-r--r-- | libtommath/bn_mp_sub_d.c | 133 |
1 files changed, 57 insertions, 76 deletions
diff --git a/libtommath/bn_mp_sub_d.c b/libtommath/bn_mp_sub_d.c index 5e96030..3ebf9b4 100644 --- a/libtommath/bn_mp_sub_d.c +++ b/libtommath/bn_mp_sub_d.c @@ -1,93 +1,74 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_SUB_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tstdenis82@gmail.com, http://libtom.org - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* single digit subtraction */ -int -mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) { - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; + mp_digit *tmpa, *tmpc; + mp_err err; + int ix, oldused; - /* grow c as required */ - if (c->alloc < (a->used + 1)) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } + /* grow c as required */ + if (c->alloc < (a->used + 1)) { + if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { + return err; + } + } - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + mp_int a_ = *a; + a_.sign = MP_ZPOS; + err = mp_add_d(&a_, b, c); + c->sign = MP_NEG; - /* clamp */ - mp_clamp(c); + /* clamp */ + mp_clamp(c); - return res; - } + return err; + } - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; - /* if a <= b simply fix the single digit */ - if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; + /* if a <= b simply fix the single digit */ + if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + mp_digit mu = b; - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); - *tmpc++ &= MP_MASK; + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); - *tmpc++ &= MP_MASK; - } - } + /* subtract digits, mu is carry */ + for (ix = 0; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); + *tmpc++ &= MP_MASK; + } + } - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; + /* zero excess digits */ + MP_ZERO_DIGITS(tmpc, oldused - ix); + + mp_clamp(c); + return MP_OKAY; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ |