OT: that reminds me of something I've wondered about. I've always assumed that a serious password cracker trying a dictionary attack or trying a list of known common passwords would also try assorted simple transformations on them that people who think they are clever might try, like using sha on the memorized password and using the output of that as the password the site sees.

But how about more complicated transforms? For example, suppose someone did this in their shell to get the password (or private key, or whatever):

X=common_word.four_digit_number
S=$(echo -n $X | shasum)
for i in {1..501}
do
X=$(echo -n $X.$S | shasum)
done
echo $X

How do you estimate the entropy of something like that? At first it might seem it is just the entropy from the choice of common_word and four_digit_number, which is presumably fairly low. But that code is simple enough and short enough that I can delete it as soon as I recover the final $X, and retype it from memory the next time I need it.

In effect, isn't the secret that has to be guessed here both common_work.four_digit_number AND the code? And so doesn't the choice of code contribute to the entropy?

If so, what's the entropy of the program above? Let's say the bad guy knows that I've got some kind of memorized program that can take text input and transform it to text output, and it's small enough that I'm willing to type it in whenever I need it. That still leaves a huge number of possible algorithms.

Back in the days before password managers were common, I played around with something like this. I had a PGP encrypted file containing my password list. My PGP password was a long random string that I had memorized, and did not have written down anywhere. I wanted to have some kind of recovery procedure in case I forgot that password.

An encrypted file with my PGP password, encrypted with some other password, is the obvious approach, but then we are right back where we started with having to deal with that other password. It occurred to me that I'm less likely to forget an algorithm than a long random string, so if the second password was the result of an algorithm, I could memorize the algorithm and generate the password as needed.

Here's the algorithm I used:

1. Make a 100 x 100 array of all zeros.

2. Imagining this array represents a bitmapped 100x100 pixel display black and white display, draw in the lower left corner the string "tzs!" using a specific bitmapped font.

3. Run 108 generations of Conways's Life cellular automaton on the 100 x 100 array, with left to right and top to bottom wrapping.

3. Form a string of 10000 characters by scanning the array row by row, adding a "0" or "1" to the string depending on the state of the current array cell.

4. MD5 (this was a long time ago) that string, and print the result in hex. That hex string is the password for the PGP encrypted file containing my PGP password for my encrypted password list.

I never actually put that into production, but every few months I would sit down and implement that algorithm in C and run it, see that I got the right password, and then delete the code again. I had no trouble remembering it, even with only such sparse usage.