Browse Source

Dixon: starting to play with multiple cores. GROW BABY

Michele Orrù 11 years ago
parent
commit
c2b285f52d
1 changed files with 84 additions and 15 deletions
  1. 84 15
      src/questions/dixon.c

+ 84 - 15
src/questions/dixon.c

@@ -15,11 +15,18 @@
  * while e, d . ed ≡ 1 (mod φ(N))  are respectively the public and the private
  * exponent.
  */
+#include "config.h"
+
 #include <assert.h>
+#include <string.h>
 #include <strings.h>
 
 #include <openssl/bn.h>
 
+#ifdef HAVE_OPENMPI
+#include <mpi.h>
+#endif
+
 #include "qa/questions/questions.h"
 #include "qa/questions/primes.h"
 #include "qa/questions/qarith.h"
@@ -27,6 +34,13 @@
 #include "qa/questions/qdixon.h"
 
 
+#ifdef HAVE_OPENMPI
+#define ENCLEN 2048
+
+MPI_Datatype MPI_BNPAIR;
+
+#endif
+
 matrix_t*
 identity_matrix_new(int d)
 {
@@ -136,6 +150,7 @@ discover_smooth(BIGNUM *y, BIGNUM *x, BIGNUM *n,
   } while (!dixon_smooth(y, ctx, v, len));
 }
 
+
 static RSA*
 dixon_question_ask_rsa(const RSA *rsa)
 {
@@ -164,6 +179,7 @@ dixon_question_ask_rsa(const RSA *rsa)
   matrix_t *h;
 
 
+#ifndef HAVE_OPENMPI
   /** STEP 1: initialization **/
   /* plus one for the sign */
   m = matrix_new(f, r);
@@ -172,21 +188,6 @@ dixon_question_ask_rsa(const RSA *rsa)
     R[i].x = BN_new();
     R[i].y = BN_new();
   }
-/* #else */
-/*   int procs, proc; */
-
-/*   MPI_Comm_rank(MPI_COMM_WORLD, &proc); */
-/*   MPI_Comm_size(MPI_COMM_WORLD, &procs); */
-
-/*   /\* root node fetches, child nodes discovery *\/ */
-/*   if (proc == 0) { */
-
-
-/*   if (proc != 0) { */
-/*     MPI_Finalize(); */
-/*     exit(); */
-/*   } */
-/* #endif */
 
   /** STEP 2 generating R */
   for (i=0; i < m->f; i++) {
@@ -194,6 +195,74 @@ dixon_question_ask_rsa(const RSA *rsa)
     discover_smooth(R[i].y, R[i].x, rsa->n,
                     ctx, m->M[i], m->r);
   }
+#else
+  int procs, proc;
+  int count;
+  MPI_Comm_rank(MPI_COMM_WORLD, &proc);
+  MPI_Comm_size(MPI_COMM_WORLD, &procs);
+  struct {
+    char x[ENCLEN];
+    char y[ENCLEN];
+    char v[r];
+  } to;
+
+  MPI_Aint offsets[3] = {0, ENCLEN, 2*ENCLEN};
+  MPI_Datatype types[3] = {MPI_CHAR, MPI_CHAR, MPI_CHAR};
+  int lengths[3] = {ENCLEN, ENCLEN, r};
+  MPI_Type_struct(3, lengths, offsets, types, &MPI_BNPAIR);
+  MPI_Type_commit(&MPI_BNPAIR);
+
+  count = procs > 1 ? f / (procs-1) : f;
+  printf("slave %d/%d at your service, sir.\n", proc, procs);
+  /* root node fetches, child nodes discovery */
+  if (proc == 0) {
+    /** STEP 1: initialization **/
+    m = matrix_new(f, r);
+    R = malloc(sizeof(struct bnpair) * f);
+
+    /** STEP 2 generating R */
+    for (i=0; i != f - count; i++) {
+      MPI_Recv(&to, 1, MPI_BNPAIR, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+      R[i].x = BN_new();
+      R[i].y = BN_new();
+      BN_hex2bn(&R[i].x, to.x);
+      BN_hex2bn(&R[i].y, to.y);
+      memcpy(m->M[i], to.v, r);
+
+      fprintf(stderr, "received: %s (%zu/%d)\n", to.x, i, f);
+    }
+
+    while (i++ < f) {
+      R[i].x = BN_new();
+      R[i].y = BN_new();
+      discover_smooth(R[i].y, R[i].x, rsa->n, ctx, m->M[i], r);
+    }
+  } else {
+    BIGNUM *x = BN_new(), *y = BN_new();
+    char *s;
+
+    while (count--) {
+      discover_smooth(y, x, rsa->n, ctx, to.v, r);
+      s = BN_bn2hex(x);
+      strcpy(to.x, s);
+      OPENSSL_free(s);
+      s = BN_bn2hex(y);
+      strcpy(to.y, s);
+      OPENSSL_free(s);
+
+      //      fprintf(stderr, "generated: %s (%d)", to.x, count);
+      MPI_Send(&to, 1, MPI_BNPAIR, 0, 0, MPI_COMM_WORLD);
+    }
+    fprintf(stderr, "worker %zu finished.", proc);
+    BN_free(x);
+    BN_free(y);
+  }
+
+  if (proc != 0) {
+    MPI_Finalize();
+    exit(EXIT_SUCCESS);
+  }
+#endif
 
   /** STEP 3: break & enter. */
   h = kernel(m);