Просмотр исходного кода

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

Michele Orrù лет назад: 12
Родитель
Сommit
673cf9c83f
4 измененных файлов с 1000074 добавлено и 1000102 удалено
  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

Разница между файлами не показана из-за своего большого размера
+ 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;
 }
 }