bn_mp_mul_2d.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. /* shift left by a certain bit count */
  6. mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c)
  7. {
  8. mp_digit d;
  9. mp_err err;
  10. /* copy */
  11. if (a != c) {
  12. if ((err = mp_copy(a, c)) != MP_OKAY) {
  13. return err;
  14. }
  15. }
  16. if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) {
  17. if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
  18. return err;
  19. }
  20. }
  21. /* shift by as many digits in the bit count */
  22. if (b >= MP_DIGIT_BIT) {
  23. if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) {
  24. return err;
  25. }
  26. }
  27. /* shift any bit count < MP_DIGIT_BIT */
  28. d = (mp_digit)(b % MP_DIGIT_BIT);
  29. if (d != 0u) {
  30. mp_digit *tmpc, shift, mask, r, rr;
  31. int x;
  32. /* bitmask for carries */
  33. mask = ((mp_digit)1 << d) - (mp_digit)1;
  34. /* shift for msbs */
  35. shift = (mp_digit)MP_DIGIT_BIT - d;
  36. /* alias */
  37. tmpc = c->dp;
  38. /* carry */
  39. r = 0;
  40. for (x = 0; x < c->used; x++) {
  41. /* get the higher bits of the current word */
  42. rr = (*tmpc >> shift) & mask;
  43. /* shift the current word and OR in the carry */
  44. *tmpc = ((*tmpc << d) | r) & MP_MASK;
  45. ++tmpc;
  46. /* set the carry to the carry bits of the current word */
  47. r = rr;
  48. }
  49. /* set final carry */
  50. if (r != 0u) {
  51. c->dp[(c->used)++] = r;
  52. }
  53. }
  54. mp_clamp(c);
  55. return MP_OKAY;
  56. }
  57. #endif