infincia / bip39-rs

A Rust implementation of BIP-0039
Apache License 2.0
54 stars 61 forks source link

Add `from_key` #5

Closed dpc closed 4 years ago

dpc commented 7 years ago

I guess that solves my problem from #4

steveatinfincia commented 7 years ago

Hi :)

This (and the general idea in #4) would allow you to use arbitrary entropy sources, but that's about all, as the only thing you're supposed to use as cryptographic key material is the seed value, for a few reasons:

1. The seed value depends on the checksum of the original entropy

If you store the phrase & use the seed value as cryptographic key material, you get an early error if something happens to it, because the checksum will fail validation. And, due to the design of this crate, when that happens you can't end up with what looks like a usable Bip39 struct with a correct seed value in it, because the only available constructors will fail (the pub fields in the struct are an exception I need to fix).

You also get a chance to autocorrect the phrase itself using standard text algorithms, since there are only 2048 words in the wordlist, and of those there are only a few possibilities when one of the words in a phrase is wrong, you may even be able to autocorrect it just by reading it.

If you use/store the original entropy instead, and something happens to it that alters the value, you could end up passing it back in and still get a valid phrase, along with a new incorrect checksum, but when you go to use the entropy as a key somewhere it won't match anymore & you'll have no indication of why.

You may not even find out about it until you attempt to use the key to decrypt older data that was encrypted with the original key, and in the meantime newer data may have been encrypted with the new incorrect key, effectively a "fork" in the dataset.

2. Using the entropy directly will silently circumvent the passphrase design

When you create a mnemonic phrase, you have the option to include a separate passphrase that protects the seed value that will be generated from the mnemonic, so even if the mnemonic is revealed or even printed out on a piece of paper and left in the open, without the passphrase it's useless. That passphrase is only factored in when the mnemonic is turned in to a seed value, because it's the salt input to pbkdf2.

In addition the passphrase creates an opportunity for deniable mnemonic phrases, because the mnemonic will still be valid no matter what passphrase you use, but without the correct passphrase, the seed generated will be different.

Non-bitcoin use

With all that said, the original purpose of this crate was exactly what you mentioned in #4, that's what I use it for right now rather than anything Bitcoin related.

I use it by generating a phrase, storing and passing that around as the secret instead of a binary key, and then to use it for crypto purposes I generate the seed value and run it through sha256 to get a 256-bit key. You could also run it through something with a variable length hash output, like blake2, if you need some specific size.

It works very well in practice while still preserving some of the original protections bip39 has.

It would certainly be possible to add a get_original_entropy() -> Vec<u8> function though if you really want one, that can always be gotten back from a phrase.

I see no problem with allowing the original entropy to be passed in as well, probably as an Option<&[u8]> parameter, though it shouldn't be called a key as that will turn the API into a foot-gun for anyone using it according to the standard for HD wallets.

dpc commented 7 years ago

I am a bit distracted, but I've read your post, and I get what you're saying (I think), but I don't get the overall point. (I'm not trying to be dismissive)

So I guess I will ask a question here: is my PR OK? :)

Then I'll ask another in #4

steveatinfincia commented 6 years ago

Hi again @dpc, I apologize for not being able to get back to this until now :(

Do the changes in #7 work for you as far as getting the original entropy value back out?

dpc commented 6 years ago

Not a problem. I took a quick glance, and they might. I'll get back to it at some point! You might consider the case solved. :)