Line data Source code
1 : #include <tommath.h>
2 : #ifdef BN_MP_SUB_D_C
3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis
4 : *
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, tomstdenis@gmail.com, http://libtom.org
16 : */
17 :
18 : /* single digit subtraction */
19 : int
20 0 : mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
21 : {
22 : mp_digit *tmpa, *tmpc, mu;
23 : int res, ix, oldused;
24 :
25 : /* grow c as required */
26 0 : if (c->alloc < a->used + 1) {
27 0 : if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
28 0 : return res;
29 : }
30 : }
31 :
32 : /* if a is negative just do an unsigned
33 : * addition [with fudged signs]
34 : */
35 0 : if (a->sign == MP_NEG) {
36 0 : a->sign = MP_ZPOS;
37 0 : res = mp_add_d(a, b, c);
38 0 : a->sign = c->sign = MP_NEG;
39 :
40 : /* clamp */
41 0 : mp_clamp(c);
42 :
43 0 : return res;
44 : }
45 :
46 : /* setup regs */
47 0 : oldused = c->used;
48 0 : tmpa = a->dp;
49 0 : tmpc = c->dp;
50 :
51 : /* if a <= b simply fix the single digit */
52 0 : if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
53 0 : if (a->used == 1) {
54 0 : *tmpc++ = b - *tmpa;
55 : } else {
56 0 : *tmpc++ = b;
57 : }
58 0 : ix = 1;
59 :
60 : /* negative/1digit */
61 0 : c->sign = MP_NEG;
62 0 : c->used = 1;
63 : } else {
64 : /* positive/size */
65 0 : c->sign = MP_ZPOS;
66 0 : c->used = a->used;
67 :
68 : /* subtract first digit */
69 0 : *tmpc = *tmpa++ - b;
70 0 : mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
71 0 : *tmpc++ &= MP_MASK;
72 :
73 : /* handle rest of the digits */
74 0 : for (ix = 1; ix < a->used; ix++) {
75 0 : *tmpc = *tmpa++ - mu;
76 0 : mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
77 0 : *tmpc++ &= MP_MASK;
78 : }
79 : }
80 :
81 : /* zero excess digits */
82 0 : while (ix++ < oldused) {
83 0 : *tmpc++ = 0;
84 : }
85 0 : mp_clamp(c);
86 0 : return MP_OKAY;
87 : }
88 :
89 : #endif
90 :
91 : /* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */
92 : /* $Revision: 1.6 $ */
93 : /* $Date: 2006/12/28 01:25:13 $ */
|