comparison bn_mp_exptmod_fast.c @ 190:d8254fc979e9 libtommath-orig LTM_0.35

Initial import of libtommath 0.35
author Matt Johnston <matt@ucc.asn.au>
date Fri, 06 May 2005 08:59:30 +0000
parents d29b64170cf0
children
comparison
equal deleted inserted replaced
142:d29b64170cf0 190:d8254fc979e9
27 #define TAB_SIZE 32 27 #define TAB_SIZE 32
28 #else 28 #else
29 #define TAB_SIZE 256 29 #define TAB_SIZE 256
30 #endif 30 #endif
31 31
32 int 32 int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
33 mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
34 { 33 {
35 mp_int M[TAB_SIZE], res; 34 mp_int M[TAB_SIZE], res;
36 mp_digit buf, mp; 35 mp_digit buf, mp;
37 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; 36 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
38 37
86 /* determine and setup reduction code */ 85 /* determine and setup reduction code */
87 if (redmode == 0) { 86 if (redmode == 0) {
88 #ifdef BN_MP_MONTGOMERY_SETUP_C 87 #ifdef BN_MP_MONTGOMERY_SETUP_C
89 /* now setup montgomery */ 88 /* now setup montgomery */
90 if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { 89 if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
91 goto __M; 90 goto LBL_M;
92 } 91 }
93 #else 92 #else
94 err = MP_VAL; 93 err = MP_VAL;
95 goto __M; 94 goto LBL_M;
96 #endif 95 #endif
97 96
98 /* automatically pick the comba one if available (saves quite a few calls/ifs) */ 97 /* automatically pick the comba one if available (saves quite a few calls/ifs) */
99 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C 98 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
100 if (((P->used * 2 + 1) < MP_WARRAY) && 99 if (((P->used * 2 + 1) < MP_WARRAY) &&
106 #ifdef BN_MP_MONTGOMERY_REDUCE_C 105 #ifdef BN_MP_MONTGOMERY_REDUCE_C
107 /* use slower baseline Montgomery method */ 106 /* use slower baseline Montgomery method */
108 redux = mp_montgomery_reduce; 107 redux = mp_montgomery_reduce;
109 #else 108 #else
110 err = MP_VAL; 109 err = MP_VAL;
111 goto __M; 110 goto LBL_M;
112 #endif 111 #endif
113 } 112 }
114 } else if (redmode == 1) { 113 } else if (redmode == 1) {
115 #if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) 114 #if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
116 /* setup DR reduction for moduli of the form B**k - b */ 115 /* setup DR reduction for moduli of the form B**k - b */
117 mp_dr_setup(P, &mp); 116 mp_dr_setup(P, &mp);
118 redux = mp_dr_reduce; 117 redux = mp_dr_reduce;
119 #else 118 #else
120 err = MP_VAL; 119 err = MP_VAL;
121 goto __M; 120 goto LBL_M;
122 #endif 121 #endif
123 } else { 122 } else {
124 #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) 123 #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
125 /* setup DR reduction for moduli of the form 2**k - b */ 124 /* setup DR reduction for moduli of the form 2**k - b */
126 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { 125 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
127 goto __M; 126 goto LBL_M;
128 } 127 }
129 redux = mp_reduce_2k; 128 redux = mp_reduce_2k;
130 #else 129 #else
131 err = MP_VAL; 130 err = MP_VAL;
132 goto __M; 131 goto LBL_M;
133 #endif 132 #endif
134 } 133 }
135 134
136 /* setup result */ 135 /* setup result */
137 if ((err = mp_init (&res)) != MP_OKAY) { 136 if ((err = mp_init (&res)) != MP_OKAY) {
138 goto __M; 137 goto LBL_M;
139 } 138 }
140 139
141 /* create M table 140 /* create M table
142 * 141 *
143 142
147 146
148 if (redmode == 0) { 147 if (redmode == 0) {
149 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C 148 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
150 /* now we need R mod m */ 149 /* now we need R mod m */
151 if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { 150 if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
152 goto __RES; 151 goto LBL_RES;
153 } 152 }
154 #else 153 #else
155 err = MP_VAL; 154 err = MP_VAL;
156 goto __RES; 155 goto LBL_RES;
157 #endif 156 #endif
158 157
159 /* now set M[1] to G * R mod m */ 158 /* now set M[1] to G * R mod m */
160 if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { 159 if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
161 goto __RES; 160 goto LBL_RES;
162 } 161 }
163 } else { 162 } else {
164 mp_set(&res, 1); 163 mp_set(&res, 1);
165 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { 164 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
166 goto __RES; 165 goto LBL_RES;
167 } 166 }
168 } 167 }
169 168
170 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ 169 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
171 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { 170 if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
172 goto __RES; 171 goto LBL_RES;
173 } 172 }
174 173
175 for (x = 0; x < (winsize - 1); x++) { 174 for (x = 0; x < (winsize - 1); x++) {
176 if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { 175 if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
177 goto __RES; 176 goto LBL_RES;
178 } 177 }
179 if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { 178 if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
180 goto __RES; 179 goto LBL_RES;
181 } 180 }
182 } 181 }
183 182
184 /* create upper table */ 183 /* create upper table */
185 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { 184 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
186 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { 185 if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
187 goto __RES; 186 goto LBL_RES;
188 } 187 }
189 if ((err = redux (&M[x], P, mp)) != MP_OKAY) { 188 if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
190 goto __RES; 189 goto LBL_RES;
191 } 190 }
192 } 191 }
193 192
194 /* set initial mode and bit cnt */ 193 /* set initial mode and bit cnt */
195 mode = 0; 194 mode = 0;
225 } 224 }
226 225
227 /* if the bit is zero and mode == 1 then we square */ 226 /* if the bit is zero and mode == 1 then we square */
228 if (mode == 1 && y == 0) { 227 if (mode == 1 && y == 0) {
229 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { 228 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
230 goto __RES; 229 goto LBL_RES;
231 } 230 }
232 if ((err = redux (&res, P, mp)) != MP_OKAY) { 231 if ((err = redux (&res, P, mp)) != MP_OKAY) {
233 goto __RES; 232 goto LBL_RES;
234 } 233 }
235 continue; 234 continue;
236 } 235 }
237 236
238 /* else we add it to the window */ 237 /* else we add it to the window */
242 if (bitcpy == winsize) { 241 if (bitcpy == winsize) {
243 /* ok window is filled so square as required and multiply */ 242 /* ok window is filled so square as required and multiply */
244 /* square first */ 243 /* square first */
245 for (x = 0; x < winsize; x++) { 244 for (x = 0; x < winsize; x++) {
246 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { 245 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
247 goto __RES; 246 goto LBL_RES;
248 } 247 }
249 if ((err = redux (&res, P, mp)) != MP_OKAY) { 248 if ((err = redux (&res, P, mp)) != MP_OKAY) {
250 goto __RES; 249 goto LBL_RES;
251 } 250 }
252 } 251 }
253 252
254 /* then multiply */ 253 /* then multiply */
255 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { 254 if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
256 goto __RES; 255 goto LBL_RES;
257 } 256 }
258 if ((err = redux (&res, P, mp)) != MP_OKAY) { 257 if ((err = redux (&res, P, mp)) != MP_OKAY) {
259 goto __RES; 258 goto LBL_RES;
260 } 259 }
261 260
262 /* empty window and reset */ 261 /* empty window and reset */
263 bitcpy = 0; 262 bitcpy = 0;
264 bitbuf = 0; 263 bitbuf = 0;
269 /* if bits remain then square/multiply */ 268 /* if bits remain then square/multiply */
270 if (mode == 2 && bitcpy > 0) { 269 if (mode == 2 && bitcpy > 0) {
271 /* square then multiply if the bit is set */ 270 /* square then multiply if the bit is set */
272 for (x = 0; x < bitcpy; x++) { 271 for (x = 0; x < bitcpy; x++) {
273 if ((err = mp_sqr (&res, &res)) != MP_OKAY) { 272 if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
274 goto __RES; 273 goto LBL_RES;
275 } 274 }
276 if ((err = redux (&res, P, mp)) != MP_OKAY) { 275 if ((err = redux (&res, P, mp)) != MP_OKAY) {
277 goto __RES; 276 goto LBL_RES;
278 } 277 }
279 278
280 /* get next bit of the window */ 279 /* get next bit of the window */
281 bitbuf <<= 1; 280 bitbuf <<= 1;
282 if ((bitbuf & (1 << winsize)) != 0) { 281 if ((bitbuf & (1 << winsize)) != 0) {
283 /* then multiply */ 282 /* then multiply */
284 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { 283 if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
285 goto __RES; 284 goto LBL_RES;
286 } 285 }
287 if ((err = redux (&res, P, mp)) != MP_OKAY) { 286 if ((err = redux (&res, P, mp)) != MP_OKAY) {
288 goto __RES; 287 goto LBL_RES;
289 } 288 }
290 } 289 }
291 } 290 }
292 } 291 }
293 292
297 * actually multiplied by R mod n. So we have 296 * actually multiplied by R mod n. So we have
298 * to reduce one more time to cancel out the factor 297 * to reduce one more time to cancel out the factor
299 * of R. 298 * of R.
300 */ 299 */
301 if ((err = redux(&res, P, mp)) != MP_OKAY) { 300 if ((err = redux(&res, P, mp)) != MP_OKAY) {
302 goto __RES; 301 goto LBL_RES;
303 } 302 }
304 } 303 }
305 304
306 /* swap res with Y */ 305 /* swap res with Y */
307 mp_exch (&res, Y); 306 mp_exch (&res, Y);
308 err = MP_OKAY; 307 err = MP_OKAY;
309 __RES:mp_clear (&res); 308 LBL_RES:mp_clear (&res);
310 __M: 309 LBL_M:
311 mp_clear(&M[1]); 310 mp_clear(&M[1]);
312 for (x = 1<<(winsize-1); x < (1 << winsize); x++) { 311 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
313 mp_clear (&M[x]); 312 mp_clear (&M[x]);
314 } 313 }
315 return err; 314 return err;