Mercurial > dropbear
comparison libtommath/bn_s_mp_sub.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_S_MP_SUB_C | 2 #ifdef BN_S_MP_SUB_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 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ | 6 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ |
19 int | 7 mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) |
20 s_mp_sub (mp_int * a, mp_int * b, mp_int * c) | |
21 { | 8 { |
22 int olduse, res, min, max; | 9 int olduse, min, max; |
10 mp_err err; | |
23 | 11 |
24 /* find sizes */ | 12 /* find sizes */ |
25 min = b->used; | 13 min = b->used; |
26 max = a->used; | 14 max = a->used; |
27 | 15 |
28 /* init result */ | 16 /* init result */ |
29 if (c->alloc < max) { | 17 if (c->alloc < max) { |
30 if ((res = mp_grow (c, max)) != MP_OKAY) { | 18 if ((err = mp_grow(c, max)) != MP_OKAY) { |
31 return res; | 19 return err; |
32 } | 20 } |
33 } | 21 } |
34 olduse = c->used; | 22 olduse = c->used; |
35 c->used = max; | 23 c->used = max; |
36 | 24 |
37 { | 25 { |
38 mp_digit u, *tmpa, *tmpb, *tmpc; | 26 mp_digit u, *tmpa, *tmpb, *tmpc; |
39 int i; | 27 int i; |
40 | 28 |
41 /* alias for digit pointers */ | 29 /* alias for digit pointers */ |
42 tmpa = a->dp; | 30 tmpa = a->dp; |
43 tmpb = b->dp; | 31 tmpb = b->dp; |
44 tmpc = c->dp; | 32 tmpc = c->dp; |
45 | 33 |
46 /* set carry to zero */ | 34 /* set carry to zero */ |
47 u = 0; | 35 u = 0; |
48 for (i = 0; i < min; i++) { | 36 for (i = 0; i < min; i++) { |
49 /* T[i] = A[i] - B[i] - U */ | 37 /* T[i] = A[i] - B[i] - U */ |
50 *tmpc = (*tmpa++ - *tmpb++) - u; | 38 *tmpc = (*tmpa++ - *tmpb++) - u; |
51 | 39 |
52 /* U = carry bit of T[i] | 40 /* U = carry bit of T[i] |
53 * Note this saves performing an AND operation since | 41 * Note this saves performing an AND operation since |
54 * if a carry does occur it will propagate all the way to the | 42 * if a carry does occur it will propagate all the way to the |
55 * MSB. As a result a single shift is enough to get the carry | 43 * MSB. As a result a single shift is enough to get the carry |
56 */ | 44 */ |
57 u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); | 45 u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); |
58 | 46 |
59 /* Clear carry from T[i] */ | 47 /* Clear carry from T[i] */ |
60 *tmpc++ &= MP_MASK; | 48 *tmpc++ &= MP_MASK; |
61 } | 49 } |
62 | 50 |
63 /* now copy higher words if any, e.g. if A has more digits than B */ | 51 /* now copy higher words if any, e.g. if A has more digits than B */ |
64 for (; i < max; i++) { | 52 for (; i < max; i++) { |
65 /* T[i] = A[i] - U */ | 53 /* T[i] = A[i] - U */ |
66 *tmpc = *tmpa++ - u; | 54 *tmpc = *tmpa++ - u; |
67 | 55 |
68 /* U = carry bit of T[i] */ | 56 /* U = carry bit of T[i] */ |
69 u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); | 57 u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); |
70 | 58 |
71 /* Clear carry from T[i] */ | 59 /* Clear carry from T[i] */ |
72 *tmpc++ &= MP_MASK; | 60 *tmpc++ &= MP_MASK; |
73 } | 61 } |
74 | 62 |
75 /* clear digits above used (since we may not have grown result above) */ | 63 /* clear digits above used (since we may not have grown result above) */ |
76 for (i = c->used; i < olduse; i++) { | 64 MP_ZERO_DIGITS(tmpc, olduse - c->used); |
77 *tmpc++ = 0; | 65 } |
78 } | |
79 } | |
80 | 66 |
81 mp_clamp (c); | 67 mp_clamp(c); |
82 return MP_OKAY; | 68 return MP_OKAY; |
83 } | 69 } |
84 | 70 |
85 #endif | 71 #endif |
86 | |
87 /* ref: $Format:%D$ */ | |
88 /* git commit: $Format:%H$ */ | |
89 /* commit time: $Format:%ai$ */ |