comparison libtommath/bn_fast_mp_montgomery_reduce.c @ 1436:60fc6476e044

Update to libtommath v1.0
author Matt Johnston <matt@ucc.asn.au>
date Sat, 24 Jun 2017 22:37:14 +0800
parents 5ff8218bcee9
children 8bba51a55704
comparison
equal deleted inserted replaced
1435:f849a5ca2efc 1436:60fc6476e044
1 #include <tommath.h> 1 #include <tommath_private.h>
2 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C 2 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis
4 * 4 *
5 * LibTomMath is a library that provides multiple-precision 5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality. 6 * integer arithmetic as well as number theoretic functionality.
10 * additional optimizations in place. 10 * additional optimizations in place.
11 * 11 *
12 * The library is free for all purposes without any express 12 * The library is free for all purposes without any express
13 * guarantee it works. 13 * guarantee it works.
14 * 14 *
15 * Tom St Denis, [email protected], http://math.libtomcrypt.com 15 * Tom St Denis, [email protected], http://libtom.org
16 */ 16 */
17 17
18 /* computes xR**-1 == x (mod N) via Montgomery Reduction 18 /* computes xR**-1 == x (mod N) via Montgomery Reduction
19 * 19 *
20 * This is an optimized implementation of montgomery_reduce 20 * This is an optimized implementation of montgomery_reduce
30 30
31 /* get old used count */ 31 /* get old used count */
32 olduse = x->used; 32 olduse = x->used;
33 33
34 /* grow a as required */ 34 /* grow a as required */
35 if (x->alloc < n->used + 1) { 35 if (x->alloc < (n->used + 1)) {
36 if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { 36 if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
37 return res; 37 return res;
38 } 38 }
39 } 39 }
40 40
41 /* first we have to get the digits of the input into 41 /* first we have to get the digits of the input into
42 * an array of double precision words W[...] 42 * an array of double precision words W[...]
43 */ 43 */
44 { 44 {
45 register mp_word *_W; 45 mp_word *_W;
46 register mp_digit *tmpx; 46 mp_digit *tmpx;
47 47
48 /* alias for the W[] array */ 48 /* alias for the W[] array */
49 _W = W; 49 _W = W;
50 50
51 /* alias for the digits of x*/ 51 /* alias for the digits of x*/
55 for (ix = 0; ix < x->used; ix++) { 55 for (ix = 0; ix < x->used; ix++) {
56 *_W++ = *tmpx++; 56 *_W++ = *tmpx++;
57 } 57 }
58 58
59 /* zero the high words of W[a->used..m->used*2] */ 59 /* zero the high words of W[a->used..m->used*2] */
60 for (; ix < n->used * 2 + 1; ix++) { 60 for (; ix < ((n->used * 2) + 1); ix++) {
61 *_W++ = 0; 61 *_W++ = 0;
62 } 62 }
63 } 63 }
64 64
65 /* now we proceed to zero successive digits 65 /* now we proceed to zero successive digits
70 * 70 *
71 * We avoid a double precision multiplication (which isn't required) 71 * We avoid a double precision multiplication (which isn't required)
72 * by casting the value down to a mp_digit. Note this requires 72 * by casting the value down to a mp_digit. Note this requires
73 * that W[ix-1] have the carry cleared (see after the inner loop) 73 * that W[ix-1] have the carry cleared (see after the inner loop)
74 */ 74 */
75 register mp_digit mu; 75 mp_digit mu;
76 mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); 76 mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
77 77
78 /* a = a + mu * m * b**i 78 /* a = a + mu * m * b**i
79 * 79 *
80 * This is computed in place and on the fly. The multiplication 80 * This is computed in place and on the fly. The multiplication
88 * handled by fixing up one carry after the inner loop. The 88 * handled by fixing up one carry after the inner loop. The
89 * carry fixups are done in order so after these loops the 89 * carry fixups are done in order so after these loops the
90 * first m->used words of W[] have the carries fixed 90 * first m->used words of W[] have the carries fixed
91 */ 91 */
92 { 92 {
93 register int iy; 93 int iy;
94 register mp_digit *tmpn; 94 mp_digit *tmpn;
95 register mp_word *_W; 95 mp_word *_W;
96 96
97 /* alias for the digits of the modulus */ 97 /* alias for the digits of the modulus */
98 tmpn = n->dp; 98 tmpn = n->dp;
99 99
100 /* Alias for the columns set by an offset of ix */ 100 /* Alias for the columns set by an offset of ix */
113 /* now we have to propagate the carries and 113 /* now we have to propagate the carries and
114 * shift the words downward [all those least 114 * shift the words downward [all those least
115 * significant digits we zeroed]. 115 * significant digits we zeroed].
116 */ 116 */
117 { 117 {
118 register mp_digit *tmpx; 118 mp_digit *tmpx;
119 register mp_word *_W, *_W1; 119 mp_word *_W, *_W1;
120 120
121 /* nox fix rest of carries */ 121 /* nox fix rest of carries */
122 122
123 /* alias for current word */ 123 /* alias for current word */
124 _W1 = W + ix; 124 _W1 = W + ix;
125 125
126 /* alias for next word, where the carry goes */ 126 /* alias for next word, where the carry goes */
127 _W = W + ++ix; 127 _W = W + ++ix;
128 128
129 for (; ix <= n->used * 2 + 1; ix++) { 129 for (; ix <= ((n->used * 2) + 1); ix++) {
130 *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); 130 *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
131 } 131 }
132 132
133 /* copy out, A = A/b**n 133 /* copy out, A = A/b**n
134 * 134 *
141 tmpx = x->dp; 141 tmpx = x->dp;
142 142
143 /* alias for shifted double precision result */ 143 /* alias for shifted double precision result */
144 _W = W + n->used; 144 _W = W + n->used;
145 145
146 for (ix = 0; ix < n->used + 1; ix++) { 146 for (ix = 0; ix < (n->used + 1); ix++) {
147 *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); 147 *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
148 } 148 }
149 149
150 /* zero oldused digits, if the input a was larger than 150 /* zero oldused digits, if the input a was larger than
151 * m->used+1 we'll have to clear the digits 151 * m->used+1 we'll have to clear the digits
165 } 165 }
166 return MP_OKAY; 166 return MP_OKAY;
167 } 167 }
168 #endif 168 #endif
169 169
170 /* $Source: /cvs/libtom/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */ 170 /* $Source$ */
171 /* $Revision: 1.3 $ */ 171 /* $Revision$ */
172 /* $Date: 2006/03/31 14:18:44 $ */ 172 /* $Date$ */