int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { BIGNUM *t; int found=0; int i,j,c1=0; BN_CTX *ctx; int checks = BN_prime_checks_for_size(bits); if (bits < 2) { /* There are no prime numbers this small. */ BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); return 0; } else if (bits == 2 && safe) { /* The smallest safe prime (7) is three bits. */ BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL); return 0; } ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); t = BN_CTX_get(ctx); if(!t) goto err; loop: /* make a random number and set the top and bottom bits */ if (add == NULL) { if (!probable_prime(ret,bits)) goto err; } else { if (safe) { if (!probable_prime_dh_safe(ret,bits,add,rem,ctx)) goto err; } else { if (!bn_probable_prime_dh(ret,bits,add,rem,ctx)) goto err; } } /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ if(!BN_GENCB_call(cb, 0, c1++)) /* aborted */ goto err; if (!safe) { i=BN_is_prime_fasttest_ex(ret,checks,ctx,0,cb); if (i == -1) goto err; if (i == 0) goto loop; } else { /* for "safe prime" generation, * check that (p-1)/2 is prime. * Since a prime is odd, We just * need to divide by 2 */ if (!BN_rshift1(t,ret)) goto err; for (i=0; i<checks; i++) { j=BN_is_prime_fasttest_ex(ret,1,ctx,0,cb); if (j == -1) goto err; if (j == 0) goto loop; j=BN_is_prime_fasttest_ex(t,1,ctx,0,cb); if (j == -1) goto err; if (j == 0) goto loop; if(!BN_GENCB_call(cb, 2, c1-1)) goto err; /* We have a safe prime test pass */ } } /* we have a prime :-) */ found = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } bn_check_top(ret); return found; }
BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) { BIGNUM *rnd=NULL; BIGNUM t; int found=0; int i,j,c1=0; BN_CTX *ctx; int checks = BN_prime_checks_for_size(bits); ctx=BN_CTX_new(); if (ctx == NULL) goto err; if (ret == NULL) { if ((rnd=BN_new()) == NULL) goto err; } else rnd=ret; BN_init(&t); loop: /* make a random number and set the top and bottom bits */ if (add == NULL) { if (!probable_prime(rnd,bits)) goto err; } else { if (safe) { if (!probable_prime_dh_safe(rnd,bits,add,rem,ctx)) goto err; } else { if (!probable_prime_dh(rnd,bits,add,rem,ctx)) goto err; } } /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ if (callback != NULL) callback(0,c1++,cb_arg); if (!safe) { i=BN_is_prime_fasttest(rnd,checks,callback,ctx,cb_arg,0); if (i == -1) goto err; if (i == 0) goto loop; } else { /* for "safe prime" generation, * check that (p-1)/2 is prime. * Since a prime is odd, We just * need to divide by 2 */ if (!BN_rshift1(&t,rnd)) goto err; for (i=0; i<checks; i++) { j=BN_is_prime_fasttest(rnd,1,callback,ctx,cb_arg,0); if (j == -1) goto err; if (j == 0) goto loop; j=BN_is_prime_fasttest(&t,1,callback,ctx,cb_arg,0); if (j == -1) goto err; if (j == 0) goto loop; if (callback != NULL) callback(2,c1-1,cb_arg); /* We have a safe prime test pass */ } } /* we have a prime :-) */ found = 1; err: if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); BN_free(&t); if (ctx != NULL) BN_CTX_free(ctx); return(found ? rnd : NULL); }
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { BIGNUM *t; int found = 0; int i, j, c1 = 0; BN_CTX *ctx; int checks = BN_prime_checks_for_size(bits); if (bits < 2) { /* There are no prime numbers this small. */ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); return 0; } else if (bits == 2 && safe) { /* The smallest safe prime (7) is three bits. */ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); return 0; } ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); t = BN_CTX_get(ctx); if (!t) { goto err; } loop: /* make a random number and set the top and bottom bits */ if (add == NULL) { if (!probable_prime(ret, bits)) { goto err; } } else { if (safe) { if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) { goto err; } } else { if (!probable_prime_dh(ret, bits, add, rem, ctx)) { goto err; } } } if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) { /* aborted */ goto err; } if (!safe) { i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); if (i == -1) { goto err; } else if (i == 0) { goto loop; } } else { /* for "safe prime" generation, check that (p-1)/2 is prime. Since a prime * is odd, We just need to divide by 2 */ if (!BN_rshift1(t, ret)) { goto err; } for (i = 0; i < checks; i++) { j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, NULL); if (j == -1) { goto err; } else if (j == 0) { goto loop; } j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL); if (j == -1) { goto err; } else if (j == 0) { goto loop; } if (!BN_GENCB_call(cb, i, c1 - 1)) { goto err; } /* We have a safe prime test pass */ } } /* we have a prime :-) */ found = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return found; }