diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_prime.c')
| -rw-r--r-- | src/lib/libcrypto/bn/bn_prime.c | 393 |
1 files changed, 209 insertions, 184 deletions
diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c index 7b25979dd1..7d4cab4acd 100644 --- a/src/lib/libcrypto/bn/bn_prime.c +++ b/src/lib/libcrypto/bn/bn_prime.c | |||
| @@ -5,21 +5,21 @@ | |||
| 5 | * This package is an SSL implementation written | 5 | * This package is an SSL implementation written |
| 6 | * by Eric Young (eay@cryptsoft.com). | 6 | * by Eric Young (eay@cryptsoft.com). |
| 7 | * The implementation was written so as to conform with Netscapes SSL. | 7 | * The implementation was written so as to conform with Netscapes SSL. |
| 8 | * | 8 | * |
| 9 | * This library is free for commercial and non-commercial use as long as | 9 | * This library is free for commercial and non-commercial use as long as |
| 10 | * the following conditions are aheared to. The following conditions | 10 | * the following conditions are aheared to. The following conditions |
| 11 | * apply to all code found in this distribution, be it the RC4, RSA, | 11 | * apply to all code found in this distribution, be it the RC4, RSA, |
| 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | 12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
| 13 | * included with this distribution is covered by the same copyright terms | 13 | * included with this distribution is covered by the same copyright terms |
| 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | 14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
| 15 | * | 15 | * |
| 16 | * Copyright remains Eric Young's, and as such any Copyright notices in | 16 | * Copyright remains Eric Young's, and as such any Copyright notices in |
| 17 | * the code are not to be removed. | 17 | * the code are not to be removed. |
| 18 | * If this package is used in a product, Eric Young should be given attribution | 18 | * If this package is used in a product, Eric Young should be given attribution |
| 19 | * as the author of the parts of the library used. | 19 | * as the author of the parts of the library used. |
| 20 | * This can be in the form of a textual message at program startup or | 20 | * This can be in the form of a textual message at program startup or |
| 21 | * in documentation (online or textual) provided with the package. | 21 | * in documentation (online or textual) provided with the package. |
| 22 | * | 22 | * |
| 23 | * Redistribution and use in source and binary forms, with or without | 23 | * Redistribution and use in source and binary forms, with or without |
| 24 | * modification, are permitted provided that the following conditions | 24 | * modification, are permitted provided that the following conditions |
| 25 | * are met: | 25 | * are met: |
| @@ -34,10 +34,10 @@ | |||
| 34 | * Eric Young (eay@cryptsoft.com)" | 34 | * Eric Young (eay@cryptsoft.com)" |
| 35 | * The word 'cryptographic' can be left out if the rouines from the library | 35 | * The word 'cryptographic' can be left out if the rouines from the library |
| 36 | * being used are not cryptographic related :-). | 36 | * being used are not cryptographic related :-). |
| 37 | * 4. If you include any Windows specific code (or a derivative thereof) from | 37 | * 4. If you include any Windows specific code (or a derivative thereof) from |
| 38 | * the apps directory (application code) you must include an acknowledgement: | 38 | * the apps directory (application code) you must include an acknowledgement: |
| 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | 39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
| 40 | * | 40 | * |
| 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | 41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
| 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| @@ -49,7 +49,7 @@ | |||
| 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 51 | * SUCH DAMAGE. | 51 | * SUCH DAMAGE. |
| 52 | * | 52 | * |
| 53 | * The licence and distribution terms for any publically available version or | 53 | * The licence and distribution terms for any publically available version or |
| 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | 54 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
| 55 | * copied and put under another distribution licence | 55 | * copied and put under another distribution licence |
| @@ -63,7 +63,7 @@ | |||
| 63 | * are met: | 63 | * are met: |
| 64 | * | 64 | * |
| 65 | * 1. Redistributions of source code must retain the above copyright | 65 | * 1. Redistributions of source code must retain the above copyright |
| 66 | * notice, this list of conditions and the following disclaimer. | 66 | * notice, this list of conditions and the following disclaimer. |
| 67 | * | 67 | * |
| 68 | * 2. Redistributions in binary form must reproduce the above copyright | 68 | * 2. Redistributions in binary form must reproduce the above copyright |
| 69 | * notice, this list of conditions and the following disclaimer in | 69 | * notice, this list of conditions and the following disclaimer in |
| @@ -127,22 +127,23 @@ | |||
| 127 | #include "bn_prime.h" | 127 | #include "bn_prime.h" |
| 128 | 128 | ||
| 129 | static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, | 129 | static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, |
| 130 | const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont); | 130 | const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont); |
| 131 | static int probable_prime(BIGNUM *rnd, int bits); | 131 | static int probable_prime(BIGNUM *rnd, int bits); |
| 132 | static int probable_prime_dh(BIGNUM *rnd, int bits, | 132 | static int probable_prime_dh(BIGNUM *rnd, int bits, |
| 133 | const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); | 133 | const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); |
| 134 | static int probable_prime_dh_safe(BIGNUM *rnd, int bits, | 134 | static int probable_prime_dh_safe(BIGNUM *rnd, int bits, |
| 135 | const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); | 135 | const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx); |
| 136 | 136 | ||
| 137 | int BN_GENCB_call(BN_GENCB *cb, int a, int b) | 137 | int |
| 138 | { | 138 | BN_GENCB_call(BN_GENCB *cb, int a, int b) |
| 139 | { | ||
| 139 | /* No callback means continue */ | 140 | /* No callback means continue */ |
| 140 | if(!cb) return 1; | 141 | if (!cb) |
| 141 | switch(cb->ver) | 142 | return 1; |
| 142 | { | 143 | switch (cb->ver) { |
| 143 | case 1: | 144 | case 1: |
| 144 | /* Deprecated-style callbacks */ | 145 | /* Deprecated-style callbacks */ |
| 145 | if(!cb->cb.cb_1) | 146 | if (!cb->cb.cb_1) |
| 146 | return 1; | 147 | return 1; |
| 147 | cb->cb.cb_1(a, b, cb->arg); | 148 | cb->cb.cb_1(a, b, cb->arg); |
| 148 | return 1; | 149 | return 1; |
| @@ -151,98 +152,101 @@ int BN_GENCB_call(BN_GENCB *cb, int a, int b) | |||
| 151 | return cb->cb.cb_2(a, b, cb); | 152 | return cb->cb.cb_2(a, b, cb); |
| 152 | default: | 153 | default: |
| 153 | break; | 154 | break; |
| 154 | } | 155 | } |
| 155 | /* Unrecognised callback type */ | 156 | /* Unrecognised callback type */ |
| 156 | return 0; | 157 | return 0; |
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, | 160 | int |
| 160 | const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) | 161 | BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, |
| 161 | { | 162 | const BIGNUM *rem, BN_GENCB *cb) |
| 163 | { | ||
| 162 | BIGNUM *t; | 164 | BIGNUM *t; |
| 163 | int found=0; | 165 | int found = 0; |
| 164 | int i,j,c1=0; | 166 | int i, j, c1 = 0; |
| 165 | BN_CTX *ctx; | 167 | BN_CTX *ctx; |
| 166 | int checks = BN_prime_checks_for_size(bits); | 168 | int checks = BN_prime_checks_for_size(bits); |
| 167 | 169 | ||
| 168 | ctx=BN_CTX_new(); | 170 | ctx = BN_CTX_new(); |
| 169 | if (ctx == NULL) goto err; | 171 | if (ctx == NULL) |
| 172 | goto err; | ||
| 170 | BN_CTX_start(ctx); | 173 | BN_CTX_start(ctx); |
| 171 | t = BN_CTX_get(ctx); | 174 | t = BN_CTX_get(ctx); |
| 172 | if(!t) goto err; | 175 | if (!t) |
| 173 | loop: | 176 | goto err; |
| 177 | loop: | ||
| 174 | /* make a random number and set the top and bottom bits */ | 178 | /* make a random number and set the top and bottom bits */ |
| 175 | if (add == NULL) | 179 | if (add == NULL) { |
| 176 | { | 180 | if (!probable_prime(ret, bits)) |
| 177 | if (!probable_prime(ret,bits)) goto err; | 181 | goto err; |
| 178 | } | 182 | } else { |
| 179 | else | 183 | if (safe) { |
| 180 | { | 184 | if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) |
| 181 | if (safe) | 185 | goto err; |
| 182 | { | 186 | } else { |
| 183 | if (!probable_prime_dh_safe(ret,bits,add,rem,ctx)) | 187 | if (!probable_prime_dh(ret, bits, add, rem, ctx)) |
| 184 | goto err; | ||
| 185 | } | ||
| 186 | else | ||
| 187 | { | ||
| 188 | if (!probable_prime_dh(ret,bits,add,rem,ctx)) | ||
| 189 | goto err; | 188 | goto err; |
| 190 | } | ||
| 191 | } | 189 | } |
| 190 | } | ||
| 192 | /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ | 191 | /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ |
| 193 | if(!BN_GENCB_call(cb, 0, c1++)) | 192 | if (!BN_GENCB_call(cb, 0, c1++)) |
| 194 | /* aborted */ | 193 | /* aborted */ |
| 195 | goto err; | 194 | goto err; |
| 196 | 195 | ||
| 197 | if (!safe) | 196 | if (!safe) { |
| 198 | { | 197 | i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); |
| 199 | i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb); | 198 | if (i == -1) |
| 200 | if (i == -1) goto err; | 199 | goto err; |
| 201 | if (i == 0) goto loop; | 200 | if (i == 0) |
| 202 | } | 201 | goto loop; |
| 203 | else | 202 | } else { |
| 204 | { | ||
| 205 | /* for "safe prime" generation, | 203 | /* for "safe prime" generation, |
| 206 | * check that (p-1)/2 is prime. | 204 | * check that (p-1)/2 is prime. |
| 207 | * Since a prime is odd, We just | 205 | * Since a prime is odd, We just |
| 208 | * need to divide by 2 */ | 206 | * need to divide by 2 */ |
| 209 | if (!BN_rshift1(t,ret)) goto err; | 207 | if (!BN_rshift1(t, ret)) |
| 208 | goto err; | ||
| 210 | 209 | ||
| 211 | for (i=0; i<checks; i++) | 210 | for (i = 0; i < checks; i++) { |
| 212 | { | 211 | j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb); |
| 213 | j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb); | 212 | if (j == -1) |
| 214 | if (j == -1) goto err; | 213 | goto err; |
| 215 | if (j == 0) goto loop; | 214 | if (j == 0) |
| 215 | goto loop; | ||
| 216 | 216 | ||
| 217 | j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb); | 217 | j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb); |
| 218 | if (j == -1) goto err; | 218 | if (j == -1) |
| 219 | if (j == 0) goto loop; | 219 | goto err; |
| 220 | if (j == 0) | ||
| 221 | goto loop; | ||
| 220 | 222 | ||
| 221 | if(!BN_GENCB_call(cb, 2, c1-1)) | 223 | if (!BN_GENCB_call(cb, 2, c1 - 1)) |
| 222 | goto err; | 224 | goto err; |
| 223 | /* We have a safe prime test pass */ | 225 | /* We have a safe prime test pass */ |
| 224 | } | ||
| 225 | } | 226 | } |
| 227 | } | ||
| 226 | /* we have a prime :-) */ | 228 | /* we have a prime :-) */ |
| 227 | found = 1; | 229 | found = 1; |
| 230 | |||
| 228 | err: | 231 | err: |
| 229 | if (ctx != NULL) | 232 | if (ctx != NULL) { |
| 230 | { | ||
| 231 | BN_CTX_end(ctx); | 233 | BN_CTX_end(ctx); |
| 232 | BN_CTX_free(ctx); | 234 | BN_CTX_free(ctx); |
| 233 | } | 235 | } |
| 234 | bn_check_top(ret); | 236 | bn_check_top(ret); |
| 235 | return found; | 237 | return found; |
| 236 | } | 238 | } |
| 237 | 239 | ||
| 238 | int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb) | 240 | int |
| 239 | { | 241 | BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_GENCB *cb) |
| 242 | { | ||
| 240 | return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); | 243 | return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); |
| 241 | } | 244 | } |
| 242 | 245 | ||
| 243 | int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, | 246 | int |
| 244 | int do_trial_division, BN_GENCB *cb) | 247 | BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, |
| 245 | { | 248 | int do_trial_division, BN_GENCB *cb) |
| 249 | { | ||
| 246 | int i, j, ret = -1; | 250 | int i, j, ret = -1; |
| 247 | int k; | 251 | int k; |
| 248 | BN_CTX *ctx = NULL; | 252 | BN_CTX *ctx = NULL; |
| @@ -252,7 +256,7 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, | |||
| 252 | 256 | ||
| 253 | if (BN_cmp(a, BN_value_one()) <= 0) | 257 | if (BN_cmp(a, BN_value_one()) <= 0) |
| 254 | return 0; | 258 | return 0; |
| 255 | 259 | ||
| 256 | if (checks == BN_prime_checks) | 260 | if (checks == BN_prime_checks) |
| 257 | checks = BN_prime_checks_for_size(BN_num_bits(a)); | 261 | checks = BN_prime_checks_for_size(BN_num_bits(a)); |
| 258 | 262 | ||
| @@ -260,48 +264,45 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, | |||
| 260 | if (!BN_is_odd(a)) | 264 | if (!BN_is_odd(a)) |
| 261 | /* a is even => a is prime if and only if a == 2 */ | 265 | /* a is even => a is prime if and only if a == 2 */ |
| 262 | return BN_is_word(a, 2); | 266 | return BN_is_word(a, 2); |
| 263 | if (do_trial_division) | 267 | if (do_trial_division) { |
| 264 | { | ||
| 265 | for (i = 1; i < NUMPRIMES; i++) | 268 | for (i = 1; i < NUMPRIMES; i++) |
| 266 | if (BN_mod_word(a, primes[i]) == 0) | 269 | if (BN_mod_word(a, primes[i]) == 0) |
| 267 | return 0; | 270 | return 0; |
| 268 | if(!BN_GENCB_call(cb, 1, -1)) | 271 | if (!BN_GENCB_call(cb, 1, -1)) |
| 269 | goto err; | 272 | goto err; |
| 270 | } | 273 | } |
| 271 | 274 | ||
| 272 | if (ctx_passed != NULL) | 275 | if (ctx_passed != NULL) |
| 273 | ctx = ctx_passed; | 276 | ctx = ctx_passed; |
| 274 | else | 277 | else if ((ctx = BN_CTX_new()) == NULL) |
| 275 | if ((ctx=BN_CTX_new()) == NULL) | 278 | goto err; |
| 276 | goto err; | ||
| 277 | BN_CTX_start(ctx); | 279 | BN_CTX_start(ctx); |
| 278 | 280 | ||
| 279 | /* A := abs(a) */ | 281 | /* A := abs(a) */ |
| 280 | if (a->neg) | 282 | if (a->neg) { |
| 281 | { | ||
| 282 | BIGNUM *t; | 283 | BIGNUM *t; |
| 283 | if ((t = BN_CTX_get(ctx)) == NULL) goto err; | 284 | if ((t = BN_CTX_get(ctx)) == NULL) |
| 285 | goto err; | ||
| 284 | BN_copy(t, a); | 286 | BN_copy(t, a); |
| 285 | t->neg = 0; | 287 | t->neg = 0; |
| 286 | A = t; | 288 | A = t; |
| 287 | } | 289 | } else |
| 288 | else | ||
| 289 | A = a; | 290 | A = a; |
| 290 | A1 = BN_CTX_get(ctx); | 291 | A1 = BN_CTX_get(ctx); |
| 291 | A1_odd = BN_CTX_get(ctx); | 292 | A1_odd = BN_CTX_get(ctx); |
| 292 | check = BN_CTX_get(ctx); | 293 | check = BN_CTX_get(ctx); |
| 293 | if (check == NULL) goto err; | 294 | if (check == NULL) |
| 295 | goto err; | ||
| 294 | 296 | ||
| 295 | /* compute A1 := A - 1 */ | 297 | /* compute A1 := A - 1 */ |
| 296 | if (!BN_copy(A1, A)) | 298 | if (!BN_copy(A1, A)) |
| 297 | goto err; | 299 | goto err; |
| 298 | if (!BN_sub_word(A1, 1)) | 300 | if (!BN_sub_word(A1, 1)) |
| 299 | goto err; | 301 | goto err; |
| 300 | if (BN_is_zero(A1)) | 302 | if (BN_is_zero(A1)) { |
| 301 | { | ||
| 302 | ret = 0; | 303 | ret = 0; |
| 303 | goto err; | 304 | goto err; |
| 304 | } | 305 | } |
| 305 | 306 | ||
| 306 | /* write A1 as A1_odd * 2^k */ | 307 | /* write A1 as A1_odd * 2^k */ |
| 307 | k = 1; | 308 | k = 1; |
| @@ -316,9 +317,8 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, | |||
| 316 | goto err; | 317 | goto err; |
| 317 | if (!BN_MONT_CTX_set(mont, A, ctx)) | 318 | if (!BN_MONT_CTX_set(mont, A, ctx)) |
| 318 | goto err; | 319 | goto err; |
| 319 | 320 | ||
| 320 | for (i = 0; i < checks; i++) | 321 | for (i = 0; i < checks; i++) { |
| 321 | { | ||
| 322 | if (!BN_pseudo_rand_range(check, A1)) | 322 | if (!BN_pseudo_rand_range(check, A1)) |
| 323 | goto err; | 323 | goto err; |
| 324 | if (!BN_add_word(check, 1)) | 324 | if (!BN_add_word(check, 1)) |
| @@ -326,40 +326,41 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, | |||
| 326 | /* now 1 <= check < A */ | 326 | /* now 1 <= check < A */ |
| 327 | 327 | ||
| 328 | j = witness(check, A, A1, A1_odd, k, ctx, mont); | 328 | j = witness(check, A, A1, A1_odd, k, ctx, mont); |
| 329 | if (j == -1) goto err; | 329 | if (j == -1) |
| 330 | if (j) | ||
| 331 | { | ||
| 332 | ret=0; | ||
| 333 | goto err; | 330 | goto err; |
| 334 | } | 331 | if (j) { |
| 335 | if(!BN_GENCB_call(cb, 1, i)) | 332 | ret = 0; |
| 336 | goto err; | 333 | goto err; |
| 337 | } | 334 | } |
| 338 | ret=1; | 335 | if (!BN_GENCB_call(cb, 1, i)) |
| 336 | goto err; | ||
| 337 | } | ||
| 338 | ret = 1; | ||
| 339 | |||
| 339 | err: | 340 | err: |
| 340 | if (ctx != NULL) | 341 | if (ctx != NULL) { |
| 341 | { | ||
| 342 | BN_CTX_end(ctx); | 342 | BN_CTX_end(ctx); |
| 343 | if (ctx_passed == NULL) | 343 | if (ctx_passed == NULL) |
| 344 | BN_CTX_free(ctx); | 344 | BN_CTX_free(ctx); |
| 345 | } | 345 | } |
| 346 | if (mont != NULL) | 346 | if (mont != NULL) |
| 347 | BN_MONT_CTX_free(mont); | 347 | BN_MONT_CTX_free(mont); |
| 348 | 348 | ||
| 349 | return(ret); | 349 | return (ret); |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, | 352 | static int |
| 353 | const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont) | 353 | witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, const BIGNUM *a1_odd, |
| 354 | { | 354 | int k, BN_CTX *ctx, BN_MONT_CTX *mont) |
| 355 | if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */ | 355 | { |
| 356 | if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) | ||
| 357 | /* w := w^a1_odd mod a */ | ||
| 356 | return -1; | 358 | return -1; |
| 357 | if (BN_is_one(w)) | 359 | if (BN_is_one(w)) |
| 358 | return 0; /* probably prime */ | 360 | return 0; /* probably prime */ |
| 359 | if (BN_cmp(w, a1) == 0) | 361 | if (BN_cmp(w, a1) == 0) |
| 360 | return 0; /* w == -1 (mod a), 'a' is probably prime */ | 362 | return 0; /* w == -1 (mod a), 'a' is probably prime */ |
| 361 | while (--k) | 363 | while (--k) { |
| 362 | { | ||
| 363 | if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ | 364 | if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ |
| 364 | return -1; | 365 | return -1; |
| 365 | if (BN_is_one(w)) | 366 | if (BN_is_one(w)) |
| @@ -367,128 +368,152 @@ static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, | |||
| 367 | * have been == -1 (mod 'a') */ | 368 | * have been == -1 (mod 'a') */ |
| 368 | if (BN_cmp(w, a1) == 0) | 369 | if (BN_cmp(w, a1) == 0) |
| 369 | return 0; /* w == -1 (mod a), 'a' is probably prime */ | 370 | return 0; /* w == -1 (mod a), 'a' is probably prime */ |
| 370 | } | 371 | } |
| 371 | /* If we get here, 'w' is the (a-1)/2-th power of the original 'w', | 372 | /* If we get here, 'w' is the (a-1)/2-th power of the original 'w', |
| 372 | * and it is neither -1 nor +1 -- so 'a' cannot be prime */ | 373 | * and it is neither -1 nor +1 -- so 'a' cannot be prime */ |
| 373 | bn_check_top(w); | 374 | bn_check_top(w); |
| 374 | return 1; | 375 | return 1; |
| 375 | } | 376 | } |
| 376 | 377 | ||
| 377 | static int probable_prime(BIGNUM *rnd, int bits) | 378 | static int |
| 378 | { | 379 | probable_prime(BIGNUM *rnd, int bits) |
| 380 | { | ||
| 379 | int i; | 381 | int i; |
| 380 | prime_t mods[NUMPRIMES]; | 382 | prime_t mods[NUMPRIMES]; |
| 381 | BN_ULONG delta,maxdelta; | 383 | BN_ULONG delta, maxdelta; |
| 382 | 384 | ||
| 383 | again: | 385 | again: |
| 384 | if (!BN_rand(rnd,bits,1,1)) return(0); | 386 | if (!BN_rand(rnd, bits, 1, 1)) |
| 387 | return (0); | ||
| 385 | /* we now have a random number 'rand' to test. */ | 388 | /* we now have a random number 'rand' to test. */ |
| 386 | for (i=1; i<NUMPRIMES; i++) | 389 | for (i = 1; i < NUMPRIMES; i++) |
| 387 | mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]); | 390 | mods[i] = (prime_t)BN_mod_word(rnd, (BN_ULONG)primes[i]); |
| 388 | maxdelta=BN_MASK2 - primes[NUMPRIMES-1]; | 391 | maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; |
| 389 | delta=0; | 392 | delta = 0; |
| 390 | loop: for (i=1; i<NUMPRIMES; i++) | 393 | loop: |
| 391 | { | 394 | for (i = 1; i < NUMPRIMES; i++) { |
| 392 | /* check that rnd is not a prime and also | 395 | /* check that rnd is not a prime and also |
| 393 | * that gcd(rnd-1,primes) == 1 (except for 2) */ | 396 | * that gcd(rnd-1,primes) == 1 (except for 2) */ |
| 394 | if (((mods[i]+delta)%primes[i]) <= 1) | 397 | if (((mods[i] + delta) % primes[i]) <= 1) { |
| 395 | { | 398 | delta += 2; |
| 396 | delta+=2; | 399 | if (delta > maxdelta) |
| 397 | if (delta > maxdelta) goto again; | 400 | goto again; |
| 398 | goto loop; | 401 | goto loop; |
| 399 | } | ||
| 400 | } | 402 | } |
| 401 | if (!BN_add_word(rnd,delta)) return(0); | ||
| 402 | bn_check_top(rnd); | ||
| 403 | return(1); | ||
| 404 | } | 403 | } |
| 405 | 404 | if (!BN_add_word(rnd, delta)) | |
| 406 | static int probable_prime_dh(BIGNUM *rnd, int bits, | 405 | return (0); |
| 407 | const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx) | 406 | bn_check_top(rnd); |
| 408 | { | 407 | return (1); |
| 409 | int i,ret=0; | 408 | } |
| 409 | |||
| 410 | static int | ||
| 411 | probable_prime_dh(BIGNUM *rnd, int bits, const BIGNUM *add, const BIGNUM *rem, | ||
| 412 | BN_CTX *ctx) | ||
| 413 | { | ||
| 414 | int i, ret = 0; | ||
| 410 | BIGNUM *t1; | 415 | BIGNUM *t1; |
| 411 | 416 | ||
| 412 | BN_CTX_start(ctx); | 417 | BN_CTX_start(ctx); |
| 413 | if ((t1 = BN_CTX_get(ctx)) == NULL) goto err; | 418 | if ((t1 = BN_CTX_get(ctx)) == NULL) |
| 419 | goto err; | ||
| 414 | 420 | ||
| 415 | if (!BN_rand(rnd,bits,0,1)) goto err; | 421 | if (!BN_rand(rnd, bits, 0, 1)) |
| 422 | goto err; | ||
| 416 | 423 | ||
| 417 | /* we need ((rnd-rem) % add) == 0 */ | 424 | /* we need ((rnd-rem) % add) == 0 */ |
| 418 | 425 | ||
| 419 | if (!BN_mod(t1,rnd,add,ctx)) goto err; | 426 | if (!BN_mod(t1, rnd, add, ctx)) |
| 420 | if (!BN_sub(rnd,rnd,t1)) goto err; | 427 | goto err; |
| 421 | if (rem == NULL) | 428 | if (!BN_sub(rnd, rnd, t1)) |
| 422 | { if (!BN_add_word(rnd,1)) goto err; } | 429 | goto err; |
| 423 | else | 430 | if (rem == NULL) { |
| 424 | { if (!BN_add(rnd,rnd,rem)) goto err; } | 431 | if (!BN_add_word(rnd, 1)) |
| 432 | goto err; | ||
| 433 | } else { | ||
| 434 | if (!BN_add(rnd, rnd, rem)) | ||
| 435 | goto err; | ||
| 436 | } | ||
| 425 | 437 | ||
| 426 | /* we now have a random number 'rand' to test. */ | 438 | /* we now have a random number 'rand' to test. */ |
| 427 | 439 | ||
| 428 | loop: for (i=1; i<NUMPRIMES; i++) | 440 | loop: |
| 429 | { | 441 | for (i = 1; i < NUMPRIMES; i++) { |
| 430 | /* check that rnd is a prime */ | 442 | /* check that rnd is a prime */ |
| 431 | if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1) | 443 | if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { |
| 432 | { | 444 | if (!BN_add(rnd, rnd, add)) |
| 433 | if (!BN_add(rnd,rnd,add)) goto err; | 445 | goto err; |
| 434 | goto loop; | 446 | goto loop; |
| 435 | } | ||
| 436 | } | 447 | } |
| 437 | ret=1; | 448 | } |
| 449 | ret = 1; | ||
| 450 | |||
| 438 | err: | 451 | err: |
| 439 | BN_CTX_end(ctx); | 452 | BN_CTX_end(ctx); |
| 440 | bn_check_top(rnd); | 453 | bn_check_top(rnd); |
| 441 | return(ret); | 454 | return (ret); |
| 442 | } | 455 | } |
| 443 | 456 | ||
| 444 | static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, | 457 | static int |
| 445 | const BIGNUM *rem, BN_CTX *ctx) | 458 | probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, |
| 446 | { | 459 | const BIGNUM *rem, BN_CTX *ctx) |
| 447 | int i,ret=0; | 460 | { |
| 448 | BIGNUM *t1,*qadd,*q; | 461 | int i, ret = 0; |
| 462 | BIGNUM *t1, *qadd, *q; | ||
| 449 | 463 | ||
| 450 | bits--; | 464 | bits--; |
| 451 | BN_CTX_start(ctx); | 465 | BN_CTX_start(ctx); |
| 452 | t1 = BN_CTX_get(ctx); | 466 | t1 = BN_CTX_get(ctx); |
| 453 | q = BN_CTX_get(ctx); | 467 | q = BN_CTX_get(ctx); |
| 454 | qadd = BN_CTX_get(ctx); | 468 | qadd = BN_CTX_get(ctx); |
| 455 | if (qadd == NULL) goto err; | 469 | if (qadd == NULL) |
| 470 | goto err; | ||
| 471 | |||
| 472 | if (!BN_rshift1(qadd, padd)) | ||
| 473 | goto err; | ||
| 456 | 474 | ||
| 457 | if (!BN_rshift1(qadd,padd)) goto err; | 475 | if (!BN_rand(q, bits, 0, 1)) |
| 458 | 476 | goto err; | |
| 459 | if (!BN_rand(q,bits,0,1)) goto err; | ||
| 460 | 477 | ||
| 461 | /* we need ((rnd-rem) % add) == 0 */ | 478 | /* we need ((rnd-rem) % add) == 0 */ |
| 462 | if (!BN_mod(t1,q,qadd,ctx)) goto err; | 479 | if (!BN_mod(t1, q,qadd, ctx)) |
| 463 | if (!BN_sub(q,q,t1)) goto err; | 480 | goto err; |
| 464 | if (rem == NULL) | 481 | if (!BN_sub(q, q, t1)) |
| 465 | { if (!BN_add_word(q,1)) goto err; } | 482 | goto err; |
| 466 | else | 483 | if (rem == NULL) { |
| 467 | { | 484 | if (!BN_add_word(q, 1)) |
| 468 | if (!BN_rshift1(t1,rem)) goto err; | 485 | goto err; |
| 469 | if (!BN_add(q,q,t1)) goto err; | 486 | } else { |
| 470 | } | 487 | if (!BN_rshift1(t1, rem)) |
| 488 | goto err; | ||
| 489 | if (!BN_add(q, q, t1)) | ||
| 490 | goto err; | ||
| 491 | } | ||
| 471 | 492 | ||
| 472 | /* we now have a random number 'rand' to test. */ | 493 | /* we now have a random number 'rand' to test. */ |
| 473 | if (!BN_lshift1(p,q)) goto err; | 494 | if (!BN_lshift1(p, q)) |
| 474 | if (!BN_add_word(p,1)) goto err; | 495 | goto err; |
| 496 | if (!BN_add_word(p, 1)) | ||
| 497 | goto err; | ||
| 475 | 498 | ||
| 476 | loop: for (i=1; i<NUMPRIMES; i++) | 499 | loop: |
| 477 | { | 500 | for (i = 1; i < NUMPRIMES; i++) { |
| 478 | /* check that p and q are prime */ | 501 | /* check that p and q are prime */ |
| 479 | /* check that for p and q | 502 | /* check that for p and q |
| 480 | * gcd(p-1,primes) == 1 (except for 2) */ | 503 | * gcd(p-1,primes) == 1 (except for 2) */ |
| 481 | if ( (BN_mod_word(p,(BN_ULONG)primes[i]) == 0) || | 504 | if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) || |
| 482 | (BN_mod_word(q,(BN_ULONG)primes[i]) == 0)) | 505 | (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) { |
| 483 | { | 506 | if (!BN_add(p, p, padd)) |
| 484 | if (!BN_add(p,p,padd)) goto err; | 507 | goto err; |
| 485 | if (!BN_add(q,q,qadd)) goto err; | 508 | if (!BN_add(q, q, qadd)) |
| 509 | goto err; | ||
| 486 | goto loop; | 510 | goto loop; |
| 487 | } | ||
| 488 | } | 511 | } |
| 489 | ret=1; | 512 | } |
| 513 | ret = 1; | ||
| 514 | |||
| 490 | err: | 515 | err: |
| 491 | BN_CTX_end(ctx); | 516 | BN_CTX_end(ctx); |
| 492 | bn_check_top(p); | 517 | bn_check_top(p); |
| 493 | return(ret); | 518 | return (ret); |
| 494 | } | 519 | } |
