Encryption of an existing BIP39 mnemonic without changing the seed

Encryption of an existing BIP39 mnemonic without changing the seed
2021-05-06 12:56 ` Peter D. Gray
                   ` (2 more replies)
  
From: Tobias Kaupat @ 2021-05-05 17:32 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 1922 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 2504 bytes --]

 permalink raw reply	[|nested]
2021-05-06 12:56 ` 
                   ` 
  
From: Tobias Kaupat @ 2021-05-05 17:32 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 1922 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 2504 bytes --]

 permalink raw reply	[|nested]
2021-05-05 17:32 [bitcoin-dev] Encryption of an existing BIP39 mnemonic without changing the seed Tobias Kaupat
  2021-05-06 12:56 ` Peter D. Gray

  2021-05-06 14:10   ` Tobias Kaupat
  2021-05-08 22:49 ` yanmaani
  
From: Erik Aronesty @ 2021-05-06 13:19 UTC (permalink / raw)
  To: Tobias Kaupat, Bitcoin Protocol Discussion

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


 permalink raw reply	[|nested]
2021-05-06 13:19 ` Erik Aronesty

  
From: Tobias Kaupat @ 2021-05-06 14:10 UTC (permalink / raw)
  To: Erik Aronesty;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3148 bytes --]

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:

> 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
>

[-- Attachment #2: Type: text/html, Size: 4618 bytes --]

 permalink raw reply	[|nested]
2021-05-05 17:32 [bitcoin-dev] Encryption of an existing BIP39 mnemonic without changing the seed Tobias Kaupat
  2021-05-06 12:56 ` Peter D. Gray
  2021-05-06 13:19 ` Erik Aronesty

  
From: yanmaani @ 2021-05-08 22:49 UTC ( / )
  To: Tobias Kaupat, Bitcoin Protocol Discussion

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:
> 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