Loading CHANGES +13 −2 Original line number Diff line number Diff line Loading @@ -4,6 +4,17 @@ Changes between 0.9.4 and 0.9.5 [xx XXX 1999] *) Make BN_generate_prime() return NULL on error if ret!=NULL. [Ulf Möller] *) Retain source code compatibility for BN_prime_checks macro. [Ulf Möller] *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to DH_CHECK_P_NOT_SAFE_PRIME. (Check if this is true? OpenPGP calls them "strong".) [Ulf Möller] *) Merge the functionality of "dh" and "gendh" programs into a new program "dhparam". The old programs are retained for now but will handle DH keys (instead of parameters) in future. Loading Loading @@ -57,8 +68,8 @@ *) Do more iterations of Rabin-Miller probable prime test (specifically, 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes instead of only 2 for all lengths; see BN_prime_checks definition in crypto/bn/bn.h for the complete table). This guarantees a instead of only 2 for all lengths; see BN_prime_checks_size definition in crypto/bn/bn_prime.c for the complete table). This guarantees a false-positive rate of at most 2^-80 (actually less because we are additionally doing trial division) for random input. [Bodo Moeller] Loading crypto/bn/bn.h +2 −17 Original line number Diff line number Diff line Loading @@ -283,23 +283,8 @@ typedef struct bn_recp_ctx_st #define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ r,a,&((mont)->RR),(mont),ctx) /* number of Miller-Rabin iterations for an error rate of less than 2^-80 * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; * original paper: Damgaard, Landrock, Pomerance: Average case error estimates * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ #define BN_prime_checks(b) ((b) >= 1300 ? 2 : \ (b) >= 850 ? 3 : \ (b) >= 650 ? 4 : \ (b) >= 550 ? 5 : \ (b) >= 450 ? 6 : \ (b) >= 400 ? 7 : \ (b) >= 350 ? 8 : \ (b) >= 300 ? 9 : \ (b) >= 250 ? 12 : \ (b) >= 200 ? 15 : \ (b) >= 150 ? 18 : \ /* b >= 100 */ 27) #define BN_prime_checks 0 /* default: select number of iterations based on the size of the number */ #define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) #define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) Loading crypto/bn/bn_prime.c +30 −5 Original line number Diff line number Diff line Loading @@ -62,12 +62,30 @@ #include "bn_lcl.h" #include <openssl/rand.h> /* The quick seive algorithm approach to weeding out primes is /* The quick sieve algorithm approach to weeding out primes is * Philip Zimmermann's, as implemented in PGP. I have had a read of * his comments and implemented my own version. */ #include "bn_prime.h" /* number of Miller-Rabin iterations for an error rate of less than 2^-80 * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; * original paper: Damgaard, Landrock, Pomerance: Average case error estimates * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ #define BN_prime_checks_size(b) ((b) >= 1300 ? 2 : \ (b) >= 850 ? 3 : \ (b) >= 650 ? 4 : \ (b) >= 550 ? 5 : \ (b) >= 450 ? 6 : \ (b) >= 400 ? 7 : \ (b) >= 350 ? 8 : \ (b) >= 300 ? 9 : \ (b) >= 250 ? 12 : \ (b) >= 200 ? 15 : \ (b) >= 150 ? 18 : \ /* b >= 100 */ 27) static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2, BN_MONT_CTX *mont); static int probable_prime(BIGNUM *rnd, int bits); Loading @@ -81,9 +99,10 @@ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add, { BIGNUM *rnd=NULL; BIGNUM t; int found=0; int i,j,c1=0; BN_CTX *ctx; int checks = BN_prime_checks(bits); int checks = BN_prime_checks_size(bits); ctx=BN_CTX_new(); if (ctx == NULL) goto err; Loading Loading @@ -145,12 +164,12 @@ loop: } } /* we have a prime :-) */ ret=rnd; found = 1; err: if ((ret == NULL) && (rnd != NULL)) BN_free(rnd); if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); BN_free(&t); if (ctx != NULL) BN_CTX_free(ctx); return(ret); return(found ? rnd : NULL); } int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), Loading @@ -161,6 +180,12 @@ int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), BN_CTX *ctx=NULL,*ctx2=NULL; BN_MONT_CTX *mont=NULL; if (checks == BN_prime_checks) { int bits = BN_num_bits(a); checks = BN_prime_checks_size(bits); } if (!BN_is_odd(a)) return(0); if (ctx_passed != NULL) Loading crypto/dh/dh.h +6 −2 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ struct dh_st BIGNUM *p; BIGNUM *g; int length; /* optional */ BIGNUM *pub_key; /* y */ BIGNUM *pub_key; /* g^x */ BIGNUM *priv_key; /* x */ int flags; Loading @@ -121,10 +121,14 @@ struct dh_st /* DH_check error codes */ #define DH_CHECK_P_NOT_PRIME 0x01 #define DH_CHECK_P_NOT_STRONG_PRIME 0x02 #define DH_CHECK_P_NOT_SAFE_PRIME 0x02 #define DH_UNABLE_TO_CHECK_GENERATOR 0x04 #define DH_NOT_SUITABLE_GENERATOR 0x08 /* primes p where (p-1)/2 is prime too are called "safe"; we define this for backward compatibility: */ #define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME #define DHparams_dup(x) (DH *)ASN1_dup((int (*)())i2d_DHparams, \ (char *(*)())d2i_DHparams,(char *)(x)) #define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ Loading crypto/dh/dh_check.c +8 −6 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ #include <openssl/bn.h> #include <openssl/dh.h> /* Check that p is a strong prime and /* Check that p is a safe prime and * if g is 2, 3 or 5, check that is is a suitable generator * where * for 2, p mod 24 == 11 Loading @@ -88,11 +88,13 @@ int DH_check(DH *dh, int *ret) l=BN_mod_word(dh->p,24); if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR; } /* else if (BN_is_word(dh->g,DH_GENERATOR_3)) #if 0 else if (BN_is_word(dh->g,DH_GENERATOR_3)) { l=BN_mod_word(dh->p,12); if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR; }*/ } #endif else if (BN_is_word(dh->g,DH_GENERATOR_5)) { l=BN_mod_word(dh->p,10); Loading @@ -102,13 +104,13 @@ int DH_check(DH *dh, int *ret) else *ret|=DH_UNABLE_TO_CHECK_GENERATOR; if (!BN_is_prime(dh->p,BN_prime_checks(BN_num_bits(dh->p)),NULL,ctx,NULL)) if (!BN_is_prime(dh->p,BN_prime_checks,NULL,ctx,NULL)) *ret|=DH_CHECK_P_NOT_PRIME; else { if (!BN_rshift1(q,dh->p)) goto err; if (!BN_is_prime(q,BN_prime_checks(BN_num_bits(q)),NULL,ctx,NULL)) *ret|=DH_CHECK_P_NOT_STRONG_PRIME; if (!BN_is_prime(q,BN_prime_checks,NULL,ctx,NULL)) *ret|=DH_CHECK_P_NOT_SAFE_PRIME; } ok=1; err: Loading Loading
CHANGES +13 −2 Original line number Diff line number Diff line Loading @@ -4,6 +4,17 @@ Changes between 0.9.4 and 0.9.5 [xx XXX 1999] *) Make BN_generate_prime() return NULL on error if ret!=NULL. [Ulf Möller] *) Retain source code compatibility for BN_prime_checks macro. [Ulf Möller] *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to DH_CHECK_P_NOT_SAFE_PRIME. (Check if this is true? OpenPGP calls them "strong".) [Ulf Möller] *) Merge the functionality of "dh" and "gendh" programs into a new program "dhparam". The old programs are retained for now but will handle DH keys (instead of parameters) in future. Loading Loading @@ -57,8 +68,8 @@ *) Do more iterations of Rabin-Miller probable prime test (specifically, 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes instead of only 2 for all lengths; see BN_prime_checks definition in crypto/bn/bn.h for the complete table). This guarantees a instead of only 2 for all lengths; see BN_prime_checks_size definition in crypto/bn/bn_prime.c for the complete table). This guarantees a false-positive rate of at most 2^-80 (actually less because we are additionally doing trial division) for random input. [Bodo Moeller] Loading
crypto/bn/bn.h +2 −17 Original line number Diff line number Diff line Loading @@ -283,23 +283,8 @@ typedef struct bn_recp_ctx_st #define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ r,a,&((mont)->RR),(mont),ctx) /* number of Miller-Rabin iterations for an error rate of less than 2^-80 * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; * original paper: Damgaard, Landrock, Pomerance: Average case error estimates * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ #define BN_prime_checks(b) ((b) >= 1300 ? 2 : \ (b) >= 850 ? 3 : \ (b) >= 650 ? 4 : \ (b) >= 550 ? 5 : \ (b) >= 450 ? 6 : \ (b) >= 400 ? 7 : \ (b) >= 350 ? 8 : \ (b) >= 300 ? 9 : \ (b) >= 250 ? 12 : \ (b) >= 200 ? 15 : \ (b) >= 150 ? 18 : \ /* b >= 100 */ 27) #define BN_prime_checks 0 /* default: select number of iterations based on the size of the number */ #define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) #define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) Loading
crypto/bn/bn_prime.c +30 −5 Original line number Diff line number Diff line Loading @@ -62,12 +62,30 @@ #include "bn_lcl.h" #include <openssl/rand.h> /* The quick seive algorithm approach to weeding out primes is /* The quick sieve algorithm approach to weeding out primes is * Philip Zimmermann's, as implemented in PGP. I have had a read of * his comments and implemented my own version. */ #include "bn_prime.h" /* number of Miller-Rabin iterations for an error rate of less than 2^-80 * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; * original paper: Damgaard, Landrock, Pomerance: Average case error estimates * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ #define BN_prime_checks_size(b) ((b) >= 1300 ? 2 : \ (b) >= 850 ? 3 : \ (b) >= 650 ? 4 : \ (b) >= 550 ? 5 : \ (b) >= 450 ? 6 : \ (b) >= 400 ? 7 : \ (b) >= 350 ? 8 : \ (b) >= 300 ? 9 : \ (b) >= 250 ? 12 : \ (b) >= 200 ? 15 : \ (b) >= 150 ? 18 : \ /* b >= 100 */ 27) static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2, BN_MONT_CTX *mont); static int probable_prime(BIGNUM *rnd, int bits); Loading @@ -81,9 +99,10 @@ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add, { BIGNUM *rnd=NULL; BIGNUM t; int found=0; int i,j,c1=0; BN_CTX *ctx; int checks = BN_prime_checks(bits); int checks = BN_prime_checks_size(bits); ctx=BN_CTX_new(); if (ctx == NULL) goto err; Loading Loading @@ -145,12 +164,12 @@ loop: } } /* we have a prime :-) */ ret=rnd; found = 1; err: if ((ret == NULL) && (rnd != NULL)) BN_free(rnd); if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); BN_free(&t); if (ctx != NULL) BN_CTX_free(ctx); return(ret); return(found ? rnd : NULL); } int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), Loading @@ -161,6 +180,12 @@ int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), BN_CTX *ctx=NULL,*ctx2=NULL; BN_MONT_CTX *mont=NULL; if (checks == BN_prime_checks) { int bits = BN_num_bits(a); checks = BN_prime_checks_size(bits); } if (!BN_is_odd(a)) return(0); if (ctx_passed != NULL) Loading
crypto/dh/dh.h +6 −2 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ struct dh_st BIGNUM *p; BIGNUM *g; int length; /* optional */ BIGNUM *pub_key; /* y */ BIGNUM *pub_key; /* g^x */ BIGNUM *priv_key; /* x */ int flags; Loading @@ -121,10 +121,14 @@ struct dh_st /* DH_check error codes */ #define DH_CHECK_P_NOT_PRIME 0x01 #define DH_CHECK_P_NOT_STRONG_PRIME 0x02 #define DH_CHECK_P_NOT_SAFE_PRIME 0x02 #define DH_UNABLE_TO_CHECK_GENERATOR 0x04 #define DH_NOT_SUITABLE_GENERATOR 0x08 /* primes p where (p-1)/2 is prime too are called "safe"; we define this for backward compatibility: */ #define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME #define DHparams_dup(x) (DH *)ASN1_dup((int (*)())i2d_DHparams, \ (char *(*)())d2i_DHparams,(char *)(x)) #define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ Loading
crypto/dh/dh_check.c +8 −6 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ #include <openssl/bn.h> #include <openssl/dh.h> /* Check that p is a strong prime and /* Check that p is a safe prime and * if g is 2, 3 or 5, check that is is a suitable generator * where * for 2, p mod 24 == 11 Loading @@ -88,11 +88,13 @@ int DH_check(DH *dh, int *ret) l=BN_mod_word(dh->p,24); if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR; } /* else if (BN_is_word(dh->g,DH_GENERATOR_3)) #if 0 else if (BN_is_word(dh->g,DH_GENERATOR_3)) { l=BN_mod_word(dh->p,12); if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR; }*/ } #endif else if (BN_is_word(dh->g,DH_GENERATOR_5)) { l=BN_mod_word(dh->p,10); Loading @@ -102,13 +104,13 @@ int DH_check(DH *dh, int *ret) else *ret|=DH_UNABLE_TO_CHECK_GENERATOR; if (!BN_is_prime(dh->p,BN_prime_checks(BN_num_bits(dh->p)),NULL,ctx,NULL)) if (!BN_is_prime(dh->p,BN_prime_checks,NULL,ctx,NULL)) *ret|=DH_CHECK_P_NOT_PRIME; else { if (!BN_rshift1(q,dh->p)) goto err; if (!BN_is_prime(q,BN_prime_checks(BN_num_bits(q)),NULL,ctx,NULL)) *ret|=DH_CHECK_P_NOT_STRONG_PRIME; if (!BN_is_prime(q,BN_prime_checks,NULL,ctx,NULL)) *ret|=DH_CHECK_P_NOT_SAFE_PRIME; } ok=1; err: Loading