0

I am using OpenSSL in C to search for a double safe prime P. That is, I'm looking for a prime P such that P=2p+1 and p=2p'+1, and p and p' are also prime. This search takes long, so I use OpenMP to do multithreading. Here is my code:

BIGNUM *p,*p_temp, *P, *P_temp, *temp1,*temp2;

BN_CTX *ctx;

ctx = BN_CTX_new(); 
p = BN_new();
p_temp = BN_new();
P = BN_new();
P_temp = BN_new();
temp1 = BN_new();
temp2 = BN_new();
int doublesafe;
int found;
int ID;
omp_set_num_threads(150);

#pragma omp parallel private(doublesafe,p_temp,P_temp,temp1,temp2,ID) shared(found,P,p,ctx)
{
    ID = omp_get_thread_num();
    printf("\n thread %d", ID);
    found=0;
    while(!found){
       BN_generate_prime_ex(p_temp,1536,1,NULL,NULL,NULL);
       BN_set_word(temp1,2);
       BN_mul(P_temp, temp1, p_temp, ctx);
       BN_add(P_temp, P_temp, BN_value_one());
       doublesafe = BN_is_prime_ex(P_temp,10,ctx, NULL);
       if(doublesafe){
         #pragma omp critical
         {
            if(!found){
            found = 1;
            BN_mul(P, P_temp, BN_value_one(),ctx);
            BN_mul(p, p_temp, BN_value_one(),ctx);
            printf("\n found P! %d", ID);
         }
      }
    }
  }
}
//the parallel block for finding prime p ends here

On running this, I get a segmentation fault:

>Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffb1ae8e700 (LWP 141701)]
0x00007ffff7a9b160 in BN_mod_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>(gdb) bt
>#0  0x00007ffff7a9b160 in BN_mod_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#1  0x00007ffff7a9d2dd in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#2  0x00007ffff7a9dd5c in BN_generate_prime_ex () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#3  0x0000000000401e0f in main._omp_fn.0 () at myprogram.c:265
>#4  0x00007ffff77f734a in ?? () from /usr/lib/x86_64-linux-gnu/libgomp.so.1
>#5  0x00007ffff75d9184 in start_thread (arg=0x7ffb1ae8e700) at pthread_create.c:312
>#6  0x00007ffff730603d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Any idea what the cause may be?

I updated the code following Zulan's suggestions. It worked once, but when I run it again it throws segmentation faults. Updated code:

   BIGNUM *p, *P;
   BN_CTX *ctx;
   ctx = BN_CTX_new();
   p = BN_new();
   P = BN_new();
   int found=0;
   omp_set_num_threads(150);
   #pragma omp parallel shared(found,P,p,ctx)
   {
      int ID = omp_get_thread_num();
      printf("\n thread %d", ID);
      int doublesafe=0;
      int local_found=0;
      BIGNUM *P_temp, *p_temp, *temp1;
      p_temp = BN_new();
      P_temp = BN_new();
      temp1 = BN_new();

      while(!local_found){
      BN_generate_prime_ex(p_temp,1536,1,NULL,NULL,NULL);
      BN_set_word(temp1,2);
      BN_mul(P_temp, temp1, p_temp, ctx);
      BN_add(P_temp, P_temp, BN_value_one());
      doublesafe = BN_is_prime_ex(P_temp,10,ctx, NULL);
      if(doublesafe){
      #pragma omp critical
      {
         if(!found){
         found = 1;
         BN_mul(P, P_temp, BN_value_one(),ctx);
         BN_mul(p, p_temp, BN_value_one(),ctx);
         printf("\n found p and P! %d", ID);
      }
      }
      }
    #pragma omp atomic read
    local_found = found;
    }
    }
    //the parallel block for finding safe prime p ends here

I get the following seg fault:

>Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffb6171b700 (LWP 143091)]
0x00007ffff7a9700c in BN_set_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>(gdb) bt
>#0  0x00007ffff7a9700c in BN_set_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#1  0x00007ffff7a97c45 in BN_CTX_get () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#2  0x00007ffff7a9d482 in BN_is_prime_fasttest_ex () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#3  0x0000000000401c36 in main._omp_fn.0 () at myprogram.c:257
>#4  0x00007ffff77f734a in ?? () from /usr/lib/x86_64-linux-gnu/libgomp.so.1
>#5  0x00007ffff75d9184 in start_thread (arg=0x7ffb6171b700) at pthread_create.c:312
>#6  0x00007ffff730603d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
>(gdb) 

Update:

I notice that calling functions like

BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb);

and

BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb);

in a parallel region throws segmentation faults most of the time (not always). When I comment these functions out, the program works fine.

Does anyone know how to deal with this?

I encounter segmentation faults even though I am following the suggestion from Tutorial on Using OpenSSL with pthreads about having two callback functions etc.

jww
  • 97,681
  • 90
  • 411
  • 885
MSJ
  • 97
  • 1
  • 10

1 Answers1

1

Private variables are not initialized within the parallel region! You must manually initialize them - better yet: Declare these locally in the parallel region itself, then they are implicitly private and it's easier to spot. Declare all variables as locally as possible and initialize them right at the declaration.

Meanwhile your found-loop is also wrong. You must not read found unprotected if it's written to by another thread. Even if that write happens to be protected. One solution is to use atomics, or you could use cancellation.

Zulan
  • 21,896
  • 6
  • 49
  • 109