summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_exp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_exp.c')
-rw-r--r--src/lib/libcrypto/bn/bn_exp.c210
1 files changed, 103 insertions, 107 deletions
diff --git a/src/lib/libcrypto/bn/bn_exp.c b/src/lib/libcrypto/bn/bn_exp.c
index c056a5083f..2df1614ada 100644
--- a/src/lib/libcrypto/bn/bn_exp.c
+++ b/src/lib/libcrypto/bn/bn_exp.c
@@ -60,22 +60,23 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63#define TABLE_SIZE 16
64
63/* slow but works */ 65/* slow but works */
64int BN_mod_mul(ret, a, b, m, ctx) 66int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
65BIGNUM *ret;
66BIGNUM *a;
67BIGNUM *b;
68BIGNUM *m;
69BN_CTX *ctx;
70 { 67 {
71 BIGNUM *t; 68 BIGNUM *t;
72 int r=0; 69 int r=0;
73 70
74 t=ctx->bn[ctx->tos++]; 71 bn_check_top(a);
72 bn_check_top(b);
73 bn_check_top(m);
74
75 t= &(ctx->bn[ctx->tos++]);
75 if (a == b) 76 if (a == b)
76 { if (!BN_sqr(t,a,ctx)) goto err; } 77 { if (!BN_sqr(t,a,ctx)) goto err; }
77 else 78 else
78 { if (!BN_mul(t,a,b)) goto err; } 79 { if (!BN_mul(t,a,b,ctx)) goto err; }
79 if (!BN_mod(ret,t,m,ctx)) goto err; 80 if (!BN_mod(ret,t,m,ctx)) goto err;
80 r=1; 81 r=1;
81err: 82err:
@@ -85,22 +86,20 @@ err:
85 86
86#if 0 87#if 0
87/* this one works - simple but works */ 88/* this one works - simple but works */
88int BN_mod_exp(r,a,p,m,ctx) 89int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
89BIGNUM *r,*a,*p,*m;
90BN_CTX *ctx;
91 { 90 {
92 int i,bits,ret=0; 91 int i,bits,ret=0;
93 BIGNUM *v,*tmp; 92 BIGNUM *v,*tmp;
94 93
95 v=ctx->bn[ctx->tos++]; 94 v= &(ctx->bn[ctx->tos++]);
96 tmp=ctx->bn[ctx->tos++]; 95 tmp= &(ctx->bn[ctx->tos++]);
97 96
98 if (BN_copy(v,a) == NULL) goto err; 97 if (BN_copy(v,a) == NULL) goto err;
99 bits=BN_num_bits(p); 98 bits=BN_num_bits(p);
100 99
101 if (BN_is_odd(p)) 100 if (BN_is_odd(p))
102 { if (BN_copy(r,a) == NULL) goto err; } 101 { if (BN_copy(r,a) == NULL) goto err; }
103 else { if (BN_one(r)) goto err; } 102 else { if (!BN_one(r)) goto err; }
104 103
105 for (i=1; i<bits; i++) 104 for (i=1; i<bits; i++)
106 { 105 {
@@ -108,7 +107,7 @@ BN_CTX *ctx;
108 if (!BN_mod(v,tmp,m,ctx)) goto err; 107 if (!BN_mod(v,tmp,m,ctx)) goto err;
109 if (BN_is_bit_set(p,i)) 108 if (BN_is_bit_set(p,i))
110 { 109 {
111 if (!BN_mul(tmp,r,v)) goto err; 110 if (!BN_mul(tmp,r,v,ctx)) goto err;
112 if (!BN_mod(r,tmp,m,ctx)) goto err; 111 if (!BN_mod(r,tmp,m,ctx)) goto err;
113 } 112 }
114 } 113 }
@@ -121,46 +120,49 @@ err:
121#endif 120#endif
122 121
123/* this one works - simple but works */ 122/* this one works - simple but works */
124int BN_exp(r,a,p,ctx) 123int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
125BIGNUM *r,*a,*p;
126BN_CTX *ctx;
127 { 124 {
128 int i,bits,ret=0; 125 int i,bits,ret=0,tos;
129 BIGNUM *v,*tmp; 126 BIGNUM *v,*rr;
130 127
131 v=ctx->bn[ctx->tos++]; 128 tos=ctx->tos;
132 tmp=ctx->bn[ctx->tos++]; 129 v= &(ctx->bn[ctx->tos++]);
130 if ((r == a) || (r == p))
131 rr= &(ctx->bn[ctx->tos++]);
132 else
133 rr=r;
133 134
134 if (BN_copy(v,a) == NULL) goto err; 135 if (BN_copy(v,a) == NULL) goto err;
135 bits=BN_num_bits(p); 136 bits=BN_num_bits(p);
136 137
137 if (BN_is_odd(p)) 138 if (BN_is_odd(p))
138 { if (BN_copy(r,a) == NULL) goto err; } 139 { if (BN_copy(rr,a) == NULL) goto err; }
139 else { if (BN_one(r)) goto err; } 140 else { if (!BN_one(rr)) goto err; }
140 141
141 for (i=1; i<bits; i++) 142 for (i=1; i<bits; i++)
142 { 143 {
143 if (!BN_sqr(tmp,v,ctx)) goto err; 144 if (!BN_sqr(v,v,ctx)) goto err;
144 if (BN_is_bit_set(p,i)) 145 if (BN_is_bit_set(p,i))
145 { 146 {
146 if (!BN_mul(tmp,r,v)) goto err; 147 if (!BN_mul(rr,rr,v,ctx)) goto err;
147 } 148 }
148 } 149 }
149 ret=1; 150 ret=1;
150err: 151err:
151 ctx->tos-=2; 152 ctx->tos=tos;
153 if (r != rr) BN_copy(r,rr);
152 return(ret); 154 return(ret);
153 } 155 }
154 156
155int BN_mod_exp(r,a,p,m,ctx) 157int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
156BIGNUM *r; 158 BN_CTX *ctx)
157BIGNUM *a;
158BIGNUM *p;
159BIGNUM *m;
160BN_CTX *ctx;
161 { 159 {
162 int ret; 160 int ret;
163 161
162 bn_check_top(a);
163 bn_check_top(p);
164 bn_check_top(m);
165
164#ifdef MONT_MUL_MOD 166#ifdef MONT_MUL_MOD
165 /* I have finally been able to take out this pre-condition of 167 /* I have finally been able to take out this pre-condition of
166 * the top bit being set. It was caused by an error in BN_div 168 * the top bit being set. It was caused by an error in BN_div
@@ -182,20 +184,16 @@ BN_CTX *ctx;
182 } 184 }
183 185
184/* #ifdef RECP_MUL_MOD */ 186/* #ifdef RECP_MUL_MOD */
185int BN_mod_exp_recp(r,a,p,m,ctx) 187int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
186BIGNUM *r; 188 const BIGNUM *m, BN_CTX *ctx)
187BIGNUM *a;
188BIGNUM *p;
189BIGNUM *m;
190BN_CTX *ctx;
191 { 189 {
192 int nb,i,j,bits,ret=0,wstart,wend,window,wvalue; 190 int i,j,bits,ret=0,wstart,wend,window,wvalue;
193 int start=1; 191 int start=1,ts=0;
194 BIGNUM *d,*aa; 192 BIGNUM *aa;
195 BIGNUM *val[16]; 193 BIGNUM val[TABLE_SIZE];
194 BN_RECP_CTX recp;
196 195
197 d=ctx->bn[ctx->tos++]; 196 aa= &(ctx->bn[ctx->tos++]);
198 aa=ctx->bn[ctx->tos++];
199 bits=BN_num_bits(p); 197 bits=BN_num_bits(p);
200 198
201 if (bits == 0) 199 if (bits == 0)
@@ -203,12 +201,14 @@ BN_CTX *ctx;
203 BN_one(r); 201 BN_one(r);
204 return(1); 202 return(1);
205 } 203 }
206 nb=BN_reciprocal(d,m,ctx); 204 BN_RECP_CTX_init(&recp);
207 if (nb == -1) goto err; 205 if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
208 206
209 val[0]=BN_new(); 207 BN_init(&(val[0]));
210 if (!BN_mod(val[0],a,m,ctx)) goto err; /* 1 */ 208 ts=1;
211 if (!BN_mod_mul_reciprocal(aa,val[0],val[0],m,d,nb,ctx)) 209
210 if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
211 if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
212 goto err; /* 2 */ 212 goto err; /* 2 */
213 213
214 if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */ 214 if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
@@ -223,12 +223,11 @@ BN_CTX *ctx;
223 j=1<<(window-1); 223 j=1<<(window-1);
224 for (i=1; i<j; i++) 224 for (i=1; i<j; i++)
225 { 225 {
226 val[i]=BN_new(); 226 BN_init(&val[i]);
227 if (!BN_mod_mul_reciprocal(val[i],val[i-1],aa,m,d,nb,ctx)) 227 if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
228 goto err; 228 goto err;
229 } 229 }
230 for (; i<16; i++) 230 ts=i;
231 val[i]=NULL;
232 231
233 start=1; /* This is used to avoid multiplication etc 232 start=1; /* This is used to avoid multiplication etc
234 * when there is only the value '1' in the 233 * when there is only the value '1' in the
@@ -244,7 +243,7 @@ BN_CTX *ctx;
244 if (BN_is_bit_set(p,wstart) == 0) 243 if (BN_is_bit_set(p,wstart) == 0)
245 { 244 {
246 if (!start) 245 if (!start)
247 if (!BN_mod_mul_reciprocal(r,r,r,m,d,nb,ctx)) 246 if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
248 goto err; 247 goto err;
249 if (wstart == 0) break; 248 if (wstart == 0) break;
250 wstart--; 249 wstart--;
@@ -274,12 +273,12 @@ BN_CTX *ctx;
274 if (!start) 273 if (!start)
275 for (i=0; i<j; i++) 274 for (i=0; i<j; i++)
276 { 275 {
277 if (!BN_mod_mul_reciprocal(r,r,r,m,d,nb,ctx)) 276 if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
278 goto err; 277 goto err;
279 } 278 }
280 279
281 /* wvalue will be an odd number < 2^window */ 280 /* wvalue will be an odd number < 2^window */
282 if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],m,d,nb,ctx)) 281 if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
283 goto err; 282 goto err;
284 283
285 /* move the 'window' down further */ 284 /* move the 'window' down further */
@@ -290,35 +289,36 @@ BN_CTX *ctx;
290 } 289 }
291 ret=1; 290 ret=1;
292err: 291err:
293 ctx->tos-=2; 292 ctx->tos--;
294 for (i=0; i<16; i++) 293 for (i=0; i<ts; i++)
295 if (val[i] != NULL) BN_clear_free(val[i]); 294 BN_clear_free(&(val[i]));
295 BN_RECP_CTX_free(&recp);
296 return(ret); 296 return(ret);
297 } 297 }
298/* #endif */ 298/* #endif */
299 299
300/* #ifdef MONT_MUL_MOD */ 300/* #ifdef MONT_MUL_MOD */
301int BN_mod_exp_mont(r,a,p,m,ctx,in_mont) 301int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
302BIGNUM *r; 302 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
303BIGNUM *a;
304BIGNUM *p;
305BIGNUM *m;
306BN_CTX *ctx;
307BN_MONT_CTX *in_mont;
308 { 303 {
309#define TABLE_SIZE 16
310 int i,j,bits,ret=0,wstart,wend,window,wvalue; 304 int i,j,bits,ret=0,wstart,wend,window,wvalue;
311 int start=1; 305 int start=1,ts=0;
312 BIGNUM *d,*aa; 306 BIGNUM *d,*r;
313 BIGNUM *val[TABLE_SIZE]; 307 BIGNUM *aa;
308 BIGNUM val[TABLE_SIZE];
314 BN_MONT_CTX *mont=NULL; 309 BN_MONT_CTX *mont=NULL;
315 310
311 bn_check_top(a);
312 bn_check_top(p);
313 bn_check_top(m);
314
316 if (!(m->d[0] & 1)) 315 if (!(m->d[0] & 1))
317 { 316 {
318 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); 317 BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
319 return(0); 318 return(0);
320 } 319 }
321 d=ctx->bn[ctx->tos++]; 320 d= &(ctx->bn[ctx->tos++]);
321 r= &(ctx->bn[ctx->tos++]);
322 bits=BN_num_bits(p); 322 bits=BN_num_bits(p);
323 if (bits == 0) 323 if (bits == 0)
324 { 324 {
@@ -339,22 +339,23 @@ BN_MONT_CTX *in_mont;
339 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; 339 if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
340 } 340 }
341 341
342 val[0]=BN_new(); 342 BN_init(&val[0]);
343 ts=1;
343 if (BN_ucmp(a,m) >= 0) 344 if (BN_ucmp(a,m) >= 0)
344 { 345 {
345 BN_mod(val[0],a,m,ctx); 346 BN_mod(&(val[0]),a,m,ctx);
346 aa=val[0]; 347 aa= &(val[0]);
347 } 348 }
348 else 349 else
349 aa=a; 350 aa=a;
350 if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */ 351 if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
351 if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */ 352 if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */
352 353
353 if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */ 354 if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */
354 window=1; 355 window=1;
355 else if (bits > 250) 356 else if (bits >= 256)
356 window=5; /* max size of window */ 357 window=5; /* max size of window */
357 else if (bits >= 120) 358 else if (bits >= 128)
358 window=4; 359 window=4;
359 else 360 else
360 window=3; 361 window=3;
@@ -362,12 +363,11 @@ BN_MONT_CTX *in_mont;
362 j=1<<(window-1); 363 j=1<<(window-1);
363 for (i=1; i<j; i++) 364 for (i=1; i<j; i++)
364 { 365 {
365 val[i]=BN_new(); 366 BN_init(&(val[i]));
366 if (!BN_mod_mul_montgomery(val[i],val[i-1],d,mont,ctx)) 367 if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx))
367 goto err; 368 goto err;
368 } 369 }
369 for (; i<TABLE_SIZE; i++) 370 ts=i;
370 val[i]=NULL;
371 371
372 start=1; /* This is used to avoid multiplication etc 372 start=1; /* This is used to avoid multiplication etc
373 * when there is only the value '1' in the 373 * when there is only the value '1' in the
@@ -419,7 +419,7 @@ BN_MONT_CTX *in_mont;
419 } 419 }
420 420
421 /* wvalue will be an odd number < 2^window */ 421 /* wvalue will be an odd number < 2^window */
422 if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx)) 422 if (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx))
423 goto err; 423 goto err;
424 424
425 /* move the 'window' down further */ 425 /* move the 'window' down further */
@@ -428,31 +428,27 @@ BN_MONT_CTX *in_mont;
428 start=0; 428 start=0;
429 if (wstart < 0) break; 429 if (wstart < 0) break;
430 } 430 }
431 BN_from_montgomery(r,r,mont,ctx); 431 BN_from_montgomery(rr,r,mont,ctx);
432 ret=1; 432 ret=1;
433err: 433err:
434 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); 434 if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
435 ctx->tos--; 435 ctx->tos-=2;
436 for (i=0; i<TABLE_SIZE; i++) 436 for (i=0; i<ts; i++)
437 if (val[i] != NULL) BN_clear_free(val[i]); 437 BN_clear_free(&(val[i]));
438 return(ret); 438 return(ret);
439 } 439 }
440/* #endif */ 440/* #endif */
441 441
442/* The old fallback, simple version :-) */ 442/* The old fallback, simple version :-) */
443int BN_mod_exp_simple(r,a,p,m,ctx) 443int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
444BIGNUM *r; 444 BN_CTX *ctx)
445BIGNUM *a;
446BIGNUM *p;
447BIGNUM *m;
448BN_CTX *ctx;
449 { 445 {
450 int i,j,bits,ret=0,wstart,wend,window,wvalue; 446 int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
451 int start=1; 447 int start=1;
452 BIGNUM *d; 448 BIGNUM *d;
453 BIGNUM *val[16]; 449 BIGNUM val[TABLE_SIZE];
454 450
455 d=ctx->bn[ctx->tos++]; 451 d= &(ctx->bn[ctx->tos++]);
456 bits=BN_num_bits(p); 452 bits=BN_num_bits(p);
457 453
458 if (bits == 0) 454 if (bits == 0)
@@ -461,9 +457,10 @@ BN_CTX *ctx;
461 return(1); 457 return(1);
462 } 458 }
463 459
464 val[0]=BN_new(); 460 BN_init(&(val[0]));
465 if (!BN_mod(val[0],a,m,ctx)) goto err; /* 1 */ 461 ts=1;
466 if (!BN_mod_mul(d,val[0],val[0],m,ctx)) 462 if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
463 if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx))
467 goto err; /* 2 */ 464 goto err; /* 2 */
468 465
469 if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */ 466 if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
@@ -478,12 +475,11 @@ BN_CTX *ctx;
478 j=1<<(window-1); 475 j=1<<(window-1);
479 for (i=1; i<j; i++) 476 for (i=1; i<j; i++)
480 { 477 {
481 val[i]=BN_new(); 478 BN_init(&(val[i]));
482 if (!BN_mod_mul(val[i],val[i-1],d,m,ctx)) 479 if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx))
483 goto err; 480 goto err;
484 } 481 }
485 for (; i<16; i++) 482 ts=i;
486 val[i]=NULL;
487 483
488 start=1; /* This is used to avoid multiplication etc 484 start=1; /* This is used to avoid multiplication etc
489 * when there is only the value '1' in the 485 * when there is only the value '1' in the
@@ -534,7 +530,7 @@ BN_CTX *ctx;
534 } 530 }
535 531
536 /* wvalue will be an odd number < 2^window */ 532 /* wvalue will be an odd number < 2^window */
537 if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx)) 533 if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx))
538 goto err; 534 goto err;
539 535
540 /* move the 'window' down further */ 536 /* move the 'window' down further */
@@ -546,8 +542,8 @@ BN_CTX *ctx;
546 ret=1; 542 ret=1;
547err: 543err:
548 ctx->tos--; 544 ctx->tos--;
549 for (i=0; i<16; i++) 545 for (i=0; i<ts; i++)
550 if (val[i] != NULL) BN_clear_free(val[i]); 546 BN_clear_free(&(val[i]));
551 return(ret); 547 return(ret);
552 } 548 }
553 549