Browse Source

Introducting prime iterators.

A trivial attempt to keep multiple iterators alive at the same item. In order to
do this, I am using different file descriptors for each one of those.
Michele Orrù 11 years ago
parent
commit
ef7404a270

+ 27 - 17
src/questions/primes.c

@@ -4,42 +4,47 @@
  * \brief Fast access to a prime pool
  *
  */
-#include <stdint.h>
+#include <strings.h>
 
 #include <openssl/bn.h>
 
+#include "qa/questions/primes.h"
+
 static const char *PRIME_POOL_FILE = "primes.txt";
-FILE *pool = NULL;
-char sp[10];
 
 /**
  * \brief Prime Poll initialization.
  *
- * \return 1 if the initialization suceeded
- *         0 if the initialization failed
- *         2 if the initialization had been already performed.
+ * \return a new prime iterator if the initialization succeeded, NULL
+ *         otherwise.
  */
-int primes_init(void)
+pit_t *primes_init(void)
 {
-  if (pool) return 2;
-
-  if (!(pool = fopen(PRIME_POOL_FILE, "r")))
-    return 0;
-  else
-    return 1;
+  return fopen(PRIME_POOL_FILE, "r");
 }
 
 
+/**
+ * \brief Prime Pool Iterator destructor.
+ *
+ */
+void prime_iterator_free(pit_t *it)
+{
+  /* XXX. check for errors. */
+  fclose(it);
+}
+
 /**
  * \brief Next prime in the pool
  *
  * \return true if there was another prime, false otherwise.
  *
  */
-int primes_next(BIGNUM* p)
+int primes_next(pit_t *it, BIGNUM* p)
 {
+  static char sp[10];
   /* overlow on me, yeah */
-  fscanf(pool, "%s", sp);
+  fscanf(it, "%s", sp);
   BN_dec2bn(&p, sp);
 
   return 1;
@@ -55,19 +60,23 @@ int primes_next(BIGNUM* p)
  *   thresh, false otherwise
  */
 int
-smooth(BIGNUM *x, BN_CTX *ctx, uint8_t* v, size_t thresh)
+smooth(BIGNUM *x, BN_CTX *ctx, char* v, size_t thresh)
 {
   BIGNUM *p = BN_new();
   BIGNUM *rem = BN_new();
   BIGNUM *dv = BN_new();
+  pit_t *it;
   size_t i;
 
   i = 0;
   BN_zero(rem);
+  bzero(v, thresh);
   if (BN_cmp(x, BN_value_one()) < 1) return 0;
 
   i = 0;
-  for (primes_init(); primes_next(p) && i < thresh; i++) {
+  for (it = primes_init();
+       primes_next(it, p) && i < thresh;
+       i++) {
     BN_div(dv, rem, x, p, ctx);
     for (v[i] = 0; BN_is_zero(rem); BN_div(dv, rem, x, p, ctx)) {
       v[i] = (v[i] + 1) % 2;
@@ -80,6 +89,7 @@ smooth(BIGNUM *x, BN_CTX *ctx, uint8_t* v, size_t thresh)
     }
   }
 
+  prime_iterator_free(it);
   BN_free(p);
   return 0;
 }

+ 2 - 0
src/questions/tests/test_dixon.c

@@ -3,6 +3,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <openssl/bn.h>
+
 #include "qa/questions/qdixon.h"
 #include "qa/questions/qstrings.h"
 

+ 31 - 12
src/questions/tests/test_primes.c

@@ -9,21 +9,23 @@ void test_primes(void)
 {
   BIGNUM *p = BN_new();
   BIGNUM *check = BN_new();
+  pit_t *it;
 
-  assert(primes_init());
+  assert((it = primes_init()));
 
   BN_dec2bn(&check, "2");
-  primes_next(p);
+  primes_next(it, p);
   assert(!BN_cmp(check, p));
 
   BN_dec2bn(&check, "3");
-  primes_next(p);
+  primes_next(it, p);
   assert(!BN_cmp(check, p));
 
   BN_dec2bn(&check, "5");
-  primes_next(p);
+  primes_next(it, p);
   assert(!BN_cmp(check, p));
 
+  prime_iterator_free(it);
   BN_free(p);
   BN_free(check);
 }
@@ -34,8 +36,7 @@ test_smooth(void)
   BIGNUM *x = BN_new();
   BN_CTX* ctx = BN_CTX_new();
   static const int primes = 100;
-  uint8_t v[primes];
-
+  char v[primes];
 
   BN_one(x);
   assert(!smooth(x, ctx, v, primes));
@@ -50,17 +51,35 @@ test_smooth(void)
   BN_free(x);
 }
 
+void
+test_iterator(void)
+{
+  BIGNUM *p1 = BN_new();
+  BIGNUM *p2 = BN_new();
+  pit_t *it1, *it2;
+
+  it1 = primes_init();
+  it2 = primes_init();
+  assert(it1 && it2);
+  primes_next(it1, p1);
+  primes_next(it2, p2);
+  assert(!BN_cmp(p1, p2));
+
+  primes_next(it1, p1);
+  primes_next(it1, p1);
+  primes_next(it2, p2);
+  assert(BN_cmp(p1, p2) > 0);
+
+  prime_iterator_free(it1);
+  prime_iterator_free(it2);
+}
+
 
 int main(int argc, char **argv)
 {
   test_primes();
-
-  /* XXX. shit we DO NEED an iterator object asap. */
-  extern FILE *pool;
-  fclose(pool);
-  pool = NULL;
-
   test_smooth();
+  test_iterator();
 
   return 0;
 }

+ 3 - 1
src/questions/williams+1.c

@@ -82,6 +82,7 @@ williams_question_ask_rsa(const RSA* rsa)
   BIGNUM *q = BN_new();
   int e, i;
   BN_CTX *ctx = BN_CTX_new();
+  pit_t *pit;
 
   n = rsa->n;
   BN_one(gcd);
@@ -90,7 +91,7 @@ williams_question_ask_rsa(const RSA* rsa)
   BN_copy(v, tau);
   /* In the future, accumulated values: BN_one(q); */
 
-  for (primes_init(); primes_next(p); ) {
+  for (pit = primes_init(); primes_next(pit, p); ) {
     e = BN_num_bits(n) / (BN_num_bits(p));
     for (i=0; i < e; i++) {
       lucas(v, w, p, tau, ctx);
@@ -108,6 +109,7 @@ williams_question_ask_rsa(const RSA* rsa)
 
  end:
   BN_free(p);
+  prime_iterator_free(pit);
 
   if (BN_ucmp(gcd, n) != 0) {
     ret = RSA_new();