Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240517205228.GA30958@openwall.com>
Date: Fri, 17 May 2024 22:52:28 +0200
From: Solar Designer <solar@...nwall.com>
To: john-users@...ts.openwall.com
Subject: Re: Markov phrases in john

On Wed, May 15, 2024 at 11:50:45PM +0200, Solar Designer wrote:
> On Wed, May 08, 2024 at 07:12:47AM -0400, Matt Weir wrote:
> > Now if you don't want to do conditional probability and do more 'individual
> > words frequency sorted' like mask mode, that is a lot easier to do. I
> > wouldn't be surprised if there is an external mode in JtR to do just this
> > already.
> 
> This wasn't convenient to do from an external mode because of its too
> limited interfacing to the rest of JtR.  We offered two kinds of modes:
> standalone generators and filters.  The former would have to have the
> wordlist embedded in the code, which is cumbersome.  The latter can
> produce at most one output word per input word (filtering or modifying
> it).  This changed when JimF introduced hybrid external modes in 2016 -
> that's two extra callbacks.  So a candidate passphrase generator as an
> external mode is more reasonably implementable now, but not done yet.

OK, done for word pairs now:

# Combine words coming from another cracking mode into pairs.  This gradually
# memorizes up to the initial 1 MB worth of words and uses them to prefix and
# suffix each current word.
# Known limitations: the progress indicator and ETA will be too optimistic
# (they assume linear progress through the input stream, but actual complexity
# is quadratic), --restore of an interrupted session will not work right (has
# no opportunity to re-memorize the other mode's skipped words).
# Example usage: --wordlist --external=combinator --rules-stack=phrase
[List.External:Combinator]
int separator;
int words[1000000], size;
int base[0x40], base_size, base_length, swap, p, q;

void init()
{
	separator = ' '; // Set to 0 for no separators
	size = 1000000;
	base_size = 0x40;
	if (req_maxlen && base_size > req_maxlen + 1)
		base_size = req_maxlen + 1;
	q = 0;
}

void new()
{
	swap = p = 0;

	base_length = -1;
	while (q < size && (words[q++] = word[++base_length]))
		continue;
	if (q < size && base_length < base_size)
		return;

	q -= base_length + 1;
	while (word[++base_length])
		continue;

	if (base_length >= base_size)
		word = 0;
}

void next()
{
	int i, j;

	if (swap) {
		i = -1;
		while (word[++i] = words[p++])
			continue;
		if (p >= q) {
			word = 0;
			return;
		}
		if (separator)
			word[i++] = separator;
		j = 0;
		while (word[i++] = base[j++])
			continue;
		return;
	}

	i = base_length;
	if (separator)
		word[i++] = separator;
	while (word[i++] = words[p++])
		continue;
	if (p >= q) {
		p = 0;
		swap++;
		i = -1;
		while (++i < base_length)
			base[i] = word[i];
		base[i] = 0;
	}
}

Alexander

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.