Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Thu, 26 Sep 2013 00:14:16 +0200
From: magnum <john.magnum@...hmail.com>
To: "john-dev@...ts.openwall.com" <john-dev@...ts.openwall.com>
Subject: External node distribution (call for help)

Solar, all,

The enclosed patch avoids the modulo operation in External mode when 
distributing work using node/fork/MPI. The speedup depends on several 
parameters but I've seen 10-15% for 8 nodes. This is the same scheme 
that I now use in mask mode.

The downside is that the patch (once you enable it by uncommenting the 
#define) changes the session file format for External mode so it will be 
incompatible with core.

However, there is a way to avoid changing the file format: We could read 
a "seq" number from file and convert it to "my_words" and "their_words". 
And vice versa when saving. That should be fairly easy (although I 
haven't really tried it yet) BUT what if the session was started on core 
John, and "seq" wrapped around it's 32 bits once or several times? And 
only then we resume it using the new code... and let's say our number of 
nodes is a prime... Would this mean our conversion might not be valid? 
Or can I totaly ignore such wrapping? I haven't figured that out yet %-)

magnum

From 9e028a7e1dc29c5e628236aaadfbcf838d00b4f5 Mon Sep 17 00:00:00 2001
From: magnum <john.magnum@...hmail.com>
Date: Wed, 25 Sep 2013 23:18:19 +0200
Subject: [PATCH] Faster node/fork/MPI distribution for External mode. This
 changes the session file format so it will be incompatible, so until we get
 that sorted out it's ifdef'ed out and we use the core scheme.

---
 src/external.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/src/external.c b/src/external.c
index b60287b..0ddf0a7 100644
--- a/src/external.c
+++ b/src/external.c
@@ -33,11 +33,21 @@ static char int_word[PLAINTEXT_BUFFER_SIZE];
 static char rec_word[PLAINTEXT_BUFFER_SIZE];
 
 /*
+ * Faster node distribution, avoiding modulo op.
+ * Session file will be incompatible.
+ */
+//#define NEW_DISTRIBUTION
+
+#ifdef NEW_DISTRIBUTION
+static int my_words, rec_my_words, their_words, rec_their_words;
+#else
+/*
  * A "sequence number" for distributing the candidate passwords across nodes.
  * It is OK if this number overflows once in a while, as long as this happens
  * in the same way for all nodes (must be same size unsigned integer type).
  */
 static unsigned int seq, rec_seq;
+#endif
 
 unsigned int ext_flags = 0;
 static char *ext_mode;
@@ -275,7 +285,12 @@ static void save_state(FILE *file)
 {
 	unsigned char *ptr;
 
+#ifdef NEW_DISTRIBUTION
+	fprintf(file, "%u\n", rec_my_words);
+	fprintf(file, "%u\n", rec_their_words);
+#else
 	fprintf(file, "%u\n", rec_seq);
+#endif
 	ptr = (unsigned char *)rec_word;
 	do {
 		fprintf(file, "%d\n", (int)*ptr);
@@ -289,8 +304,15 @@ static int restore_state(FILE *file)
 	c_int *external;
 	int count;
 
+#ifdef NEW_DISTRIBUTION
+	if (rec_version >= 4 && fscanf(file, "%u\n", &my_words) != 1)
+		return 1;
+	if (rec_version >= 4 && fscanf(file, "%u\n", &their_words) != 1)
+		return 1;
+#else
 	if (rec_version >= 4 && fscanf(file, "%u\n", &seq) != 1)
 		return 1;
+#endif
 
 	internal = (unsigned char *)int_word;
 	external = ext_word;
@@ -308,13 +330,22 @@ static int restore_state(FILE *file)
 static void fix_state(void)
 {
 	strcpy(rec_word, int_word);
+#ifdef NEW_DISTRIBUTION
+	rec_my_words = my_words;
+	rec_their_words = their_words;
+#else
 	rec_seq = seq;
+#endif
 }
 
 void do_external_crack(struct db_main *db)
 {
 	unsigned char *internal;
 	c_int *external;
+#ifdef NEW_DISTRIBUTION
+	my_words = options.node_max - options.node_min + 1;
+	their_words = options.node_min - 1;
+#endif
 
 	log_event("Proceeding with external mode: %.100s", ext_mode);
 
@@ -324,7 +355,9 @@ void do_external_crack(struct db_main *db)
 		*internal++ = *external++;
 	*internal = 0;
 
+#ifndef NEW_DISTRIBUTION
 	seq = 0;
+#endif
 
 	status_init(&get_progress, 0);
 
@@ -338,6 +371,19 @@ void do_external_crack(struct db_main *db)
 		if (!ext_word[0])
 			break;
 
+#ifdef NEW_DISTRIBUTION
+		if (options.node_count) {
+			if (their_words) {
+				their_words--;
+				continue;
+			}
+			if (--my_words == 0) {
+				my_words =
+					options.node_max - options.node_min + 1;
+				their_words = options.node_count - my_words;
+			}
+		}
+#else
 /*
  * The skipping of other nodes' candidate passwords can be optimized, such as
  * to avoid the modulo division like it's done for dist_words in wordlist.c.
@@ -348,6 +394,7 @@ void do_external_crack(struct db_main *db)
 			    for_node > options.node_max)
 				continue;
 		}
+#endif
 
 		if (f_filter) {
 			c_execute_fast(f_filter);
-- 
1.8.2.3

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ