1 #include "tommath_private.h"
2 #ifdef S_MP_MUL_BALANCE_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 /* SPDX-License-Identifier: Unlicense */
6 /* single-digit multiplication with the smaller number as the single-digit */
7 mp_err
s_mp_mul_balance(const mp_int
*a
, const mp_int
*b
, mp_int
*c
)
12 nblocks
= MP_MAX(a
->used
, b
->used
) / MP_MIN(a
->used
, b
->used
),
13 bsize
= MP_MIN(a
->used
, b
->used
);
15 if ((err
= mp_init_size(&a0
, bsize
+ 2)) != MP_OKAY
) {
18 if ((err
= mp_init_multi(&tmp
, &r
, NULL
)) != MP_OKAY
) {
23 /* Make sure that A is the larger one*/
24 if (a
->used
< b
->used
) {
25 MP_EXCH(const mp_int
*, a
, b
);
28 for (i
= 0, j
=0; i
< nblocks
; i
++) {
29 /* Cut a slice off of a */
31 s_mp_copy_digs(a0
.dp
, a
->dp
+ j
, a0
.used
);
36 if ((err
= mp_mul(&a0
, b
, &tmp
)) != MP_OKAY
) {
39 /* Shift tmp to the correct position */
40 if ((err
= mp_lshd(&tmp
, bsize
* i
)) != MP_OKAY
) {
43 /* Add to output. No carry needed */
44 if ((err
= mp_add(&r
, &tmp
, &r
)) != MP_OKAY
) {
48 /* The left-overs; there are always left-overs */
50 a0
.used
= a
->used
- j
;
51 s_mp_copy_digs(a0
.dp
, a
->dp
+ j
, a0
.used
);
55 if ((err
= mp_mul(&a0
, b
, &tmp
)) != MP_OKAY
) {
58 if ((err
= mp_lshd(&tmp
, bsize
* i
)) != MP_OKAY
) {
61 if ((err
= mp_add(&r
, &tmp
, &r
)) != MP_OKAY
) {
68 mp_clear_multi(&a0
, &tmp
, &r
,NULL
);