Browse Source

Pollard's ρ factorization algorithm: naïve impementation.

Correcting small error in pseudocode, too, and adding the older metadata
question into the TEST suite.
Michele Orrù 11 years ago
parent
commit
a2740f54dc

+ 4 - 2
book/pollardrho.tex

@@ -186,9 +186,11 @@ and respectively updating them via $x \gets f(x)$ and $y \gets f(f(y))$.
     \While{$g = 1$}
       \State $x \gets x^2 + 1 \pmod{N}$
       \State $y \gets y^4 + 2y^2 + 2 \pmod{N}$
-      \State $g \gets gcd(x, y)$
+      \State $g \gets gcd(|x - y|, N)$
     \EndWhile
-    \Return $g$
+    \If{$g = N$} \Return \strong{nil}
+    \Else \ \ \Return $g$
+    \EndIf
     \EndFunction
   \end{algorithmic}
 \end{algorithm}

+ 8 - 6
src/questions/Makefile.am

@@ -2,15 +2,17 @@ SUBDIRS = tests/
 
 # following the fucking manual, I am putting headers into the _SOURCES variable
 #  <https://www.gnu.org/software/automake/manual/html_node/Headers.html>
-EXAMPLE_QUESTION =   example.c
-WIENER_QUESTION =     wiener.c         include/qwiener.h
-POLLARD_QUESTION =   pollard.c         include/qpollard.h
-DIXON_QUESTION =       dixon.c
-FERMAT_QUESTION =     fermat.c
+EXAMPLE_QUESTION = example.c
+WIENER_QUESTION = wiener.c         include/qwiener.h
+POLLARD_QUESTION = pollard.c         include/qpollard.h
+DIXON_QUESTION = dixon.c
+FERMAT_QUESTION = fermat.c
 METADATA_QUESTION = metadata.c
+POLLARDRHO_QUESTION = pollardrho.c
 
 QUESTIONS = $(WIENER_QUESTION) $(POLLARD_QUESTION) $(DIXON_QUESTION) \
-	    $(FERMAT_QUESTION) $(EXAMPLE_QUESTION) $(METADATA_QUESTION)
+	    $(FERMAT_QUESTION) $(EXAMPLE_QUESTION) $(METADATA_QUESTION) \
+	    $(POLLARDRHO_QUESTION)
 
 QLIBSOURCES =         qarith.c         include/qarith.h \
 	            qstrings.c         include/qstrings.h \

+ 1 - 0
src/questions/allquestions.c

@@ -44,4 +44,5 @@ void select_all_questions(void)
   REGISTER_QUESTION(PollardQuestion);
   REGISTER_QUESTION(FermatQuestion);
   REGISTER_QUESTION(MetadataQuestion);
+  REGISTER_QUESTION(PollardRhoQuestion);
 }

+ 79 - 0
src/questions/pollardrho.c

@@ -0,0 +1,79 @@
+/**
+ * \file pollardrho.c
+ *
+ * \brief Pollard's ρ factorization method.
+ *
+ * This file contains two implementations of the pollard's ρ algorithm, used in
+ * order to attempt a factorization of N.
+ */
+
+#include <openssl/x509.h>
+
+#include <qa/questions/qarith.h>
+#include <qa/questions/questions.h>
+
+
+static RSA*
+pollardrho_question_ask_rsa(const RSA *rsa)
+{
+  RSA *ret = NULL;
+  BIGNUM
+    *x = NULL,
+    *y = NULL;
+  BIGNUM *n;
+  BIGNUM* two;
+  BIGNUM *tmp;
+  BIGNUM *gcd;
+  BN_CTX *ctx;
+
+  ctx = BN_CTX_new();
+  gcd = BN_new();
+  x = BN_new();
+  y = BN_new();
+  tmp = BN_new();
+  n = rsa->n;
+  two = BN_new();
+
+  /* initialization */
+  BN_one(gcd);
+  BN_pseudo_rand(x, 512, 0, 0);
+  BN_copy(y, x);
+  BN_one(two); BN_uiadd1(two);
+
+
+  while (!BN_cmp(gcd, BN_value_one())) {
+    /* x ← x² + 1 (mod N) */
+    BN_mod_sqr(x, x, n, ctx);
+    BN_uiadd1(x);
+    /* y ← y⁴ + 2y² + 2 (mod N) */
+    BN_mod_sqr(tmp, y, n, ctx);
+    BN_mod_sqr(y, tmp, n, ctx);
+    BN_lshift1(tmp, tmp);
+    BN_mod_add(y, y, tmp, n, ctx);
+    BN_mod_add(y, y, two, n, ctx);
+    /* gcd(|x-y|, N) */
+    BN_mod_sub(tmp, x, y, n, ctx);
+    BN_gcd(gcd, tmp, n, ctx);
+  }
+
+  if (BN_ucmp(gcd, n) != 0) {
+    ret = RSA_new();
+    ret->n = rsa->n;
+    ret->e = rsa->e;
+    ret->p = BN_dup(gcd);
+    ret->q = BN_new();
+    BN_div(ret->q, NULL, n, gcd, ctx);
+  }
+
+  BN_free(tmp);
+  BN_free(x);
+  BN_free(y);
+  BN_free(gcd);
+  return ret;
+}
+
+qa_question_t PollardRhoQuestion = {
+  .name = "pollardrho",
+  .pretty_name = "Pollard's rho factorization",
+  .ask_rsa = pollardrho_question_ask_rsa
+};

+ 4 - 2
src/questions/tests/Makefile.am

@@ -1,10 +1,12 @@
+
 # unittesting my ass
 LDADD=../libquestions.a -lssl -lcrypto
 
-check_PROGRAMS = test_qarith test_qstrings test_wiener test_pollard
-TESTS = $(check_PROGRAMS) test_fermat.test
+check_PROGRAMS = test_qarith test_qstrings test_wiener test_pollard test_dixon
+TESTS = $(check_PROGRAMS) test_fermat.test test_metadata.test test_pollardrho.test
 
 test_qstrings_SOURCES = test_qstrings.c
 test_qarith_SOURCES = test_qarith.c
 test_wiener_SOURCES = test_wiener.c
 test_pollard_SOURCES = test_pollard.c
+test_dixon_SOURCES = test_dixon.c

+ 10 - 0
src/questions/tests/pollardrho.crt

@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBWzCCAU+gAwIBAgIJAO0CRfiHioXRMAMGAQAwUTELMAkGA1UEBhMCSVQxDjAM
+BgNVBAgMBUl0YWx5MQ8wDQYDVQQHDAZUcmVudG8xITAfBgNVBAoMGEludGVybmV0
+IFdpZGdpdHMgUHR5IEx0ZDAeFw0xMzEyMDEwOTIyMjVaFw0xMzEyMzEwOTIyMjVa
+MFExCzAJBgNVBAYTAklUMQ4wDAYDVQQIDAVJdGFseTEPMA0GA1UEBwwGVHJlbnRv
+MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwIDANBgkqhkiG9w0B
+AQEFAAMPADAMAgQJkWRTAgQDnqaNo1AwTjAdBgNVHQ4EFgQUfCWIgzopf97JPQrs
+h2MlJhPvQy0wHwYDVR0jBBgwFoAUfCWIgzopf97JPQrsh2MlJhPvQy0wDAYDVR0T
+BAUwAwEB/zADBgEAAwEA
+-----END CERTIFICATE-----