Line data Source code
1 : #include "tommath_private.h" 2 : #ifdef BN_S_MP_SUB_C 3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */ 4 : /* SPDX-License-Identifier: Unlicense */ 5 : 6 : /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ 7 764956 : mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) 8 : { 9 51187 : int olduse, min, max; 10 51187 : mp_err err; 11 : 12 : /* find sizes */ 13 764956 : min = b->used; 14 764956 : max = a->used; 15 : 16 : /* init result */ 17 764956 : if (c->alloc < max) { 18 74 : if ((err = mp_grow(c, max)) != MP_OKAY) { 19 0 : return err; 20 : } 21 : } 22 764956 : olduse = c->used; 23 764956 : c->used = max; 24 : 25 : { 26 51187 : mp_digit u, *tmpa, *tmpb, *tmpc; 27 51187 : int i; 28 : 29 : /* alias for digit pointers */ 30 764956 : tmpa = a->dp; 31 764956 : tmpb = b->dp; 32 764956 : tmpc = c->dp; 33 : 34 : /* set carry to zero */ 35 764956 : u = 0; 36 42001437 : for (i = 0; i < min; i++) { 37 : /* T[i] = A[i] - B[i] - U */ 38 41236481 : *tmpc = (*tmpa++ - *tmpb++) - u; 39 : 40 : /* U = carry bit of T[i] 41 : * Note this saves performing an AND operation since 42 : * if a carry does occur it will propagate all the way to the 43 : * MSB. As a result a single shift is enough to get the carry 44 : */ 45 41236481 : u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); 46 : 47 : /* Clear carry from T[i] */ 48 41236481 : *tmpc++ &= MP_MASK; 49 : } 50 : 51 : /* now copy higher words if any, e.g. if A has more digits than B */ 52 783960 : for (; i < max; i++) { 53 : /* T[i] = A[i] - U */ 54 19004 : *tmpc = *tmpa++ - u; 55 : 56 : /* U = carry bit of T[i] */ 57 19004 : u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); 58 : 59 : /* Clear carry from T[i] */ 60 19004 : *tmpc++ &= MP_MASK; 61 : } 62 : 63 : /* clear digits above used (since we may not have grown result above) */ 64 764956 : MP_ZERO_DIGITS(tmpc, olduse - c->used); 65 : } 66 : 67 764956 : mp_clamp(c); 68 764956 : return MP_OKAY; 69 : } 70 : 71 : #endif