Line data Source code
1 : #include "tommath_private.h" 2 : #ifdef BN_MP_MUL_2D_C 3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */ 4 : /* SPDX-License-Identifier: Unlicense */ 5 : 6 : /* shift left by a certain bit count */ 7 828862 : mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) 8 : { 9 30916 : mp_digit d; 10 30916 : mp_err err; 11 : 12 : /* copy */ 13 828862 : if (a != c) { 14 0 : if ((err = mp_copy(a, c)) != MP_OKAY) { 15 0 : return err; 16 : } 17 : } 18 : 19 828862 : if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) { 20 55558 : if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) { 21 0 : return err; 22 : } 23 : } 24 : 25 : /* shift by as many digits in the bit count */ 26 828862 : if (b >= MP_DIGIT_BIT) { 27 0 : if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) { 28 0 : return err; 29 : } 30 : } 31 : 32 : /* shift any bit count < MP_DIGIT_BIT */ 33 828862 : d = (mp_digit)(b % MP_DIGIT_BIT); 34 828862 : if (d != 0u) { 35 30916 : mp_digit *tmpc, shift, mask, r, rr; 36 30916 : int x; 37 : 38 : /* bitmask for carries */ 39 828862 : mask = ((mp_digit)1 << d) - (mp_digit)1; 40 : 41 : /* shift for msbs */ 42 828862 : shift = (mp_digit)MP_DIGIT_BIT - d; 43 : 44 : /* alias */ 45 828862 : tmpc = c->dp; 46 : 47 : /* carry */ 48 828862 : r = 0; 49 35260774 : for (x = 0; x < c->used; x++) { 50 : /* get the higher bits of the current word */ 51 34431912 : rr = (*tmpc >> shift) & mask; 52 : 53 : /* shift the current word and OR in the carry */ 54 34431912 : *tmpc = ((*tmpc << d) | r) & MP_MASK; 55 34431912 : ++tmpc; 56 : 57 : /* set the carry to the carry bits of the current word */ 58 34431912 : r = rr; 59 : } 60 : 61 : /* set final carry */ 62 828862 : if (r != 0u) { 63 1113 : c->dp[(c->used)++] = r; 64 : } 65 : } 66 828862 : mp_clamp(c); 67 828862 : return MP_OKAY; 68 : } 69 : #endif