| 
															
																@@ -22,46 +22,52 @@ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  * compute <Vₕᵢ, Vₕᵢ₋₁> 
															 | 
															
															 | 
															
																  * compute <Vₕᵢ, Vₕᵢ₋₁> 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  */ 
															 | 
															
															 | 
															
																  */ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 void 
															 | 
															
															 | 
															
																 void 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-lucas(BIGNUM *v, BIGNUM *w, 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-      BIGNUM *h, BIGNUM *tau, 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+lucas(BIGNUM *v, BIGNUM *h, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BIGNUM *n, BN_CTX *ctx) 
															 | 
															
															 | 
															
																       BIGNUM *n, BN_CTX *ctx) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 { 
															 | 
															
															 | 
															
																 { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  BIGNUM *w; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BIGNUM *vv; 
															 | 
															
															 | 
															
																   BIGNUM *vv; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BIGNUM *vw; 
															 | 
															
															 | 
															
																   BIGNUM *vw; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BIGNUM *u; 
															 | 
															
															 | 
															
																   BIGNUM *u; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  BIGNUM *tau; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  int i; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  w = BN_dup(BN_value_two()); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  tau = BN_dup(v); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																   vv = BN_new(); 
															 | 
															
															 | 
															
																   vv = BN_new(); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   vw = BN_new(); 
															 | 
															
															 | 
															
																   vw = BN_new(); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   u = BN_new(); 
															 | 
															
															 | 
															
																   u = BN_new(); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  for (; 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-       !BN_is_one(h); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-       BN_rshift1(h, h)) { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-    if (BN_is_odd(h)) { 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  for (i = BN_num_bits(h); !BN_is_bit_set(h, i); i--); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  for (i--; i >= 0; i--) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+    if (BN_is_bit_set(h, i)) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_mod_sqr(vv, v, n, ctx); 
															 | 
															
															 | 
															
																       BN_mod_sqr(vv, v, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       /* v = τv² - vw - τ */ 
															 | 
															
															 | 
															
																       /* v = τv² - vw - τ */ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_mod_mul(u, tau, vv, n, ctx); 
															 | 
															
															 | 
															
																       BN_mod_mul(u, tau, vv, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_mod_mul(vw, v, w, n, ctx); 
															 | 
															
															 | 
															
																       BN_mod_mul(vw, v, w, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-      BN_sub(u, u, vw); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-      BN_sub(u, u, tau); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+      BN_mod_sub(u, u, vw, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+      BN_mod_sub(u, u, tau, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       /* w = w² - 2 */ 
															 | 
															
															 | 
															
																       /* w = w² - 2 */ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_sub(w, vv, BN_value_two()); 
															 | 
															
															 | 
															
																       BN_sub(w, vv, BN_value_two()); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     } else { 
															 | 
															
															 | 
															
																     } else { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-      BN_mod_sqr(vv, v, n, ctx); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+      BN_sqr(vv, v, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       /* v = v² - 2 */ 
															 | 
															
															 | 
															
																       /* v = v² - 2 */ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_sub(u, vv, BN_value_two()); 
															 | 
															
															 | 
															
																       BN_sub(u, vv, BN_value_two()); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       /* w = vw - τ */ 
															 | 
															
															 | 
															
																       /* w = vw - τ */ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-      BN_mod_mul(vw, v, w, n, ctx); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+      BN_mul(vw, v, w, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_sub(w, vw, tau); 
															 | 
															
															 | 
															
																       BN_sub(w, vw, tau); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     } 
															 | 
															
															 | 
															
																     } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     BN_copy(v, u); 
															 | 
															
															 | 
															
																     BN_copy(v, u); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   } 
															 | 
															
															 | 
															
																   } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  BN_free(w); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(u); 
															 | 
															
															 | 
															
																   BN_free(u); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(vv); 
															 | 
															
															 | 
															
																   BN_free(vv); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(vw); 
															 | 
															
															 | 
															
																   BN_free(vw); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 } 
															 | 
															
															 | 
															
																 } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 /** 
															 | 
															
															 | 
															
																 /** 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  * \brief William's p+1 factorization. 
															 | 
															
															 | 
															
																  * \brief William's p+1 factorization. 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  * 
															 | 
															
															 | 
															
																  * 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -73,41 +79,34 @@ williams_question_ask_rsa(const RSA* rsa) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BIGNUM 
															 | 
															
															 | 
															
																   BIGNUM 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     *v = BN_new(), 
															 | 
															
															 | 
															
																     *v = BN_new(), 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     *v2 = BN_new(), 
															 | 
															
															 | 
															
																     *v2 = BN_new(), 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-    *w = BN_new(), 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     *n = rsa->n, 
															 | 
															
															 | 
															
																     *n = rsa->n, 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-    *tau = BN_new(), 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     *q = BN_new(), 
															 | 
															
															 | 
															
																     *q = BN_new(), 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     *p = BN_new(), 
															 | 
															
															 | 
															
																     *p = BN_new(), 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     *g = BN_new(); 
															 | 
															
															 | 
															
																     *g = BN_new(); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  int e, k, j, m = 50; 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  int e, k, j, m = 100; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_CTX *ctx = BN_CTX_new(); 
															 | 
															
															 | 
															
																   BN_CTX *ctx = BN_CTX_new(); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   pit_t *pit; 
															 | 
															
															 | 
															
																   pit_t *pit; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   struct { 
															 | 
															
															 | 
															
																   struct { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     BIGNUM *p; 
															 | 
															
															 | 
															
																     BIGNUM *p; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     BIGNUM *v; 
															 | 
															
															 | 
															
																     BIGNUM *v; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-    BIGNUM *w; 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     int k; 
															 | 
															
															 | 
															
																     int k; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  } back = {BN_new(), BN_new(), BN_new(), 0}; 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  } back = {BN_new(), BN_new(), 0}; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  BN_one(w); BN_uiadd1(w); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  BN_pseudo_rand_range(tau, n); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  BN_copy(v, tau); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+  BN_pseudo_rand(v, BN_num_bits(n) / 2 + 2, 0, 0); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_copy(back.v, v); 
															 | 
															
															 | 
															
																   BN_copy(back.v, v); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  BN_copy(back.w, w); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_copy(back.p, BN_value_two()); 
															 | 
															
															 | 
															
																   BN_copy(back.p, BN_value_two()); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  back.k = 0; 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_one(g); 
															 | 
															
															 | 
															
																   BN_one(g); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_one(q); 
															 | 
															
															 | 
															
																   BN_one(q); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   for (pit = primes_init(); 
															 | 
															
															 | 
															
																   for (pit = primes_init(); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																        BN_is_one(g) && primes_next(pit, p); 
															 | 
															
															 | 
															
																        BN_is_one(g) && primes_next(pit, p); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																        ) { 
															 | 
															
															 | 
															
																        ) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-    e = BN_num_bits(n) / (BN_num_bits(p)) + 1; 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+    e = BN_num_bits(n) / BN_num_bits(p) + 1; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     for (k = 0; k < e && BN_is_one(g); k += m) { 
															 | 
															
															 | 
															
																     for (k = 0; k < e && BN_is_one(g); k += m) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       for (j = (m > e) ? e : m; j; j--) { 
															 | 
															
															 | 
															
																       for (j = (m > e) ? e : m; j; j--) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-        lucas(v, w, p, tau, n, ctx); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+        lucas(v, p, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																         /* q = v - 2 */ 
															 | 
															
															 | 
															
																         /* q = v - 2 */ 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-        BN_sub(v2, v, BN_value_two()); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+        BN_mod_sub(v2, v, BN_value_two(), n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																         BN_mod_mul(q, q, v2, n, ctx); 
															 | 
															
															 | 
															
																         BN_mod_mul(q, q, v2, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       } 
															 | 
															
															 | 
															
																       } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       /* gcd test */ 
															 | 
															
															 | 
															
																       /* gcd test */ 
															 | 
														
													
												
											
												
													
														
															 | 
															
																@@ -116,34 +115,31 @@ williams_question_ask_rsa(const RSA* rsa) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       if (BN_is_one(g)) { 
															 | 
															
															 | 
															
																       if (BN_is_one(g)) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																         BN_copy(back.p, p); 
															 | 
															
															 | 
															
																         BN_copy(back.p, p); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																         BN_copy(back.v, v); 
															 | 
															
															 | 
															
																         BN_copy(back.v, v); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-        BN_copy(back.w, w); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																         back.k = k; 
															 | 
															
															 | 
															
																         back.k = k; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       } 
															 | 
															
															 | 
															
																       } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     } 
															 | 
															
															 | 
															
																     } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   } 
															 | 
															
															 | 
															
																   } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																   if (!BN_cmp(g, n)) { 
															 | 
															
															 | 
															
																   if (!BN_cmp(g, n)) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+    printf("rollback!\n"); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     BN_copy(p, back.p); 
															 | 
															
															 | 
															
																     BN_copy(p, back.p); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     BN_one(g); 
															 | 
															
															 | 
															
																     BN_one(g); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     BN_copy(v, back.v); 
															 | 
															
															 | 
															
																     BN_copy(v, back.v); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-    BN_copy(w, back.w); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+    e = BN_num_bits(n) / BN_num_bits(p) + 5; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     for (k = back.k; k < e; k++) { 
															 | 
															
															 | 
															
																     for (k = back.k; k < e; k++) { 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-      lucas(v, w, p, tau, n, ctx); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+      lucas(v, p, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_sub(v2, v, BN_value_two()); 
															 | 
															
															 | 
															
																       BN_sub(v2, v, BN_value_two()); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																       BN_gcd(g, v2, n, ctx); 
															 | 
															
															 | 
															
																       BN_gcd(g, v2, n, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-      if (BN_is_one(g)) break; 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																 
															 | 
															
															 | 
															
																+      if (!BN_is_one(g)) break; 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     } 
															 | 
															
															 | 
															
																     } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   } 
															 | 
															
															 | 
															
																   } 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   if (!BN_is_one(g) && BN_cmp(g, n)) 
															 | 
															
															 | 
															
																   if (!BN_is_one(g) && BN_cmp(g, n)) 
															 | 
														
													
												
													
														
															| 
															 | 
															
																     ret = qa_RSA_recover(rsa, g, ctx); 
															 | 
															
															 | 
															
																     ret = qa_RSA_recover(rsa, g, ctx); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																  
															 | 
															
															 | 
															
																  
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(back.v); 
															 | 
															
															 | 
															
																   BN_free(back.v); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  BN_free(back.w); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(back.p); 
															 | 
															
															 | 
															
																   BN_free(back.p); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(v); 
															 | 
															
															 | 
															
																   BN_free(v); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(v2); 
															 | 
															
															 | 
															
																   BN_free(v2); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  BN_free(w); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																-  BN_free(tau); 
															 | 
															
															 | 
															
																 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(p); 
															 | 
															
															 | 
															
																   BN_free(p); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(q); 
															 | 
															
															 | 
															
																   BN_free(q); 
															 | 
														
													
												
													
														
															| 
															 | 
															
																   BN_free(g); 
															 | 
															
															 | 
															
																   BN_free(g); 
															 |