Add a method to generate a prime that is guaranteed not to be divisible by 3 or 5.
authorFelix Laurie von Massenbach <felix@erbridge.co.uk>
Mon, 26 May 2014 23:37:03 +0000 (00:37 +0100)
committerBen Laurie <ben@links.org>
Sun, 1 Jun 2014 14:31:26 +0000 (15:31 +0100)
Possibly some reduction in bias, but no speed gains.

apps/speed.c
crypto/bn/bn_lcl.h
crypto/bn/bn_prime.c

index 885784ee1d2318c5d47ce620aef527a82cf829ae..84d0829ad27f85e6b444d52864febe651843c5b6 100644 (file)
@@ -2041,6 +2041,29 @@ int MAIN(int argc, char **argv)
                BN_free(rnd);
                
                }
+       
+       if (prime_doit[D_PRIME_COPRIME])
+               {
+               BIGNUM *rnd = BN_new();
+               BIGNUM *add = BN_new();
+               BN_CTX *ctx = BN_CTX_new();
+               
+               BN_set_word(add, 2);
+               prime_print_message(prime_names[D_PRIME_COPRIME],
+                                                       prime_c[D_PRIME_COPRIME]);
+                       
+               Time_F(START);
+               for (count=0, run=1; COND(prime_c[D_PRIME_COPRIME]); count++)
+                       bn_probable_prime_dh_coprime(rnd, 1024, add, NULL, ctx);
+               
+               d=Time_F(STOP);
+               prime_print_result(D_PRIME_COPRIME, count, d);
+               
+               BN_CTX_free(ctx);
+               BN_free(add);
+               BN_free(rnd);
+               
+               }
 
        RAND_pseudo_bytes(buf,36);
 #ifndef OPENSSL_NO_RSA
index 40ef22b73f2243b15a80853a43503d26a8e50a94..fc54dcecdce2b3dbd6a491ce9c831f9c37b33200 100644 (file)
@@ -536,6 +536,8 @@ BIGNUM *int_bn_mod_inverse(BIGNUM *in,
 
 int bn_probable_prime_dh(BIGNUM *rnd, int bits,
        const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
+int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits,
+       const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
 
 #ifdef  __cplusplus
 }
index ac6ae30fa27451533aa017a58201cbc143f0e5c1..b303a48726772997a3d36ff2f6c3b79c9426d006 100644 (file)
 static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
        const BIGNUM *a1_odd, int k, BN_CTX *ctx, BN_MONT_CTX *mont);
 static int probable_prime(BIGNUM *rnd, int bits);
+static int probable_prime_dh(BIGNUM *rnd, const BIGNUM *add,
+       const BIGNUM *rem, BN_CTX *ctx, int first_prime_index);
 static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
        const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
 
+static int prime_offsets[8] = { 7, 11, 13, 17, 19, 23, 29, 31 };
+
 int BN_GENCB_call(BN_GENCB *cb, int a, int b)
        {
        /* No callback means continue */
@@ -363,40 +367,25 @@ err:
 int bn_probable_prime_dh(BIGNUM *rnd, int bits,
        const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
        {
-       int i,ret=0;
-       BIGNUM *t1;
+       if (!BN_rand(rnd, bits, 0, 1)) return(0);
 
-       BN_CTX_start(ctx);
-       if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
-
-       if (!BN_rand(rnd,bits,0,1)) goto err;
+       return(probable_prime_dh(rnd, add, rem, ctx, 1));
+       }
 
-       /* we need ((rnd-rem) % add) == 0 */
+int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits,
+       const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
+       {
+       BIGNUM *offset_index = BN_new();
 
-       if (!BN_mod(t1,rnd,add,ctx)) goto err;
-       if (!BN_sub(rnd,rnd,t1)) goto err;
-       if (rem == NULL)
-               { if (!BN_add_word(rnd,1)) goto err; }
-       else
-               { if (!BN_add(rnd,rnd,rem)) goto err; }
+       if (!BN_rand(rnd, bits, 0, 1)) return(0);
+       if (!BN_rand(offset_index, 3, -1, -1)) return(0);
 
-       /* we now have a random number 'rand' to test. */
+       BN_mul_word(rnd, 30);
+       BN_add_word(rnd, prime_offsets[BN_get_word(offset_index)]);
+       
+       BN_free(offset_index);
 
-loop:
-       for (i=1; i<NUMPRIMES; i++)
-               {
-               /* check that rnd is a prime */
-               if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1)
-                       {
-                       if (!BN_add(rnd,rnd,add)) goto err;
-                       goto loop;
-                       }
-               }
-       ret=1;
-err:
-       BN_CTX_end(ctx);
-       bn_check_top(rnd);
-       return(ret);
+       return(probable_prime_dh(rnd, add, rem, ctx, 3));
        }
 
 static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
@@ -491,6 +480,43 @@ loop:
        return(1);
        }
 
+static int probable_prime_dh(BIGNUM *rnd, const BIGNUM *add,
+       const BIGNUM *rem, BN_CTX *ctx, int first_prime_index)
+       {
+       int i,ret=0;
+       BIGNUM *t1;
+
+       BN_CTX_start(ctx);
+       if ((t1 = BN_CTX_get(ctx)) == NULL) goto err;
+
+       /* we need ((rnd-rem) % add) == 0 */
+
+       if (!BN_mod(t1,rnd,add,ctx)) goto err;
+       if (!BN_sub(rnd,rnd,t1)) goto err;
+       if (rem == NULL)
+               { if (!BN_add_word(rnd,1)) goto err; }
+       else
+               { if (!BN_add(rnd,rnd,rem)) goto err; }
+
+       /* we now have a random number 'rand' to test. */
+
+loop:
+       for (i=first_prime_index; i<NUMPRIMES; i++)
+               {
+               /* check that rnd is a prime */
+               if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1)
+                       {
+                       if (!BN_add(rnd,rnd,add)) goto err;
+                       goto loop;
+                       }
+               }
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       bn_check_top(rnd);
+       return(ret);
+       }
+
 static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
        const BIGNUM *rem, BN_CTX *ctx)
        {