Is it possible to map a pass-phrase directly to a Bitcoin private key by using its SHA256 hash? I remember reading somewhere that not all 256 bit values are valid ECDSA private keys. If so, how can I make sure that the resulting hash is valid, or is there some other canonical way of mapping a pass-phrase to a private key?
1 Answer
While the question isn't an exact duplicate, the answer essentially is, so I'm going to quote this answer by Pieter Wuille:
As is normal when doing Elliptic Curve encryption, a private key is simply a random number. In the case of secp256k1, the elliptic curve used by Bitcoin, it has to be a number between 1 and 115792089210356248762697446949407573529996955224135760342422259061068512044368 (or in hexadecimal, between 1 and FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551.
This private key is converted to a public key by performing an EC point multiplication with the curve's base point. The result is an (x,y) coordinate pair, which constitutes the public key.
Finally, RIPEMD160(SHA256(pubkey)), where pubkey is a serialization of those coordinates, is computed, and encoded in base58, together with a checksum. This becomes the address.
So the short answer is yes, as long as the resulting hash is less than or equal to FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551 any SHA256 hash is an acceptable privkey.
As for a canonical method of mapping a passphrase to a privkey, I don't believe there is one - after all, this functionality isn't built into the Satoshi client (at least not yet) so there cannot, by definition, be a canonical method. The closest thing I can think of would be the mini private key format used by Casascius physical bitcoins, which could easily be used with a passphrase instead. Indeed Casascius' Bitcoin Address Utility is often the app of choice for those wishing to make "mental wallets" from memorized passphrases rather than random inputs.
-
1Thank you very much for your answer! AFAICS, Casascius doesn't seem to care at all about the fact that the result of SHA256 might not result in a valid private key. I understand now that this is a very rare corner case (about 2*10^-10), but still. Maybe hashing a second time in case the first result is larger would be a sensible behavior?– NoahCommented May 9, 2012 at 16:42
-
1@Noah If Casascius would not obtain a valid private key, how do you think he would be able to obtain the public key from it? Without a valid private key you can't have any Bitcoin Address to put the coins to, and as far as I know, every Physical Bitcoin clearly shows what address is stored in it. Commented May 9, 2012 at 17:57
-
1You're right of course, but since my question was specifically aiming at these corner cases, I think pointing out that they are simply not handled at all in the "app of choice" for brain wallets is justified. Besides, there might be automated implementations of such a mapping which cannot afford to just ignore these cases. Anyway, criticizing the Bitcoin Address Utility was in no way my intention, but obviously it does not cover the case I was asking for.– NoahCommented May 9, 2012 at 18:37
-
I can't say without looking over the code whether this corner case is handled at all, letalone how it is handled, but I would assume that in the extremely unlikely event of sha256(passcode) producing an invalid privkey the BouncyCastle crypto library would throw an error rather than generating an invalid keypair. Commented May 9, 2012 at 20:37
-
2The most common way it's handled is to reduce modulo the generator. I believe the OpenSSL libraries do this automatically. (The consensus among the security community is that reducing modulo the generator has no significant effect on the security properties and there's no benefit to using more sophisticated methods.) Commented May 9, 2012 at 20:39