Browse Source

$ cut -d',' -f 2 top-1m.csv > sites.txt

Michele Orrù 11 years ago
parent
commit
673cf9c83f
4 changed files with 1000074 additions and 1000102 deletions
  1. 6 4
      book/pollardrho.tex
  2. 1000000 1000000
      top-1m.csv
  3. 34 73
      src/questions/pollard.c
  4. 34 25
      src/questions/williams+1.c

+ 6 - 4
book/pollardrho.tex

@@ -204,8 +204,9 @@ and respectively updating them via $x \gets f(x)$ and $y \gets f(f(y))$.
 
 
 An immediate improvement of this algorithm would be to occasionally compute Euclid's
 An immediate improvement of this algorithm would be to occasionally compute Euclid's
 algorithm over the accumulated product to save some computation cycles, just as
 algorithm over the accumulated product to save some computation cycles, just as
-we saw in section~\ref{sec:pollard-1:implementing}. The next code fragment
-adopts this trick together with Brent's cycle-finding variant:
+we saw in section~\ref{sec:pollard-1:implementing}. The next code fragment - algorithm
+\ref{alg:pollardrho} - adopts this trick together with Brent's cycle-finding variant
+(\cite{pollard-brent}\S 7).
 
 
 \paragraph{Parallelism}
 \paragraph{Parallelism}
 Unfortunately, a parallel implementation of the $\rho$ algorithm would not
 Unfortunately, a parallel implementation of the $\rho$ algorithm would not
@@ -218,7 +219,7 @@ sequences in parallel would be no more than \bigO{\sqrt{m}}
 efficient (\cite{brent:parallel} \S 3).
 efficient (\cite{brent:parallel} \S 3).
 
 
 \begin{algorithm}
 \begin{algorithm}
-  \caption{Pollard-Brent's factorization (\cite{pollard-brent}\S 7)
+  \caption{Pollard-Brent's factorization
     \label{alg:pollardrho}}
     \label{alg:pollardrho}}
   \begin{algorithmic}[1]
   \begin{algorithmic}[1]
     \Function{rho}{\PKArg}
     \Function{rho}{\PKArg}
@@ -248,8 +249,9 @@ efficient (\cite{brent:parallel} \S 3).
       \EndWhile
       \EndWhile
       \State $r \gets r \ll 1$
       \State $r \gets r \ll 1$
     \EndWhile
     \EndWhile
-    \If{$g = N$} \Repeat
+    \If{$g = N$}
     \Comment too far; fall back to latest epoch
     \Comment too far; fall back to latest epoch
+    \Repeat
       \State $ys \gets ys^2 + 1 \pmod{N}$
       \State $ys \gets ys^2 + 1 \pmod{N}$
       \State $g \gets \gcd(N, \abs{x -ys})$
       \State $g \gets \gcd(N, \abs{x -ys})$
     \Until{$g > 1$} \EndIf
     \Until{$g > 1$} \EndIf

File diff suppressed because it is too large
+ 1000000 - 1000000
top-1m.csv


+ 34 - 73
src/questions/pollard.c

@@ -56,96 +56,57 @@ static RSA*
 pollard1_question_ask_rsa(const RSA* rsa)
 pollard1_question_ask_rsa(const RSA* rsa)
 {
 {
   RSA *ret = NULL;
   RSA *ret = NULL;
-  BIGNUM *p = BN_new();
-  BIGNUM *b = BN_new();
-  BIGNUM *q = BN_new();
-  BIGNUM *r = BN_new();
-  BIGNUM *gcd = BN_new();
+  BIGNUM
+    *p = BN_new(),
+    *b = BN_new(),
+    *b1 = BN_new(),
+    *q = BN_new(),
+    *r = BN_new(),
+    *g = BN_new();
   BN_CTX *ctx = BN_CTX_new();
   BN_CTX *ctx = BN_CTX_new();
   pit_t *it;
   pit_t *it;
-  long thresh = 1 << 20;
-  int e;
+  long j;
+  /* long back; */
+  int e, k, m = 100;
+
 
 
   BN_pseudo_rand_range(b, rsa->n);
   BN_pseudo_rand_range(b, rsa->n);
-  it=primes_init();
-  for (primes_next(it, p); thresh-- ; primes_next(it, p))  {
+  BN_one(g);
+  BN_one(q);
+  for (it = primes_init();
+       BN_is_one(g) && primes_next(it, p);
+       )  {
     e = BN_num_bits(rsa->n) / BN_num_bits(p);
     e = BN_num_bits(rsa->n) / BN_num_bits(p);
-    while (e-- && !ret) {
-      /* XXX. unsafe. */
-      BN_mod_exp(b, b, p, rsa->n, ctx);
-      BN_sub(q, b, BN_value_one());
-      BN_gcd(gcd, q, rsa->n, ctx);
-      if (BN_cmp(gcd, rsa->n) && BN_cmp(gcd, BN_value_one()))
-          ret = qa_RSA_recover(rsa, gcd, ctx);
+    for (k = 0; k < e && BN_is_one(g); k += m) {
+      /* back = primes_tell(it); */
+      for (j = (m > e) ? e : m; j; j--) {
+        BN_mod_exp(b, b, p, rsa->n, ctx);
+        BN_sub(b1, b, BN_value_one());
+        BN_mod_mul(q, q, b1, rsa->n, ctx);
+      }
+      BN_gcd(g, q, rsa->n, ctx);
     }
     }
   }
   }
 
 
+  /* replay latest epoch */
+  /* if (BN_cmp(g, rsa->n)) { */
+  /*   primes_seek(it, back); */
+
+  /* } */
+  if (BN_cmp(g, rsa->n) && !BN_is_one(g))
+      ret = qa_RSA_recover(rsa, g, ctx);
+
   BN_free(p);
   BN_free(p);
   BN_free(q);
   BN_free(q);
   BN_free(b);
   BN_free(b);
+  BN_free(b1);
   BN_free(r);
   BN_free(r);
-  BN_free(gcd);
+  BN_free(g);
   BN_CTX_free(ctx);
   BN_CTX_free(ctx);
 
 
   return ret;
   return ret;
 }
 }
 
 
-/**
- * \brief Pollard (p-1) factorization.
- *
- * Trivially the algorithm computes a = 2^(B!) (mod N), and then verifies that
- * gcd(a-1, N) is a nontrivial factor of N.
- *
- * According to Wikipedia™,
- * « By Dixon's theorem, the probability that the largest factor of such a
- * number is less than (p − 1)^ε is roughly ε^(−ε); so there is a probability of
- * about 3^(−3) = 1/27 that a B value of n^(1/6) will yield a factorisation.»
- *
- */
-static RSA*
-naive_pollard1_question_ask_rsa(const RSA *rsa)
-{
-  RSA *ret = NULL;
-  BIGNUM *a, *B, *a1;
-  BIGNUM *gcd, *rem;
-  BIGNUM *n;
-  BN_CTX *ctx;
-
-  n = rsa->n;
-  a = BN_new();
-  B = BN_new();
-  a1 = BN_new();
-  gcd = BN_new();
-  rem = BN_new();
-  ctx = BN_CTX_new();
-
-  /* take ⁸√N */
-  BN_sqrtmod(gcd, rem, n, NULL);
-  BN_sqrtmod(B, rem, gcd, NULL);
-  /* compute 2^(B!) */
-  for (BN_copy(a, two), BN_one(gcd);
-       !(BN_is_zero(B) || !BN_is_one(gcd) || BN_cmp(gcd, n)==0);
-       BN_usub(B, B, BN_value_one())) {
-
-    BN_mod_exp(a, a, B, n, ctx);
-    /* p ≟ gcd(a-1, N) */
-    BN_usub(a1, a, BN_value_one());
-    BN_gcd(gcd, a1, n, ctx);
-  }
-
-  /* Either p or q found :) */
-  if (!BN_is_zero(B))
-    ret = qa_RSA_recover(rsa, gcd, ctx);
-
-  BN_free(a);
-  BN_free(B);
-  BN_free(a1);
-  BN_free(gcd);
-  BN_free(rem);
-  BN_CTX_free(ctx);
-
-  return ret;
-}
 
 
 
 
 qa_question_t PollardQuestion = {
 qa_question_t PollardQuestion = {

+ 34 - 25
src/questions/williams+1.c

@@ -72,48 +72,57 @@ static RSA*
 williams_question_ask_rsa(const RSA* rsa)
 williams_question_ask_rsa(const RSA* rsa)
 {
 {
   RSA *ret = NULL;
   RSA *ret = NULL;
-  BIGNUM *p = BN_new();
-  BIGNUM *gcd = BN_new();
   BIGNUM
   BIGNUM
     *v = BN_new(),
     *v = BN_new(),
-    *w = BN_new();
-  BIGNUM *n;
-  BIGNUM *tau = BN_new();
-  BIGNUM *q = BN_new();
-  int e, i;
+    *v2 = BN_new(),
+    *w = BN_new(),
+    *n = rsa->n,
+    *tau = BN_new(),
+    *q = BN_new(),
+    *p = BN_new(),
+    *g = BN_new();
+  int e, k, j, m = 100;
   BN_CTX *ctx = BN_CTX_new();
   BN_CTX *ctx = BN_CTX_new();
   pit_t *pit;
   pit_t *pit;
 
 
-  n = rsa->n;
-  BN_one(gcd);
+  BN_one(g);
   BN_one(w); BN_uiadd1(w);
   BN_one(w); BN_uiadd1(w);
   BN_pseudo_rand(tau, 512, 0, 0);
   BN_pseudo_rand(tau, 512, 0, 0);
   BN_copy(v, tau);
   BN_copy(v, tau);
-  /* In the future, accumulated values: BN_one(q); */
+  BN_one(q);
 
 
-  for (pit = primes_init(); primes_next(pit, p); ) {
+  for (pit = primes_init();
+       BN_is_one(g) && primes_next(pit, p);
+       ) {
     e = BN_num_bits(n) / (BN_num_bits(p));
     e = BN_num_bits(n) / (BN_num_bits(p));
-    for (i=0; i < e; i++) {
-      lucas(v, w, p, tau, ctx);
-      /* XXX. unsafe. */
-      BN_mod(v, v, n, ctx);
-      BN_mod(w, w, n, ctx);
-      /* q = v - 2 */
-      BN_sub(q, v, BN_value_one());
-      BN_sub(q, q, BN_value_one());
+    for (k = 0; k < e && BN_is_one(g); k += m) {
+      for (j = (m > e) ? e : m; j; j--) {
+        lucas(v, w, p, tau, ctx);
+        /* XXX. unsafe. */
+        BN_mod(v, v, n, ctx);
+        BN_mod(w, w, n, ctx);
+        /* q = v - 2 */
+        BN_sub(v2, v, BN_value_one());
+        BN_sub(v2, v2, BN_value_one());
+        BN_mod_mul(q, q, v2, n, ctx);
+      }
       /* gcd test */
       /* gcd test */
-      BN_gcd(gcd, q, n, ctx);
-      if (BN_cmp(gcd, BN_value_one()) == 1) goto end;
+      BN_gcd(g, q, n, ctx);
     }
     }
   }
   }
 
 
- end:
+  if (BN_cmp(g, n))
+    ret = qa_RSA_recover(rsa, g, ctx);
+
+  BN_free(v);
+  BN_free(v2);
+  BN_free(w);
+  BN_free(tau);
   BN_free(p);
   BN_free(p);
+  BN_free(q);
+  BN_free(g);
   prime_iterator_free(pit);
   prime_iterator_free(pit);
 
 
-  if (BN_ucmp(gcd, n) != 0)
-    ret = qa_RSA_recover(rsa, gcd, ctx);
-
   return ret;
   return ret;
 }
 }