RE: making it harder to brute-force:
I have a couple of thoughts. First, if users choose passwords like 'abc123' or 'password' or any of the other top-1,000 passwords it doesn't matter if we're scrypt'ing; they're toast. I'd rather see work on either giving users feedback on how strong or weak their password is rather than adding a tiny-little-bit-more security by scrypting.
That said, changing the 'ekey' data so that ONLY the 256-bit private key is encrypted should increase security with very little extra code. Consider what you'd have to do to brute-force:
1000 x SHA256(password_text)
Now you have a 256-bit number. Is it the right private key? To check:
ECC multiply to get candidate public key
RIPEMD160(SHA256(candidate public key)), and check to see if it matches public key.
Anybody know how easy it is to GPU parallelize ECC multiplies? A quick google search gives me the impression that is an area of active research.
RE: pre-computing wallet keys:
?? wallet private keys are 256-bit random numbers. Am I misunderstanding you gmaxwell?
Here I mean precomputing the result of the 1000x SHA256 so that the marginal work is zero to try it on a new wallet. As the software is currently implemented I can precompute the SHA256x1000 of the top hundred thousand most likely passwords then reuse it over and over again on many wallets. I could also construct disk-space compact tables of _all_ sufficiently simple passwords as exist for other unsalted schemes.
The current system is unsalted for all intents and purposes (there is something passed in as "salt", but it's a constant, so it doesn't do anything useful except make the hash different from other 1000x SHA256 EVP_BytesToKey users). This is pretty bad, in all cases it gives the attacker a speedup proportional to the number of wallets they can steal on top of the speedup they get from using a GPU farm.
If you're not going to change schemes, at least encode the iteration count in the file and turn it up so that it takes, say, 100ms when the password is set. Or failing that, at least pick something that takes 100ms on your own machine. CPUs are doing roughly 4 million SHA-256 per core per second with optimized code. This could easily be made 100x harder without making it unacceptably slow even if nothing was done to address specialized hardware speedup.
Yes, of course the "top 1000" passwords are toast regardless. But hopefully giving good password advice, as Gavin suggests, prevents any of the top 1000 from being used. I'm more concerned about the "top 100000", which can be harder to eliminate with good password advice, and slowing down the attack by a factor of 100+ would make a material improvement to the effectiveness of these attacks.
Also, part of the purpose of wallet encryption is herd immunity: Causing people to not bother writing and distributing wallet scarfing worms because they don't expect it to pay off. So even weaker passwords get some increased protection from a scheme that makes harder passwords unreachably hard.
Encrypting only the high entropy part of the keying material sounds like a good idea idea to me. It sounds like a free boost to the complexity of checking a candidate password.