Explorar el Código

Implementing smooth() function.

Michele Orrù hace 11 años
padre
commit
c3f3a01ebc
Se han modificado 4 ficheros con 78 adiciones y 3 borrados
  1. 4 3
      book/dixon.tex
  2. 40 0
      src/questions/primes.c
  3. 32 0
      src/questions/tests/test_primes.c
  4. 2 0
      src/questions/williams+1.c

+ 4 - 3
book/dixon.tex

@@ -204,9 +204,10 @@ $e^{\sqrt{\ln N \ln \ln N}}$.
 
       \If{$x < 0$} $\alpha_0 \gets 1$ \EndIf
       \For{$i = 1 \strong{ to } |\factorBase|$}
-        \If{$\factorBase_i \nmid x$} \strong{continue} \EndIf
-        \State $x \gets x// \factorBase_i$
-        \State $\alpha_i \gets \alpha_i \xor 1$
+        \While{$\factorBase_i \mid x$}
+          \State $x \gets x// \factorBase_i$
+          \State $\alpha_i \gets \alpha_i \xor 1$
+        \EndWhile
       \EndFor
       \If{$x = 1$}
         \State \Return $v$

+ 40 - 0
src/questions/primes.c

@@ -4,6 +4,7 @@
  * \brief Fast access to a prime pool
  *
  */
+#include <stdint.h>
 
 #include <openssl/bn.h>
 
@@ -43,3 +44,42 @@ int primes_next(BIGNUM* p)
 
   return 1;
 }
+
+/**
+ * \brief Test for smoothness
+ *
+ * Attempt to divide `x` for each prime pᵢ s.t. i <= thresh, filling a binary
+ * vector with the powers mod 2.
+ *
+ * \return true if the prime is smooth w.r.t our prime pool, to the limits of
+ *   thresh, false otherwise
+ */
+int
+smooth(BIGNUM *x, BN_CTX *ctx, uint8_t* v, size_t thresh)
+{
+  BIGNUM *p = BN_new();
+  BIGNUM *rem = BN_new();
+  BIGNUM *dv = BN_new();
+  size_t i;
+
+  i = 0;
+  BN_zero(rem);
+  if (BN_cmp(x, BN_value_one()) < 1) return 0;
+
+  i = 0;
+  for (primes_init(); primes_next(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;
+      BN_copy(x, dv);
+
+      if (!BN_cmp(x, BN_value_one())) {
+        BN_free(p);
+        return 1;
+      }
+    }
+  }
+
+  BN_free(p);
+  return 0;
+}

+ 32 - 0
src/questions/tests/test_primes.c

@@ -1,4 +1,5 @@
 #include <assert.h>
+#include <stdint.h>
 
 #include <openssl/bn.h>
 
@@ -27,8 +28,39 @@ void test_primes(void)
   BN_free(check);
 }
 
+void
+test_smooth(void)
+{
+  BIGNUM *x = BN_new();
+  BN_CTX* ctx = BN_CTX_new();
+  static const int primes = 100;
+  uint8_t v[primes];
+
+
+  BN_one(x);
+  assert(!smooth(x, ctx, v, primes));
+
+  BN_dec2bn(&x, "2");
+  assert(smooth(x, ctx, v, primes));
+
+  BN_dec2bn(&x, "1573");
+  assert(smooth(x, ctx, v, primes));
+
+  BN_CTX_free(ctx);
+  BN_free(x);
+}
+
+
 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();
+
   return 0;
 }

+ 2 - 0
src/questions/williams+1.c

@@ -6,6 +6,8 @@
  * based on lucas sequences and Lehmer's theorem.
  *
  */
+#include <stdint.h>
+
 #include <openssl/rsa.h>
 #include <openssl/bn.h>