| 
					
				 | 
			
			
				@@ -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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 |