Encryption of an existing BIP39 mnemonic without changing the seed
5 messages, 5 to 8 May 2021. Started by Tobias Kaupat.
Tobias Kaupat (2), Peter (Coinkite Inc), Erik Aronesty, yanmaani
Hi all, I want to start a discussion about a use case I have and a possible solution. I have not found any satisfying solution to this use case yet.
*Use case:* An existing mnemonic (e.g. for a hardware wallet) should be saved on a paper backup in a password encrypted form. The encrypted form should be a mnemonic itself to keep all backup properties like error correction.
*Suggested solution:* 1) Take the existing mnemonic and extract the related entropy 2) Create a SHA526 hash (key) from a user defined password 3) Use the key as input for an AES CTR (empty IV) to encrypt the entropy 4) Derive a new mnemonic from the encrypted entropy to be stored on a paper backup
We can add some hints to the paper backp that the mnemonic is encrypted, or prefix it with "*" to make clear it's not usable without applying the password via the algorithm above.
To restore the original mnemonic, one must know the password and need to follow the process above again.
An example implementation in GoLang can be found here: https://github.com/Niondir/go-bip39/blob/master/encyrption_test.go
*Why not use the existing BIP-39 Passphrase?* When generating a mnemonic with passphrase, the entropy is derived from the passphrase. When you have an existing mnemonic without a passphrase, any attempt to add a passphrase will end up in a different seed and thus a different private key. What we actually need is to encrypt the entropy.
I'm open for your feedback. All encryption parameters are up to discussion and the whole proposal needs a security review. It's just the first draft.
*Existing solutions* One solution I found is "Seedshift" which can be found here: https://github.com/mifunetoshiro/Seedshift
But I consider it less secure and I would like to suggest a solution based on provably secure algorithms rather than a "rot23 derivation". Also using a date as password seems not very clever to me.
Kind regards Tobias
Hi Tobias.
The most recent release of Coldcard now offers "Seed XOR" to solve similar problems. It allows any numbers of standard BIP-39 compatible seed phrases to be bitwise XOR'ed together to make a new seed.
Coldcard can split an existing seed into 2, 3 or 4 new phrases, or you can take your existing seed phrase, and XOR-in a new seed phrase to arrive at a new random seed phrase (and wallet).
More details about this feature at: <https://seedxor.com>
Best part is XOR is simple enough that the split or combine operation can be worked out by hand on paper. (We even made a worksheet for this.) The checksums on each of the XOR parts protects the final result, and each "part" is a fully functional decoy wallet.
Hope that helps!
On Wed, May 05, 2021 at 07:32:05PM +0200, Tobias Kaupat wrote:
Quoted text (15 lines)
> Hi all, > I want to start a discussion about a use case I have and a possible > solution. I have not found any satisfying solution to this use case yet. > > *Use case:* > An existing mnemonic (e.g. for a hardware wallet) should be saved on a > paper backup in a password encrypted form. The encrypted form should be a > mnemonic itself to keep all backup properties like error correction. > > *Suggested solution:* > 1) Take the existing mnemonic and extract the related entropy > 2) Create a SHA526 hash (key) from a user defined password > 3) Use the key as input for an AES CTR (empty IV) to encrypt the entropy > 4) Derive a new mnemonic from the encrypted entropy to be stored on a paper > backup
...
Quoted text (10 lines)
> *Existing solutions* > One solution I found is "Seedshift" which can be found here: > https://github.com/mifunetoshiro/Seedshift > > But I consider it less secure and I would like to suggest a solution based > on provably secure algorithms rather than a "rot23 derivation". Also using > a date as password seems not very clever to me. > > Kind regards > Tobias
--- @DocHEX || Coinkite || PGP: A3A31BAD 5A2A5B10
i would stretch the password, with pbkdf2 or argon2 with like 30k rounds or something first, rather than "just hashing it". remember, it's pretty easy to validate these seeds - not like you lock someone out after 9 guesses!
On Wed, May 5, 2021 at 3:38 PM Tobias Kaupat via bitcoin-dev <bitcoin-dev@lists•linuxfoundation•org> wrote:
Quoted text (36 lines)
> > Hi all, > I want to start a discussion about a use case I have and a possible solution. I have not found any satisfying solution to this use case yet. > > Use case: > An existing mnemonic (e.g. for a hardware wallet) should be saved on a paper backup in a password encrypted form. The encrypted form should be a mnemonic itself to keep all backup properties like error correction. > > Suggested solution: > 1) Take the existing mnemonic and extract the related entropy > 2) Create a SHA526 hash (key) from a user defined password > 3) Use the key as input for an AES CTR (empty IV) to encrypt the entropy > 4) Derive a new mnemonic from the encrypted entropy to be stored on a paper backup > > We can add some hints to the paper backp that the mnemonic is encrypted, or prefix it with "*" to make clear it's not usable without applying the password via the algorithm above. > > To restore the original mnemonic, one must know the password and need to follow the process above again. > > An example implementation in GoLang can be found here: > https://github.com/Niondir/go-bip39/blob/master/encyrption_test.go > > Why not use the existing BIP-39 Passphrase? > When generating a mnemonic with passphrase, the entropy is derived from the passphrase. When you have an existing mnemonic without a passphrase, any attempt to add a passphrase will end up in a different seed and thus a different private key. What we actually need is to encrypt the entropy. > > I'm open for your feedback. All encryption parameters are up to discussion and the whole proposal needs a security review. It's just the first draft. > > Existing solutions > One solution I found is "Seedshift" which can be found here: https://github.com/mifunetoshiro/Seedshift > > But I consider it less secure and I would like to suggest a solution based on provably secure algorithms rather than a "rot23 derivation". Also using a date as password seems not very clever to me. > > Kind regards > Tobias > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists•linuxfoundation•org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Hello Erik, Thanks for your reply. After a little research I came to the same conclusion. PDKDF2 makes sense, since it is already used in BIP39. I will update my code.
Regarding SeedXOR: That's at least a similar solution, but than I have to store 2 phrases, I really like to keep one part in my head, which is only possible with a password. Plus for anyone who want to use two seeds my proposal also works - it just needs software to be applied.
Kind regards Tobias Kaupat
Erik Aronesty <erik@q32•com> schrieb am Do., 6. Mai 2021, 15:19:
Quoted text (59 lines)
> i would stretch the password, with pbkdf2 or argon2 with like 30k > rounds or something first, rather than "just hashing it". remember, > it's pretty easy to validate these seeds - not like you lock someone > out after 9 guesses! > > On Wed, May 5, 2021 at 3:38 PM Tobias Kaupat via bitcoin-dev > <bitcoin-dev@lists•linuxfoundation•org> wrote: > > > > Hi all, > > I want to start a discussion about a use case I have and a possible > solution. I have not found any satisfying solution to this use case yet. > > > > Use case: > > An existing mnemonic (e.g. for a hardware wallet) should be saved on a > paper backup in a password encrypted form. The encrypted form should be a > mnemonic itself to keep all backup properties like error correction. > > > > Suggested solution: > > 1) Take the existing mnemonic and extract the related entropy > > 2) Create a SHA526 hash (key) from a user defined password > > 3) Use the key as input for an AES CTR (empty IV) to encrypt the entropy > > 4) Derive a new mnemonic from the encrypted entropy to be stored on a > paper backup > > > > We can add some hints to the paper backp that the mnemonic is encrypted, > or prefix it with "*" to make clear it's not usable without applying the > password via the algorithm above. > > > > To restore the original mnemonic, one must know the password and need to > follow the process above again. > > > > An example implementation in GoLang can be found here: > > https://github.com/Niondir/go-bip39/blob/master/encyrption_test.go > > > > Why not use the existing BIP-39 Passphrase? > > When generating a mnemonic with passphrase, the entropy is derived from > the passphrase. When you have an existing mnemonic without a passphrase, > any attempt to add a passphrase will end up in a different seed and thus a > different private key. What we actually need is to encrypt the entropy. > > > > I'm open for your feedback. All encryption parameters are up to > discussion and the whole proposal needs a security review. It's just the > first draft. > > > > Existing solutions > > One solution I found is "Seedshift" which can be found here: > https://github.com/mifunetoshiro/Seedshift > > > > But I consider it less secure and I would like to suggest a solution > based on provably secure algorithms rather than a "rot23 derivation". Also > using a date as password seems not very clever to me. > > > > Kind regards > > Tobias > > _______________________________________________ > > bitcoin-dev mailing list > > bitcoin-dev@lists•linuxfoundation•org > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >
Why the existing mnemonic? If you've already dealt with unencrypted material carelessly, the genie is out of the bottle. And if you're OK with making a new one, why not just use BIP-39 passphrases to begin with?
If you must, it seems like a decent way to accomplish it, but raw SHA-256 is probably not the best choice. PBKDF2 like in the BIP-39 spec is tried and true, or something like scrypt. This would however change the storage format - you'd have to store a salt too, making your mnemonic bigger.
On 2021-05-05 17:32, Tobias Kaupat via bitcoin-dev wrote:
Quoted text (54 lines)
> Hi all, > I want to start a discussion about a use case I have and a possible > solution. I have not found any satisfying solution to this use case > yet. > > Use case: > An existing mnemonic (e.g. for a hardware wallet) should be saved on a > paper backup in a password encrypted form. The encrypted form should > be a mnemonic itself to keep all backup properties like error > correction. > > Suggested solution: > 1) Take the existing mnemonic and extract the related entropy > 2) Create a SHA526 hash (key) from a user defined password > 3) Use the key as input for an AES CTR (empty IV) to encrypt the > entropy > 4) Derive a new mnemonic from the encrypted entropy to be stored on a > paper backup > > We can add some hints to the paper backp that the mnemonic is > encrypted, or prefix it with "*" to make clear it's not usable without > applying the password via the algorithm above. > > To restore the original mnemonic, one must know the password and need > to follow the process above again. > > An example implementation in GoLang can be found here: > https://github.com/Niondir/go-bip39/blob/master/encyrption_test.go > > Why not use the existing BIP-39 Passphrase? > When generating a mnemonic with passphrase, the entropy is derived > from the passphrase. When you have an existing mnemonic without a > passphrase, any attempt to add a passphrase will end up in a different > seed and thus a different private key. What we actually need is to > encrypt the entropy. > > I'm open for your feedback. All encryption parameters are up to > discussion and the whole proposal needs a security review. It's just > the first draft. > > Existing solutions > One solution I found is "Seedshift" which can be found here: > https://github.com/mifunetoshiro/Seedshift > > But I consider it less secure and I would like to suggest a solution > based on provably secure algorithms rather than a "rot23 derivation". > Also using a date as password seems not very clever to me. > > Kind regards > Tobias > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists•linuxfoundation•org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev