/src/dropbear/libtommath/bn_s_mp_balance_mul.c
Line | Count | Source |
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 | | mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) |
8 | 0 | { |
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 | 0 | } |
22 | 0 | if ((err = mp_init_multi(&tmp, &r, NULL)) != MP_OKAY) { |
23 | 0 | mp_clear(&a0); |
24 | 0 | return err; |
25 | 0 | } |
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 | 0 | } else { |
32 | 0 | A = *a; |
33 | 0 | B = *b; |
34 | 0 | } |
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 | 0 | } |
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 | 0 | } |
48 | | /* Shift tmp to the correct position */ |
49 | 0 | if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) { |
50 | 0 | goto LBL_ERR; |
51 | 0 | } |
52 | | /* Add to output. No carry needed */ |
53 | 0 | if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) { |
54 | 0 | goto LBL_ERR; |
55 | 0 | } |
56 | 0 | } |
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 | 0 | } |
64 | 0 | mp_clamp(&a0); |
65 | 0 | if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) { |
66 | 0 | goto LBL_ERR; |
67 | 0 | } |
68 | 0 | if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) { |
69 | 0 | goto LBL_ERR; |
70 | 0 | } |
71 | 0 | if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) { |
72 | 0 | goto LBL_ERR; |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | 0 | mp_exch(&r,c); |
77 | 0 | LBL_ERR: |
78 | | mp_clear_multi(&a0, &tmp, &r,NULL); |
79 | 0 | return err; |
80 | 0 | } |
81 | | #endif |