comparison libtommath/bn_s_mp_mul_digs.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 f52919ffd3b1
children
comparison
equal deleted inserted replaced
1691:2d3745d58843 1692:1051e4eea25a
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 * SPDX-License-Identifier: Unlicense
13 */
14 5
15 /* multiplies |a| * |b| and only computes upto digs digits of result 6 /* multiplies |a| * |b| and only computes upto digs digits of result
16 * 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
17 * many digits of output are created. 8 * many digits of output are created.
18 */ 9 */
19 int s_mp_mul_digs(const mp_int *a, const 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)
20 { 11 {
21 mp_int t; 12 mp_int t;
22 int res, pa, pb, ix, iy; 13 mp_err err;
14 int pa, pb, ix, iy;
23 mp_digit u; 15 mp_digit u;
24 mp_word r; 16 mp_word r;
25 mp_digit tmpx, *tmpt, *tmpy; 17 mp_digit tmpx, *tmpt, *tmpy;
26 18
27 /* can we use the fast multiplier? */ 19 /* can we use the fast multiplier? */
28 if ((digs < (int)MP_WARRAY) && 20 if ((digs < MP_WARRAY) &&
29 (MIN(a->used, b->used) < 21 (MP_MIN(a->used, b->used) < MP_MAXFAST)) {
30 (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { 22 return s_mp_mul_digs_fast(a, b, c, digs);
31 return fast_s_mp_mul_digs(a, b, c, digs);
32 } 23 }
33 24
34 if ((res = mp_init_size(&t, digs)) != MP_OKAY) { 25 if ((err = mp_init_size(&t, digs)) != MP_OKAY) {
35 return res; 26 return err;
36 } 27 }
37 t.used = digs; 28 t.used = digs;
38 29
39 /* compute the digits of the product directly */ 30 /* compute the digits of the product directly */
40 pa = a->used; 31 pa = a->used;
41 for (ix = 0; ix < pa; ix++) { 32 for (ix = 0; ix < pa; ix++) {
42 /* set the carry to zero */ 33 /* set the carry to zero */
43 u = 0; 34 u = 0;
44 35
45 /* limit ourselves to making digs digits of output */ 36 /* limit ourselves to making digs digits of output */
46 pb = MIN(b->used, digs - ix); 37 pb = MP_MIN(b->used, digs - ix);
47 38
48 /* setup some aliases */ 39 /* setup some aliases */
49 /* copy of the digit from a used within the nested loop */ 40 /* copy of the digit from a used within the nested loop */
50 tmpx = a->dp[ix]; 41 tmpx = a->dp[ix];
51 42
64 55
65 /* the new column is the lower part of the result */ 56 /* the new column is the lower part of the result */
66 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); 57 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
67 58
68 /* get the carry word from the result */ 59 /* get the carry word from the result */
69 u = (mp_digit)(r >> (mp_word)DIGIT_BIT); 60 u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
70 } 61 }
71 /* set carry if it is placed below digs */ 62 /* set carry if it is placed below digs */
72 if ((ix + iy) < digs) { 63 if ((ix + iy) < digs) {
73 *tmpt = u; 64 *tmpt = u;
74 } 65 }
79 70
80 mp_clear(&t); 71 mp_clear(&t);
81 return MP_OKAY; 72 return MP_OKAY;
82 } 73 }
83 #endif 74 #endif
84
85 /* ref: HEAD -> master, tag: v1.1.0 */
86 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */
87 /* commit time: 2019-01-28 20:32:32 +0100 */