Browse Source

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

Michele Orrù 10 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
 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}
 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).
 
 \begin{algorithm}
-  \caption{Pollard-Brent's factorization (\cite{pollard-brent}\S 7)
+  \caption{Pollard-Brent's factorization
     \label{alg:pollardrho}}
   \begin{algorithmic}[1]
     \Function{rho}{\PKArg}
@@ -248,8 +249,9 @@ efficient (\cite{brent:parallel} \S 3).
       \EndWhile
       \State $r \gets r \ll 1$
     \EndWhile
-    \If{$g = N$} \Repeat
+    \If{$g = N$}
     \Comment too far; fall back to latest epoch
+    \Repeat
       \State $ys \gets ys^2 + 1 \pmod{N}$
       \State $g \gets \gcd(N, \abs{x -ys})$
     \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)
 {
   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();
   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);
-  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);
-    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(q);
   BN_free(b);
+  BN_free(b1);
   BN_free(r);
-  BN_free(gcd);
+  BN_free(g);
   BN_CTX_free(ctx);
 
   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 = {

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

@@ -72,48 +72,57 @@ static RSA*
 williams_question_ask_rsa(const RSA* rsa)
 {
   RSA *ret = NULL;
-  BIGNUM *p = BN_new();
-  BIGNUM *gcd = BN_new();
   BIGNUM
     *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();
   pit_t *pit;
 
-  n = rsa->n;
-  BN_one(gcd);
+  BN_one(g);
   BN_one(w); BN_uiadd1(w);
   BN_pseudo_rand(tau, 512, 0, 0);
   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));
-    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 */
-      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(q);
+  BN_free(g);
   prime_iterator_free(pit);
 
-  if (BN_ucmp(gcd, n) != 0)
-    ret = qa_RSA_recover(rsa, gcd, ctx);
-
   return ret;
 }