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