annotate libtommath/bn_s_mp_mul_digs_fast.c @ 1729:f091f7536aa5

Refer to libtom license files
author Matt Johnston <matt@ucc.asn.au>
date Thu, 25 Jun 2020 23:18:16 +0800
parents 1051e4eea25a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1692
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
1 #include "tommath_private.h"
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
2 #ifdef BN_S_MP_MUL_DIGS_FAST_C
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
4 /* SPDX-License-Identifier: Unlicense */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
5
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
6 /* Fast (comba) multiplier
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
7 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
8 * This is the fast column-array [comba] multiplier. It is
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
9 * designed to compute the columns of the product first
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
10 * then handle the carries afterwards. This has the effect
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
11 * of making the nested loops that compute the columns very
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
12 * simple and schedulable on super-scalar processors.
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
13 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
14 * This has been modified to produce a variable number of
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
15 * digits of output so if say only a half-product is required
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
16 * you don't have to compute the upper half (a feature
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
17 * required for fast Barrett reduction).
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
18 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
19 * Based on Algorithm 14.12 on pp.595 of HAC.
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
20 *
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
21 */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
22 mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs)
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
23 {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
24 int olduse, pa, ix, iz;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
25 mp_err err;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
26 mp_digit W[MP_WARRAY];
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
27 mp_word _W;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
28
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
29 /* grow the destination as required */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
30 if (c->alloc < digs) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
31 if ((err = mp_grow(c, digs)) != MP_OKAY) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
32 return err;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
33 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
34 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
35
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
36 /* number of output digits to produce */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
37 pa = MP_MIN(digs, a->used + b->used);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
38
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
39 /* clear the carry */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
40 _W = 0;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
41 for (ix = 0; ix < pa; ix++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
42 int tx, ty;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
43 int iy;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
44 mp_digit *tmpx, *tmpy;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
45
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
46 /* get offsets into the two bignums */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
47 ty = MP_MIN(b->used-1, ix);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
48 tx = ix - ty;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
49
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
50 /* setup temp aliases */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
51 tmpx = a->dp + tx;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
52 tmpy = b->dp + ty;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
53
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
54 /* this is the number of times the loop will iterrate, essentially
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
55 while (tx++ < a->used && ty-- >= 0) { ... }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
56 */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
57 iy = MP_MIN(a->used-tx, ty+1);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
58
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
59 /* execute loop */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
60 for (iz = 0; iz < iy; ++iz) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
61 _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
62
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
63 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
64
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
65 /* store term */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
66 W[ix] = (mp_digit)_W & MP_MASK;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
67
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
68 /* make next carry */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
69 _W = _W >> (mp_word)MP_DIGIT_BIT;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
70 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
71
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
72 /* setup dest */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
73 olduse = c->used;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
74 c->used = pa;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
75
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
76 {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
77 mp_digit *tmpc;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
78 tmpc = c->dp;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
79 for (ix = 0; ix < pa; ix++) {
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
80 /* now extract the previous digit [below the carry] */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
81 *tmpc++ = W[ix];
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
82 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
83
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
84 /* clear unused digits [that existed in the old copy of c] */
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
85 MP_ZERO_DIGITS(tmpc, olduse - ix);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
86 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
87 mp_clamp(c);
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
88 return MP_OKAY;
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
89 }
1051e4eea25a Update LibTomMath to 1.2.0 (#84)
Steffen Jaeckel <s@jaeckel.eu>
parents:
diff changeset
90 #endif