diff options
author | Ladislav Zezula <ladislav.zezula@avg.com> | 2013-01-11 14:55:08 +0100 |
---|---|---|
committer | Ladislav Zezula <ladislav.zezula@avg.com> | 2013-01-11 14:55:08 +0100 |
commit | 3a926f0228c68d7d91cf3946624d7859976440ec (patch) | |
tree | c4e7d36dc8157576929988cdfcf5bfd8262cd09c /src/libtommath/bn_mp_sub_d.c | |
parent | df4b0c085478389c9a21a09521d46735a0109c8a (diff) |
Initial creation
Diffstat (limited to 'src/libtommath/bn_mp_sub_d.c')
-rw-r--r-- | src/libtommath/bn_mp_sub_d.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/libtommath/bn_mp_sub_d.c b/src/libtommath/bn_mp_sub_d.c new file mode 100644 index 0000000..aa08e31 --- /dev/null +++ b/src/libtommath/bn_mp_sub_d.c @@ -0,0 +1,93 @@ +#include "tommath.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, tomstdenis@gmail.com, http://libtom.org + */ + +/* single digit subtraction */ +int +mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* 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; + + /* clamp */ + mp_clamp(c); + + return res; + } + + /* 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; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + + /* 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; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + +#endif + +/* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2006/12/28 01:25:13 $ */ |