Mercurial > dropbear
comparison libtommath/bn_s_mp_mul_digs.c @ 1739:13d834efc376 fuzz
merge from main
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 15 Oct 2020 19:55:15 +0800 |
parents | 1051e4eea25a |
children |
comparison
equal
deleted
inserted
replaced
1562:768ebf737aa0 | 1739:13d834efc376 |
---|---|
1 #include <tommath_private.h> | 1 #include "tommath_private.h" |
2 #ifdef BN_S_MP_MUL_DIGS_C | 2 #ifdef BN_S_MP_MUL_DIGS_C |
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis | 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 * | 4 /* SPDX-License-Identifier: Unlicense */ |
5 * LibTomMath is a library that provides multiple-precision | |
6 * integer arithmetic as well as number theoretic functionality. | |
7 * | |
8 * The library was designed directly after the MPI library by | |
9 * Michael Fromberger but has been written from scratch with | |
10 * additional optimizations in place. | |
11 * | |
12 * The library is free for all purposes without any express | |
13 * guarantee it works. | |
14 * | |
15 * Tom St Denis, [email protected], http://libtom.org | |
16 */ | |
17 | 5 |
18 /* multiplies |a| * |b| and only computes upto digs digits of result | 6 /* multiplies |a| * |b| and only computes upto digs digits of result |
19 * HAC pp. 595, Algorithm 14.12 Modified so you can control how | 7 * HAC pp. 595, Algorithm 14.12 Modified so you can control how |
20 * many digits of output are created. | 8 * many digits of output are created. |
21 */ | 9 */ |
22 int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) | 10 mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) |
23 { | 11 { |
24 mp_int t; | 12 mp_int t; |
25 int res, pa, pb, ix, iy; | 13 mp_err err; |
26 mp_digit u; | 14 int pa, pb, ix, iy; |
27 mp_word r; | 15 mp_digit u; |
28 mp_digit tmpx, *tmpt, *tmpy; | 16 mp_word r; |
17 mp_digit tmpx, *tmpt, *tmpy; | |
29 | 18 |
30 /* can we use the fast multiplier? */ | 19 /* can we use the fast multiplier? */ |
31 if (((digs) < MP_WARRAY) && | 20 if ((digs < MP_WARRAY) && |
32 (MIN (a->used, b->used) < | 21 (MP_MIN(a->used, b->used) < MP_MAXFAST)) { |
33 (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { | 22 return s_mp_mul_digs_fast(a, b, c, digs); |
34 return fast_s_mp_mul_digs (a, b, c, digs); | 23 } |
35 } | |
36 | 24 |
37 if ((res = mp_init_size (&t, digs)) != MP_OKAY) { | 25 if ((err = mp_init_size(&t, digs)) != MP_OKAY) { |
38 return res; | 26 return err; |
39 } | 27 } |
40 t.used = digs; | 28 t.used = digs; |
41 | 29 |
42 /* compute the digits of the product directly */ | 30 /* compute the digits of the product directly */ |
43 pa = a->used; | 31 pa = a->used; |
44 for (ix = 0; ix < pa; ix++) { | 32 for (ix = 0; ix < pa; ix++) { |
45 /* set the carry to zero */ | 33 /* set the carry to zero */ |
46 u = 0; | 34 u = 0; |
47 | 35 |
48 /* limit ourselves to making digs digits of output */ | 36 /* limit ourselves to making digs digits of output */ |
49 pb = MIN (b->used, digs - ix); | 37 pb = MP_MIN(b->used, digs - ix); |
50 | 38 |
51 /* setup some aliases */ | 39 /* setup some aliases */ |
52 /* copy of the digit from a used within the nested loop */ | 40 /* copy of the digit from a used within the nested loop */ |
53 tmpx = a->dp[ix]; | 41 tmpx = a->dp[ix]; |
54 | |
55 /* an alias for the destination shifted ix places */ | |
56 tmpt = t.dp + ix; | |
57 | |
58 /* an alias for the digits of b */ | |
59 tmpy = b->dp; | |
60 | 42 |
61 /* compute the columns of the output and propagate the carry */ | 43 /* an alias for the destination shifted ix places */ |
62 for (iy = 0; iy < pb; iy++) { | 44 tmpt = t.dp + ix; |
63 /* compute the column as a mp_word */ | |
64 r = (mp_word)*tmpt + | |
65 ((mp_word)tmpx * (mp_word)*tmpy++) + | |
66 (mp_word)u; | |
67 | 45 |
68 /* the new column is the lower part of the result */ | 46 /* an alias for the digits of b */ |
69 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); | 47 tmpy = b->dp; |
70 | 48 |
71 /* get the carry word from the result */ | 49 /* compute the columns of the output and propagate the carry */ |
72 u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); | 50 for (iy = 0; iy < pb; iy++) { |
73 } | 51 /* compute the column as a mp_word */ |
74 /* set carry if it is placed below digs */ | 52 r = (mp_word)*tmpt + |
75 if ((ix + iy) < digs) { | 53 ((mp_word)tmpx * (mp_word)*tmpy++) + |
76 *tmpt = u; | 54 (mp_word)u; |
77 } | |
78 } | |
79 | 55 |
80 mp_clamp (&t); | 56 /* the new column is the lower part of the result */ |
81 mp_exch (&t, c); | 57 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); |
82 | 58 |
83 mp_clear (&t); | 59 /* get the carry word from the result */ |
84 return MP_OKAY; | 60 u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); |
61 } | |
62 /* set carry if it is placed below digs */ | |
63 if ((ix + iy) < digs) { | |
64 *tmpt = u; | |
65 } | |
66 } | |
67 | |
68 mp_clamp(&t); | |
69 mp_exch(&t, c); | |
70 | |
71 mp_clear(&t); | |
72 return MP_OKAY; | |
85 } | 73 } |
86 #endif | 74 #endif |
87 | |
88 /* ref: $Format:%D$ */ | |
89 /* git commit: $Format:%H$ */ | |
90 /* commit time: $Format:%ai$ */ |