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