|
@@ -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);
|