That ignores how people actually use passwords, if you have space to store that much entropy you're not actually far from just putting the whole key there. Typical passwords have much lower entropy than that and can be found with far fewer attempts than you'd expect from a uniform probability model.
True. But there's not much we can do in software to protect against bad passwords (other than running the obvious checks). You're storing the master key of an entire wallet. When generating one of these codes, it's probably a good idea to make a big deal out of password strength when asking for it
The obvious thing to use instead of scrypt is
cantena since script has data-dependent access patterns that leak key material in contexts where timing or power analysis are risks. Might be interesting to get a recommendation from colin percival.
I'll have a look at this, thanks!
Is there a reason base64 was not considered? These keys are all too long for the one click copying and reading applications where base58 is somewhat better for... base 64 is 10% smaller and with the right padding can result in a deterministic length. We decided to go with base64 for signmessage and I don't think we've regretted it.
This proposal started off as an extension of BIP 0038, which influenced most of the choices, like the initial scrypt 2
14/8/8 KDF and encryption scheme / encoding scheme.
Is there a reason that the salt is HASH256(Base58Check(RIPEMD160(SHA256(K)))) instead of the simpler HASH256(K)? This avoids a needless entropy bottleneck, additional computations, and an indirect network binding. If you want to bind the network you could just add a network string: HASH256("BITCOIN"+K)
I like the network dependency the way it is, because it's clearly defined how to handle alts. HASH256("BITCOIN"+K) means that I'd have to define it for all the alts as well, including testnet.
In addition to this, if you now look at the parts needed to verify if a password is correct, you need:
Selected KDF, AES, EC Public key derivation, SHA256+RIPEMD160, HASH256, bigint math to go to string (mod 58), another HASH256. All of this will significantly affect the effectiveness of a GPU based attack.
Is there a reason the date and KDF code is not included in the derivation of the salt e.g. salt = length + prefix + date + HASH256(length + prefix + date + K)[0..3]? (length is 16/32/64 or such). This alternative construction puts the prefix and date under your authentication code, and also increases the space of possible salt values. (the latter probably not very important, though OS password hardening seems to use 64 bit salts typically, but the former sounds useful and important)
Sounds good, I'll have a look at updating this.
Minor bug, your input seed can be 64 bytes, but the rest of the text assumes 32, e.g. the offsets for the whitening and aes key. This should be clarified.
I'm not sure what you're referring to:
Should the master generation procedure just reference BIP32?
I'll add an explicit mention of this.
Has there been no interest from wallet implementers in a possible span parameter: e.g. "this key has addresses assigned out to position X?"
There has, however, I'm still not entirely convinced I'd want to store a tree structure in the encoding. The point was to make this as compact as possible in order to create a paper wallet out of it.
I guess some form of notation could be added along side it to indicate the tree structure. But even then, I expect the tree structure to grow over time.