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 792368 : mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) 8 : { 9 51070 : int olduse, min, max; 10 51070 : mp_err err; 11 : 12 : /* find sizes */ 13 792368 : min = b->used; 14 792368 : max = a->used; 15 : 16 : /* init result */ 17 792368 : if (c->alloc < max) { 18 70 : if ((err = mp_grow(c, max)) != MP_OKAY) { 19 0 : return err; 20 : } 21 : } 22 792368 : olduse = c->used; 23 792368 : c->used = max; 24 : 25 : { 26 51070 : mp_digit u, *tmpa, *tmpb, *tmpc; 27 51070 : int i; 28 : 29 : /* alias for digit pointers */ 30 792368 : tmpa = a->dp; 31 792368 : tmpb = b->dp; 32 792368 : tmpc = c->dp; 33 : 34 : /* set carry to zero */ 35 792368 : u = 0; 36 43712084 : for (i = 0; i < min; i++) { 37 : /* T[i] = A[i] - B[i] - U */ 38 42919716 : *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 42919716 : u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); 46 : 47 : /* Clear carry from T[i] */ 48 42919716 : *tmpc++ &= MP_MASK; 49 : } 50 : 51 : /* now copy higher words if any, e.g. if A has more digits than B */ 52 811893 : for (; i < max; i++) { 53 : /* T[i] = A[i] - U */ 54 19525 : *tmpc = *tmpa++ - u; 55 : 56 : /* U = carry bit of T[i] */ 57 19525 : u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); 58 : 59 : /* Clear carry from T[i] */ 60 19525 : *tmpc++ &= MP_MASK; 61 : } 62 : 63 : /* clear digits above used (since we may not have grown result above) */ 64 792369 : MP_ZERO_DIGITS(tmpc, olduse - c->used); 65 : } 66 : 67 792368 : mp_clamp(c); 68 792368 : return MP_OKAY; 69 : } 70 : 71 : #endif