diff libtommath/bn_s_mp_balance_mul.c @ 1692:1051e4eea25a

Update LibTomMath to 1.2.0 (#84) * update C files * update other files * update headers * update makefiles * remove mp_set/get_double() * use ltm 1.2.0 API * update ltm_desc * use bundled tommath if system-tommath is too old * XMALLOC etc. were changed to MP_MALLOC etc.
author Steffen Jaeckel <s@jaeckel.eu>
date Tue, 26 May 2020 17:36:47 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_s_mp_balance_mul.c	Tue May 26 17:36:47 2020 +0200
@@ -0,0 +1,81 @@
+#include "tommath_private.h"
+#ifdef BN_S_MP_BALANCE_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* single-digit multiplication with the smaller number as the single-digit */
+mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   int count, len_a, len_b, nblocks, i, j, bsize;
+   mp_int a0, tmp, A, B, r;
+   mp_err err;
+
+   len_a = a->used;
+   len_b = b->used;
+
+   nblocks = MP_MAX(a->used, b->used) / MP_MIN(a->used, b->used);
+   bsize = MP_MIN(a->used, b->used) ;
+
+   if ((err = mp_init_size(&a0, bsize + 2)) != MP_OKAY) {
+      return err;
+   }
+   if ((err = mp_init_multi(&tmp, &r, NULL)) != MP_OKAY) {
+      mp_clear(&a0);
+      return err;
+   }
+
+   /* Make sure that A is the larger one*/
+   if (len_a < len_b) {
+      B = *a;
+      A = *b;
+   } else {
+      A = *a;
+      B = *b;
+   }
+
+   for (i = 0, j=0; i < nblocks; i++) {
+      /* Cut a slice off of a */
+      a0.used = 0;
+      for (count = 0; count < bsize; count++) {
+         a0.dp[count] = A.dp[ j++ ];
+         a0.used++;
+      }
+      mp_clamp(&a0);
+      /* Multiply with b */
+      if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      /* Shift tmp to the correct position */
+      if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      /* Add to output. No carry needed */
+      if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+   }
+   /* The left-overs; there are always left-overs */
+   if (j < A.used) {
+      a0.used = 0;
+      for (count = 0; j < A.used; count++) {
+         a0.dp[count] = A.dp[ j++ ];
+         a0.used++;
+      }
+      mp_clamp(&a0);
+      if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+   }
+
+   mp_exch(&r,c);
+LBL_ERR:
+   mp_clear_multi(&a0, &tmp, &r,NULL);
+   return err;
+}
+#endif