bn_s_mp_balance_mul.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "tommath_private.h"
  2. #ifdef BN_S_MP_BALANCE_MUL_C
  3. /* LibTomMath, multiple-precision integer library -- Tom St Denis */
  4. /* SPDX-License-Identifier: Unlicense */
  5. /* single-digit multiplication with the smaller number as the single-digit */
  6. mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c)
  7. {
  8. int count, len_a, len_b, nblocks, i, j, bsize;
  9. mp_int a0, tmp, A, B, r;
  10. mp_err err;
  11. len_a = a->used;
  12. len_b = b->used;
  13. nblocks = MP_MAX(a->used, b->used) / MP_MIN(a->used, b->used);
  14. bsize = MP_MIN(a->used, b->used) ;
  15. if ((err = mp_init_size(&a0, bsize + 2)) != MP_OKAY) {
  16. return err;
  17. }
  18. if ((err = mp_init_multi(&tmp, &r, NULL)) != MP_OKAY) {
  19. mp_clear(&a0);
  20. return err;
  21. }
  22. /* Make sure that A is the larger one*/
  23. if (len_a < len_b) {
  24. B = *a;
  25. A = *b;
  26. } else {
  27. A = *a;
  28. B = *b;
  29. }
  30. for (i = 0, j=0; i < nblocks; i++) {
  31. /* Cut a slice off of a */
  32. a0.used = 0;
  33. for (count = 0; count < bsize; count++) {
  34. a0.dp[count] = A.dp[ j++ ];
  35. a0.used++;
  36. }
  37. mp_clamp(&a0);
  38. /* Multiply with b */
  39. if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
  40. goto LBL_ERR;
  41. }
  42. /* Shift tmp to the correct position */
  43. if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
  44. goto LBL_ERR;
  45. }
  46. /* Add to output. No carry needed */
  47. if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) {
  48. goto LBL_ERR;
  49. }
  50. }
  51. /* The left-overs; there are always left-overs */
  52. if (j < A.used) {
  53. a0.used = 0;
  54. for (count = 0; j < A.used; count++) {
  55. a0.dp[count] = A.dp[ j++ ];
  56. a0.used++;
  57. }
  58. mp_clamp(&a0);
  59. if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
  60. goto LBL_ERR;
  61. }
  62. if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
  63. goto LBL_ERR;
  64. }
  65. if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) {
  66. goto LBL_ERR;
  67. }
  68. }
  69. mp_exch(&r,c);
  70. LBL_ERR:
  71. mp_clear_multi(&a0, &tmp, &r,NULL);
  72. return err;
  73. }
  74. #endif