Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user to enter additional custom entropy for seed generation (combine user-entropy with os.urandom() in XOR-like fashion) #523

Open
TheMastor opened this issue Jan 3, 2014 · 14 comments · May be fixed by #8839

Comments

@TheMastor
Copy link

With the NSA's shenanigans and also this fatal weakness in android there is cause to doubt the CSPRNG on many systems.

To satisfy this concern it would be important to allow users to input their entropy much like how TrueCrypt allows.

@ecdsa
Copy link
Member

ecdsa commented Jan 4, 2014

this does not require any modification of the software.
you can trivially do it yourself by "restoring" with your own seed.

@ecdsa ecdsa closed this as completed Jan 4, 2014
@TheMastor
Copy link
Author

And how would I go about doing that?

Typing gibberish into the generate wallet from seed window errors out and always results in one specific watching wallet being generated.

@wozz
Copy link
Contributor

wozz commented Jan 13, 2014

you have to choose 12 words from this list: https://github.com/spesmilo/electrum/blob/master/lib/mnemonic.py

you can use any method you want to choose the 12 words...

@TheMastor
Copy link
Author

What are you suggesting?
Print it off and throw darts at it?

Surely you could implement something more practical. I was quite impressed by the random pool thing in truecrypt and I'm pretty sure the bitcoin community would appreciate the effort it would take to implement something similar.

@TheMastor
Copy link
Author

Or instead of just ungracefully erroring out and creating a useless watching wallet when a malformed seed is entered you could just use that as entropy (after informing the user via a dialog box).

@ecdsa
Copy link
Member

ecdsa commented Jan 13, 2014

version 2.0 will no longer create wallets with malformed seeds.
However, it will probably not let users use any random string

@farzher
Copy link

farzher commented Jan 3, 2019

hello. i want to use my own entropy bits that i got by flipping coins or whatever instead of electrum's randomness. but how? i made a BIP39 seed but you don't accept it and i don't know how to generate a valid electrum seed.

@farzher
Copy link

farzher commented Feb 24, 2019

also you won't accept an xpub, ypub, or zpub for a multisig segwit wallet.
you want a Zpub. but that also seems to be a non standard electrum thing and i can't figure out how to generate one.

i just want to use my own entropy :(

@SomberNight
Copy link
Member

i made a BIP39 seed but you don't accept it and i don't know how to generate a valid electrum seed.

You can use a BIP39 seed if you tick the checkbox.

you want a Zpub. but that also seems to be a non standard electrum thing and i can't figure out how to generate one.

See https://github.com/spesmilo/electrum-docs/blob/master/xpub_version_bytes.rst
x/y/z/Y/Z version bytes come from Electrum. Others started using the same thing. The only reason Zpubs are not really used by other wallets is because no one else supports segwit multisig.
The reason why multisig uses different version bytes is explained at the above link.
You can use the convert_xkey CLI command to convert between different xpub version bytes.

@farzher
Copy link

farzher commented Feb 24, 2019

i have to use electrum mobile version for offline key generation. the BIP39 option dosen't exist there :(

but thank you, i think i finally understand the xpub insanity. convert_xkey isn't too useful, because i don't have an offline computer. but at least i know exactly what source code to read to make a javascript implementation or something that i could run on my phone

@chaserene
Copy link

please reopen this.

mixing in an external physical source of entropy (e.g. dice throws) would allow generating mnemonics that are verifiably immune to false randomness from a backdoored CPU. the current reality is that most of the CPUs in use are backdoored.

here's how a Monero wallet inspired by Electrum, Feather implemented this:

note that picking N words based on dice throws and manually "bruteforcing" the last word for a valid BIP39 mnemonic (what I suspect @farzher did, doable with at most 16 attempts for a mnemonic of length N=12) is not practically possible for Electrum-type mnemonics, due to the mnemonic hash prefix requirement: https://electrum.readthedocs.io/en/latest/seedphrase.html#version-number

@SomberNight
Copy link
Member

allow generating mnemonics that are verifiably immune to false randomness from a backdoored CPU

What do you mean by "verifiably"?
If the code naively mixes in custom entropy, you won't be able to tell whether the provided entropy was really used or the backdoored CPU discarded it.
Or is your threat model simply that randomness generated by the CPU is weak, but otherwise you trust the CPU to execute code as-is? And by verifiably immune you just mean that you can inspect the source code to see that what you provide as custom entropy is used in a sane way?

@chaserene
Copy link

I mean the two below:

randomness generated by the CPU is weak, but otherwise you trust the CPU to execute code as-is? And by verifiably immune you just mean that you can inspect the source code to see that what you provide as custom entropy is used in a sane way?

@SomberNight
Copy link
Member

Ok, I think it would be perfectly reasonable to allow that.

Unlike the option that existed in the past, which allowed the user to mix in their own entropy and then also provided a way that allowed the user to probabilistically check that the custom entropy was really used, it would be simpler and I think easier to write and validate code that just mixes in the provided entropy in a XOR-like fashion. (past option: #1574, #1964, #2070)

@SomberNight SomberNight reopened this Jan 22, 2024
@SomberNight SomberNight changed the title Enter custom entropy Allow user to enter additional custom entropy for seed generation (combine user-entropy with os.urandom() in XOR-like fashion) Jan 22, 2024
SomberNight added a commit to SomberNight/electrum that referenced this issue Jan 22, 2024
This is useful for the following threat-model:
> The randomness generated by the CPU/OS is assumed weak, but otherwise the user trusts the CPU/OS to execute code as-is.
> The user can inspect the source code to see what they provide as custom entropy is used in a sane way.

As the extra entropy is simply XOR-ed in, into the OS-generated randomness, it cannot be used as a footgun.

Note this significantly differs from the old custom_entropy option [0] that existed between version ~2.0 and 3.1.2 [1]:
- the old option *replaced* the OS-entropy with the user-provided entropy
  - e.g. if the user provided what looked like 64 bits of entropy, and by default we wanted to create a 132 bit seed,
    the resulting seed only used 132-64=68 bits of os.urandom()
  - hence think the old option was a footgun -- it required expert knowledge to use properly
  - instead, the new option mixes the user-provided entropy with os.urandom(), in a way that can never make the
    result have less entropy
- with the old option, the "custom_entropy" arg was an int, of which every "bit" was used as-is
  - for example, if the user wanted to provide some dice rolls,
    e.g. "6 3 5 2 6 6 2", and they passed the int "6352662" (base 10), they lost a lot of entropy by not using high decimal digits
    - i.e. the user was required to know *how* to convert their entropy to the expected format
    (e.g. dice rolls as base6, and then convert to base10)
  - instead, the new option takes an arbitrary string, which is then hashed internally, hence it is not possible to misuse the API
    - e.g. it is safe to provide dice rolls as a string, e.g. "6 3 5 2 6 6 2" or "6352662" or in any imaginable way
- the old option exposed a "check_seed" CLI command, that could be used to verify the user-provided entropy was used
  as part of the seed-generation. This is not possible with the new option.

related spesmilo#523 (comment)

[0]: https://github.com/spesmilo/electrum/blame/883f9be7d15cf1aba16895a0848f0d7af99f2ff3/lib/mnemonic.py#L149
[1]: 5e5134b
SomberNight added a commit to SomberNight/electrum that referenced this issue Jan 22, 2024
This is useful for the following threat-model:
> The randomness generated by the CPU/OS is assumed weak, but otherwise the user trusts the CPU/OS to execute code as-is.
> The user can inspect the source code to see what they provide as custom entropy is used in a sane way.

As the extra entropy is simply XOR-ed in, into the OS-generated randomness, it cannot be used as a footgun.

Note this significantly differs from the old custom_entropy option [0] that existed between version ~2.0 and 3.1.2 [1]:
- the old option *replaced* the OS-entropy with the user-provided entropy
  - e.g. if the user provided what looked like 64 bits of entropy, and by default we wanted to create a 132 bit seed,
    the resulting seed only used 132-64=68 bits of os.urandom()
  - hence I think the old option was a footgun -- it required expert knowledge to use properly
  - instead, the new option mixes the user-provided entropy with os.urandom(), in a way that can never make the
    result have less entropy
- with the old option, the "custom_entropy" arg was an int, of which every "bit" was used as-is
  - for example, if the user wanted to provide some dice rolls,
    e.g. "6 3 5 2 6 6 2", and they passed the int "6352662" (base 10), they lost a lot of entropy by not using high decimal digits
    - i.e. the user was required to know *how* to convert their entropy to the expected format
    (e.g. dice rolls as base6, and then convert to base10)
  - instead, the new option takes an arbitrary string, which is then hashed internally, hence it is not possible to misuse the API
    - e.g. it is safe to provide dice rolls as a string, e.g. "6 3 5 2 6 6 2" or "6352662" or in any imaginable way
- the old option exposed a "check_seed" CLI command, that could be used to verify the user-provided entropy was used
  as part of the seed-generation. This is not possible with the new option.

related spesmilo#523 (comment)

[0]: https://github.com/spesmilo/electrum/blame/883f9be7d15cf1aba16895a0848f0d7af99f2ff3/lib/mnemonic.py#L149
[1]: 5e5134b
SomberNight added a commit to SomberNight/electrum that referenced this issue Feb 21, 2024
This is useful for the following threat-model:
> The randomness generated by the CPU/OS is assumed weak, but otherwise the user trusts the CPU/OS to execute code as-is.
> The user can inspect the source code to see what they provide as custom entropy is used in a sane way.

As the extra entropy is simply XOR-ed in, into the OS-generated randomness, it cannot be used as a footgun.

Note this significantly differs from the old custom_entropy option [0] that existed between version ~2.0 and 3.1.2 [1]:
- the old option *replaced* the OS-entropy with the user-provided entropy
  - e.g. if the user provided what looked like 64 bits of entropy, and by default we wanted to create a 132 bit seed,
    the resulting seed only used 132-64=68 bits of os.urandom()
  - hence I think the old option was a footgun -- it required expert knowledge to use properly
  - instead, the new option mixes the user-provided entropy with os.urandom(), in a way that can never make the
    result have less entropy
- with the old option, the "custom_entropy" arg was an int, of which every "bit" was used as-is
  - for example, if the user wanted to provide some dice rolls,
    e.g. "6 3 5 2 6 6 2", and they passed the int "6352662" (base 10), they lost a lot of entropy by not using high decimal digits
    - i.e. the user was required to know *how* to convert their entropy to the expected format
    (e.g. dice rolls as base6, and then convert to base10)
  - instead, the new option takes an arbitrary string, which is then hashed internally, hence it is not possible to misuse the API
    - e.g. it is safe to provide dice rolls as a string, e.g. "6 3 5 2 6 6 2" or "6352662" or in any imaginable way
- the old option exposed a "check_seed" CLI command, that could be used to verify the user-provided entropy was used
  as part of the seed-generation. This is not possible with the new option.

related spesmilo#523 (comment)

[0]: https://github.com/spesmilo/electrum/blame/883f9be7d15cf1aba16895a0848f0d7af99f2ff3/lib/mnemonic.py#L149
[1]: 5e5134b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants