Browse Source

A shitty, manually tested implementation of williams factorization method.

Michele Orrù 11 years ago
parent
commit
2af3a1892e
3 changed files with 53 additions and 2 deletions
  1. 1 0
      src/questions/allquestions.c
  2. 1 1
      src/questions/tests/Makefile.am
  3. 51 1
      src/questions/williams+1.c

+ 1 - 0
src/questions/allquestions.c

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

+ 1 - 1
src/questions/tests/Makefile.am

@@ -1,6 +1,6 @@
 
 # unittesting my ass
-LDADD=../libquestions.a -lssl -lcrypto
+LDADD = ../libquestions.a -lssl -lcrypto
 
 check_PROGRAMS = test_qarith test_qstrings test_wiener test_pollard test_dixon \
 	         test_williams test_primes

+ 51 - 1
src/questions/williams+1.c

@@ -9,6 +9,7 @@
 #include <openssl/rsa.h>
 #include <openssl/bn.h>
 
+#include "qa/questions/primes.h"
 #include "qa/questions/qarith.h"
 #include "qa/questions/questions.h"
 
@@ -60,15 +61,64 @@ void lucas(BIGNUM *v, BIGNUM *w,
   BN_free(vw);
 }
 
+/**
+ * \brief William's p+1 factorization.
+ *
+ */
 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;
+  BN_CTX *ctx = BN_CTX_new();
+
+  n = rsa->n;
+  BN_one(gcd);
+  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); */
+
+  for (primes_init(); primes_next(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());
+      /* gcd test */
+      BN_gcd(gcd, q, n, ctx);
+      if (BN_cmp(gcd, BN_value_one()) == 1) goto end;
+    }
+  }
+
+ end:
+  BN_free(p);
+
+  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);
+  }
   return ret;
 }
 
 qa_question_t WilliamsQuestion = {
   .name = "p+1",
-  .pretty_name = "William's p+1 factorization",
+  .pretty_name = "Williams' p+1 factorization",
   .ask_rsa = williams_question_ask_rsa
 };