1/* $NetBSD: bn_mp_add_d.c,v 1.2 2017/01/28 21:31:47 christos Exp $ */ 2 3#include <tommath.h> 4#ifdef BN_MP_ADD_D_C 5/* LibTomMath, multiple-precision integer library -- Tom St Denis 6 * 7 * LibTomMath is a library that provides multiple-precision 8 * integer arithmetic as well as number theoretic functionality. 9 * 10 * The library was designed directly after the MPI library by 11 * Michael Fromberger but has been written from scratch with 12 * additional optimizations in place. 13 * 14 * The library is free for all purposes without any express 15 * guarantee it works. 16 * 17 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org 18 */ 19 20/* single digit addition */ 21int 22mp_add_d (mp_int * a, mp_digit b, mp_int * c) 23{ 24 int res, ix, oldused; 25 mp_digit *tmpa, *tmpc, mu; 26 27 /* grow c as required */ 28 if (c->alloc < a->used + 1) { 29 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { 30 return res; 31 } 32 } 33 34 /* if a is negative and |a| >= b, call c = |a| - b */ 35 if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { 36 /* temporarily fix sign of a */ 37 a->sign = MP_ZPOS; 38 39 /* c = |a| - b */ 40 res = mp_sub_d(a, b, c); 41 42 /* fix sign */ 43 a->sign = c->sign = MP_NEG; 44 45 /* clamp */ 46 mp_clamp(c); 47 48 return res; 49 } 50 51 /* old number of used digits in c */ 52 oldused = c->used; 53 54 /* sign always positive */ 55 c->sign = MP_ZPOS; 56 57 /* source alias */ 58 tmpa = a->dp; 59 60 /* destination alias */ 61 tmpc = c->dp; 62 63 /* if a is positive */ 64 if (a->sign == MP_ZPOS) { 65 /* add digit, after this we're propagating 66 * the carry. 67 */ 68 *tmpc = *tmpa++ + b; 69 mu = *tmpc >> DIGIT_BIT; 70 *tmpc++ &= MP_MASK; 71 72 /* now handle rest of the digits */ 73 for (ix = 1; ix < a->used; ix++) { 74 *tmpc = *tmpa++ + mu; 75 mu = *tmpc >> DIGIT_BIT; 76 *tmpc++ &= MP_MASK; 77 } 78 /* set final carry */ 79 ix++; 80 *tmpc++ = mu; 81 82 /* setup size */ 83 c->used = a->used + 1; 84 } else { 85 /* a was negative and |a| < b */ 86 c->used = 1; 87 88 /* the result is a single digit */ 89 if (a->used == 1) { 90 *tmpc++ = b - a->dp[0]; 91 } else { 92 *tmpc++ = b; 93 } 94 95 /* setup count so the clearing of oldused 96 * can fall through correctly 97 */ 98 ix = 1; 99 } 100 101 /* now zero to oldused */ 102 while (ix++ < oldused) { 103 *tmpc++ = 0; 104 } 105 mp_clamp(c); 106 107 return MP_OKAY; 108} 109 110#endif 111 112/* Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v */ 113/* Revision: 1.5 */ 114/* Date: 2006/12/28 01:25:13 */ 115