Ver código fonte

Studying efficient algorithms to populate Dixon's sets B, R.

Starting the development of Dixon's attack, and evaluating the efficieency of
some algorithms for the generation of the rᵢ.
Michele Orrù 11 anos atrás
pai
commit
373b8f23f1
1 arquivos alterados com 136 adições e 0 exclusões
  1. 136 0
      src/questions/dixon.c

+ 136 - 0
src/questions/dixon.c

@@ -0,0 +1,136 @@
+/**
+ * \file dixon.c
+ * \brief An implementation of Dixon's Attack using bignums.
+ *
+ * Given a non-empty set B of primes, called factor-base, and
+ * given a non-empty set of random numbers R, s.t. ∀ r ∈ R,  s ≡ r² (mod N) is B-smooth.
+ *
+ * Try to find
+ *   U ⊂ R | (Πᵤ rᵢ)² ≡ Π s (mod N) and by defining x ≝ Πᵤ rᵢ, y ≝ √(Π s)
+ *                 x² ≡ y² (mod N)
+ * Asserting that x ≢ y (mod N) we claim to have found the two non-trivial
+ * factors of N by computing gcd(x+y, N) and gcd(x-y, N).
+ *
+ * \note N = pq is assumed to be the public modulus,
+ * while e, d . ed ≡ 1 (mod φ(N))  are respectively the public and the private
+ * exponent.
+ */
+
+#include <stdlib.h>
+
+#include <openssl/bn.h>
+
+#include "questions.h"
+
+
+#define BPOOL_EXTEND_STEP   42
+#define BPOOL_STARTING_BITS  7
+#define RPOOL_EXTEND_STEP   42
+
+#define qa_rand rand
+
+/**
+ * \struct dixon_number_t
+ * \brief Auxiliary structure holding informations for R_pool.
+ */
+typedef struct dixon_number {
+  BIGNUM *r;   /**< the random number which have been chosen */
+  BIGNUM *s;   /**< s ≡ r² (mod N) */
+  BIGNUM **v;   /**< a cached vectors holding the exponents for the prime
+                 * factorization of s. */
+} dixon_number_t;
+
+/** Pool of random numbers, i.e. the set R. */
+dixon_number_t *R_pool = NULL;
+
+static size_t R_size = 0;
+
+/** Pool of prime numbers, i.e. B, the factor base. */
+static BIGNUM** B_pool = NULL;
+static size_t B_size = 0;
+
+
+static void extend_B_pool(int max_bits)
+{
+  size_t i, old_B_size;
+  int bits;
+
+  old_B_size = B_size;
+  B_size += BPOOL_EXTEND_STEP;
+
+  B_pool = realloc(B_pool, B_size * sizeof(BIGNUM*));
+
+  for (i=old_B_size; i!=B_size; i++) {
+    bits = 1 + qa_rand() % max_bits;
+    B_pool[i] = BN_generate_prime(NULL, bits, 0, NULL, NULL, NULL, NULL);
+  }
+  /* XXX. reallocate space for vectors in R_pool */
+}
+
+#define B_pool_free() free(B_pool)
+
+/**
+ * We have two possible choices here, for generating a valid random rumber
+ * satisfying Dixon's theorem requirements.
+ *
+ * Alg. 1 - 1. Start by generating a random r such that r > √N,
+ *          2. Calculate s ≡ r² (mod N)
+ *          3. Factorize s using B and see if that's B-smooth
+ * This algorithm shall have complexity O(k + N² + |B|lg N)
+ *
+ * Alg. 2 - 1. Generate the random exponents for s, {e₀, e₁, …, eₘ} where m = |B|
+ *          2. From the generated exponents, calculate s = p₀^e₀·p₁^e₁·…·pₘ^eₘ
+ *             knowing that s < N
+ *          3. Find an r = √(s + tN) , t ∈ {1..N-1}
+ * This algorithm shall have complexity O(k|B| + (N-1)lg N)
+ */
+static void extend_R_pool(BIGNUM* max_s)
+{
+  size_t i, j;
+  dixon_number_t *d;
+
+  i = R_size;
+  R_size += RPOOL_EXTEND_STEP;
+  R_pool = realloc(R_pool, sizeof(dixon_number_t));
+
+  for (; i!= R_size; i++) {
+    d = &R_pool[i];
+    d->s = BN_new();
+    /* generate exponents and calculate s */
+    while (BN_cmp(d->s, max_s) != -1) {
+      for (j=0; j != B_size; j++) {
+        ;
+      }
+    }
+  }
+
+}
+#define R_pool_free() free(R_pool)
+
+int dixon_question_setup(void)
+{
+  extend_B_pool(BPOOL_STARTING_BITS);
+  extend_R_pool();
+  return 0;
+}
+
+int dixon_question_teardown(void) {
+  B_pool_free();
+  R_pool_free();
+  return 0;
+}
+
+int dixon_question_test(X509* cert) { return 1; }
+
+int dixon_question_ask(X509* cert) {
+
+  return 0;
+}
+
+qa_question_t DixonQuestion = {
+  .name = "Dixon",
+  .setup = dixon_question_setup,
+  .teardown = dixon_question_teardown,
+  .test = dixon_question_test,
+  .ask = dixon_question_ask
+};