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

Standard Writeable Mnemonic Seed Proposal #75

Closed
alexvandesande opened this issue Mar 9, 2016 · 40 comments
Closed

Standard Writeable Mnemonic Seed Proposal #75

alexvandesande opened this issue Mar 9, 2016 · 40 comments

Comments

@alexvandesande
Copy link

Having an easily portable, easily writeable and even memorisable seed* is an often requested issue and I think there would be benefit to have a cross implementation compatible standard, specially because there's a lot of space for pain if you implement it the wrong way. The end goal should not an "easy to memorize" but rather a "easy to write down/possible to memorize", since the value isn't so much on keeping the wallet 100% on your brain, but rather the extreme portability.

* Sometimes called a Brain wallet, but usually when referring to a human picking the random phrase, which is not the goal here

1. Ask for a Salt: Email address

It doesn't matter how hard is your password to guess, if you don't have a unique part of it, then an attacker could continuously generate a giant table of passwords, that would allow him to steal wallets that are yet to be created for any users. A salt doesn't need to be secret it just needs to be unique, if an attacker knows your salt they can try to guess your password but then they would be using all that hash power against one specific user, so the potential gains are limited.

An email address would be a perfect salt: it's instantly memorable by the user and is unique enough to add security. A client could also use the email to send a message with instructions, which allows a few interesting uses:

  • the user could make an email on the form of username+randomstring@gmail.com to add more uniqueness, but they could still search their inbox for it
  • it could be used as an invitation. You add someone emails address and the client will send them instructions on how to redeem the ether (of course the full seed would not be sent on the email, that would require the invitee to contact the inviter)
  • Users are used to the pattern email + password as a login on social networks, so while the way this works is different, they might feel more at ease

2. Random seed generator

The user should never pick his own random seed. Humans are terrible sources of randomness and that should be provided for them. The user could be presented with the following choices:

  1. The level of security they want. This could be presented as "safe to secure up to X amount" and should reflect on the size of the seed. All clients should provide a minimum maximum security that should be in trillions of trillions of possible seeds. Not all use cases need to have complete unbreakable encryption, for transfer of small amounts of pocket money, a password that would take thousands of dollars to break should be enough.
  2. The option to generate a new seed if they want. In a typical use case the user should not have to see more than 10 seeds before settling on one, so that this wouldn't decrease the entropy by much.
  3. The option of selecting between string generation scheme. The user should pick the one that feels more comfortable with his culture or input device. Some examples would be:
  • Word List. BIP39 has an excellent word dictionary of words in multiple languages. Those were picked up to be common words yet all of them can be unambiguously distinguished by just the first 4 letters.
  • Pseudo-words. Using syllables to generate pseudo-words can be as strong and easier to write down. For example these three alien words: "fakpug temvuw jorzul" have the entropy equivalence of 6 random words (from a 1024 word list). Another example: "uffu wojtij ewiome wu cajreg hajkut mar" is the equivalent of 12 seed words.
  • Symbols. If you have a pen input or have knowledge of chinese, then an ideogram is a great seed. There probably a use case for an emoji based seed generation.
  • Security questions. An interesting way to transmit a brain wallet securely to someone would be to generate a series of questions that the user needs to answer on the other side. The questions could be sent via email and the hash would include both the question and answer. This would be much less secure but could be useful in a case where the user simply wants to send a small amount of ethers just so that the user can execute a contract
  • A mix of the above?

3. Multiple hashing rounds and multiple account outputs

Instead of a single round of hashing, the seed should be generated by hashing the password multiple times. The number should be standard, based on something that would take an average laptop/mobile phone in 2016 an average of 1 second or so. This means that even with a specialised computer and taking moose's law in consideration, testing millions of passwords would still take a considerable time and cost for the attacker.

Another layer of security can be added by generating not one, but an indeterminate amount of accounts for the user, by repeating the same hash amount. The user could be presented with 10-12 accounts to choose from whenever they generated a brain wallet, and could even choose them by picking a memorable and aesthetic pleasing icon. The attacker would then have to choose between testing a thousand passwords for 1 account or testing 10 accounts for 100 passwords. Since the user can be using the 12th account, there's a chance the attacker would have his salt, try his password combination and still not find his private key.

Interface Mockup

The following is just a mockup on how a brain wallet could look like in the Wallet. Once a user selects an ethereum address field, a pop up would appear asking them to select a field from their contact list, recently used addresses or a new brain wallet. Once selecting the brain wallet, the user would fill the email, passphrase and then they could select from multiple addresses. Each address would take about a second to appear, and the user could select any page they want.

Creating a new brain wallet:

screen shot 2016-03-09 at 1 23 53 pm

#### Loading an existing brain wallet

screen shot 2016-03-09 at 12 42 00 pm

@alexvandesande
Copy link
Author

@axic also wrote a similar page almost at the same time: #76

@pascalvanhecke
Copy link

Suggestion: omit the term "brain wallet" altogether because it has a bad rep, and can only stir controversy. This is not a brainwallet, as the main intent is not to memorize it, and the words are not chosen by users.

Electrum calls it "seed", "wallet seed" or "seed phrase", BIP 39 calls it mnemonic code or mnemonic sentence.

I think "writeable seed" is still even better since it indicates the main purpose is low-tech cold storage?

@alexvandesande alexvandesande changed the title ERC: Standard Brain Wallet (writeable seed) Proposal ERC: Standard Writeable Mnemonic Seed Proposal Mar 9, 2016
@alexvandesande
Copy link
Author

@pascalvanhecke You are right, I renamed the EIP

@axic
Copy link
Member

axic commented Mar 9, 2016

I do like the idea of providing multiple accounts at the end and distinguish them with identicons, however I do think that part has to be considered in more depth.

Remembering all this might be too much in certain cases:

  • username/email
  • generated seed (passphrase) (are spaces sensitive or ignored?)
  • and the actual account chosen

You display 12 accounts right now and offer a possibility to generate more. Depending on the KDF that might be too much effort in terms of CPU in a browser.

In terms of a user: has to be displayed in the exact same layout with the exact identicons everywhere.

I do not think the account number (4 mixed-case letters!) would be remembered by anyone. Extra care should be taken when generating those addresses to not have very similar identicons (and perhaps take color disabilities into consideration).

@rfikki
Copy link

rfikki commented Mar 9, 2016

Suggestion, please change this text to more accurately portray what it is you are trying to state: "The end goal should not an "easy to memorize" but rather a "easy to write down/possible to memorize", ".

I kind of understand what you are trying to say, but for some it could be confusing.

Also kind of silly to tell the user how much ether to store at what security level. Is it not better to just give a security level rating:

Warning not very secure
Medium Security
Very Secure

@taoteh1221
Copy link

Since you are doing this in a GUI in your example (which looks great BTW), a "Print" dialogue prompt with an Icon / Text Button to print the seed phrase would be a good idea to display after generating the brain wallet. I could see typos writing it down by hand occurring. I personally agree with @rfikki that it is a good idea to be backed up in places other than the brain (like an encrypted / password-protected zip or rar file). 😄

@alexvandesande
Copy link
Author

@axic The account should not be something you need to memorize actually. I think the idea should more like something @taoteh1221 is proposing, once you create the wallet it offers you the option of creating a PDF that you can print or send to an email and you'll keep all the accounts you need.

Also notice that which account to use should be sort of obvious to the user: it's either one that has some ether or token on it, or it's an account that is referenced in another contract.

@alexvandesande
Copy link
Author

@rfikki suggestion?

@axic
Copy link
Member

axic commented Mar 9, 2016

@alexvandesande I think our motivations are different. Your proposal tries to make a secure seed wallet in all cases suitable for high value storage. The user should not need to reenter these details frequently, possibly only once or twice during the lifetime of the wallet.

Based on that assumption it is a bit complex and heavy on RPC (need to check the balance of each address) and suits the use case in Mist well, but I do not see it as suitable for DApps.

@axic
Copy link
Member

axic commented Mar 9, 2016

Motivation

To have a standard process to generate wallets based on various sources of seed.

It should be:

  • easy to implement on the web and on phones
  • shouldn't take a long time (< 2 seconds) to calculate the seed (or at least the first page, as seen below)
  • provide a basic level of security with optionally increasing that with larger, securely generated passphrases

Seed requirements

Two inputs are required:

  • user identifier
  • passphrase

User identifier

A user identifier without limitation on the content. It can be an email address to be memorable.

Requirements:

  • must be at least 10 characters long

Passphrase

A passphrase either entered manually or generated from a dictionary/seed tool.

Requirements:

  • must be at least 10 characters long
  • specify alphabet? does space count? etc.

Calculation

This is a basic outline, but in no means a final proposal. It is potentially unsafe.

First devise master seed using scrypt with:

  • N = 1 << 12
  • r = 8
  • p = 6
  • dklen = 32

Then calculate each account as a subsequent sha3 on the seed. e.g. account1 = sha3(masterSeed) and account2 = sha3(sha3(masterSeed))

At each account step, the appropriate Ethereum address should be calculated, and the step should not be used if the resulting address doesn't fit into 155bits. This is to have the address compatible with ICAP Direct. e.g. if account1 doesn't fit, then account1 = sha3(sha3(masterSeed)) and account2 = sha3(sha3(sha3(masterSeed)))

Visual representation (UI)

Requirements:

  • Allow user to enter a user id
  • Allow user to enter a passphrase
  • Display each account with the initial 5 characters of its address and its position (1st, 2nd, etc) in the derivation chain. Excluding the 0x prefix.
  • Display 6 accounts first. Prompt for displaying the next 6.

Optional:

  • Display strength of passphrase (based on?)
  • Offer the ability to generate passphrase from a dictionary
  • Display identicons next to the accounts
  • Format the account addresses using checksumming (Yet another cool checksum address encoding #55)

Remarks

The user interface looks great and can be applied to the above with the changes mentioned.

An important difference is allowing the user to set the passphrase. My main motivation is to use this seed wallet in low impact cases (such as on a DApp site to pay for execution fees). Given the formula of generating the wallet is fixed and higher entropy passphrases can be used, with the right implementation it should be feasible to use as a high value wallet.

It is possible this proposal is trying to reimplement what a HD wallet does. It may make sense to use a subset of HD wallets instead?

@alexvandesande
Copy link
Author

@axic what you wrote sounded 100% compatible with what I am proposing, so I guess we are on the same page?

@axic
Copy link
Member

axic commented Mar 9, 2016

In point 2 you have this: The user should never pick his own random seed. That is the entire opposite :)

The other difference is the number of accounts displayed and how they are displayed.

@alexvandesande
Copy link
Author

The number of accounts displayed, if we use a username or email as salt and even how to generate the seed phrase, is up to each clients implementation in my opinion. What really matters is that how to generate a key, based on salt + seed + account index, should be the same on all clients.

@trapp
Copy link

trapp commented Mar 9, 2016

Have you thought about just using BIP32 hierarchical deterministic wallets with the BIP39 mnemonic word lists? Maybe follow even the BIP44 standard, Ethereum has been assigned coin type 60 in that standard. This has already been worked out and gives you real hierarchical wallets instead of just an account index.

The private keys are the same (secp256k1) in Ethereum and Bitcoin, public keys can get converted easily.

Libraries are already written in multiple languages which would make integration easy as well.

@trapp
Copy link

trapp commented Mar 9, 2016

Example Ethereum implementation of BIP44 in 60 lines: https://github.com/trapp/ethereum-bip44

To extend this to match the objective of this EIP we could use bitcore-mnemonic to create the HDPrivateKey used for the derivation from a 'writable mnemonic seed' (12 bip39 words):

var EthereumBIP44 = require('ethereum-bip44');
var Mnemonic = require('bitcore-mnemonic');
var code = new Mnemonic('label cart bounce visit such wide warrior siren lake under stable panda');
var hd = new EthereumBIP44(code.toHDPrivateKey());
console.log(hd.getAddress(0)); //0x47f283cff1e42e01bb050eb7d4b1e0a29dc8ebb2
console.log(hd.getAddress(1)); //0x1af839859d829c6b190e87072717959b8f98e96a

@niran
Copy link

niran commented Mar 10, 2016

Yes, please reuse BIPs 39 and 44. This is a solved problem.

@jprichardson
Copy link

Yes, please reuse BIPs 39 and 44. This is a solved problem.

Indeed. This is what we do in Exodus - for all coins/tokens. Please just use BIP39/BIP44. This would ensure compatibility across a diverse range of wallets.

@alexvandesande
Copy link
Author

Thanks for the suggestions I will take a loony at those BIP, of course I favor reusability and compatibility.

On Mar 10, 2016, at 03:56, JP Richardson notifications@github.com wrote:

Yes, please reuse BIPs 39 and 44. This is a solved problem.

Indeed. This is what we do in Exodus - for all coins/tokens. Please just use BIP39/BIP44. This would ensure compatibility across a diverse range of wallets.


Reply to this email directly or view it on GitHub.

@axic
Copy link
Member

axic commented Mar 10, 2016

I think there are two distinct use cases:

  • low impact wallet
  • high impact wallet

I think @alexvandesande's target was something between the two. My proposal (as above and in #76) targets low impact wallets.

High impact wallet

This should definitely just follow BIP32 as there is no point reinventing the wheel. I do have a few comments regarding BIP32:

  1. should we define our own network, e.g. priv/pub prefixes for the Base58 exports

Probably not if it wants to be compatible with hardware wallets and the master seed starts from the text 'Bitcoin seed' anyway.

  1. at a closer look, using vanilla BIP32 as is might not be as elegant as Ethereum strives to be:
  • uses RIPEM160 in the fingerprint
  • forces the use of compressed keys, which have to be decompressed for the purpose of address generation

Probably these two aren't worth changing either.

  1. BIP32 is (almost?) exclusively used with BIP39 mnemonics. Is it worth considering other dictionaries (as mentioned in above)?

Perhaps if it is using vanilla BIP32, there is no point changing dictionaries either.

Low impact wallet

This is a lower security wallet only to be used for small amounts, predominantly for interacting with low impact DApps.

As BIP44 (well, SLIP44) allocates coin type 60 for Ethereum, the first public address would be the path m/44'/60'/0'/0/0. That is at least 106 derivation steps (not counting possible invalid key steps which have to be skipped). Each step involves SHA512-HMAC + ECC multiplication and/or addition.

That might be too much effort CPU wise and the code is slightly more complex. These might be the reasons it is not used on Ethereum sites yet?

Maybe a good middle ground would be fleshing out a restricted feature set of BIP32 for these low impact wallets?

@jprichardson
Copy link

should we define our own network, e.g. priv/pub prefixes for the Base58 exports

No. See: https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki#node-serialization

master seed starts from the text 'Bitcoin seed' anyway.

Yep.

at a closer look, using vanilla BIP32 as is might not be as elegant as Ethereum strives to be:

You only really care about this scheme to derive private keys in a compatible way. With this new private key, you can then generate the the Ethereum address (and public) in the Ethereum way. That's what we do.

BIP32 is (almost?) exclusively used with BIP39 mnemonics.

Yes, today BIP39 and BIP32/44 are frequently used together although they don't have to be.

Is it worth considering other dictionaries (as mentioned in above)?

Per the BIP39 standard, technically the dictionary does not matter. i.e. you could use any text to seed for BIP32 - that is, in any correct BIP39 implementation the same text will always produce the same seed. However, practically, it would matter, because most wallets now check (validate) the mnemonic to make sure that it matches the dictionary. Why not just use the standard dictionary?

As BIP44 (well, SLIP44) allocates coin type 60 for Ethereum, the first public address would be the path m/44'/60'/0'/0/0.

Correct.

That might be too much effort CPU wise and the code is slightly more complex.

I disagree, but I don't have hard numbers handy. Probably worth benchmarking here.

@leafcutterant
Copy link

I highly agree, both with the need for a mnemonic-based HD wallet structure, and most of the mentioned methods to achieve it. Allow me some comments though:

@alexvandesande

Users are used to the pattern email + password as a login on social networks, so while the way this works is different, they might feel more at ease

This is a very bad idea. Most people heavily re-use credentials even when prompted not to. If you go this way, Facebook/Gmail/any-big-provider will be "co-owners" and potential thieves of a big chunk of ethers.

The option of selecting between string generation scheme

This is great from a perspective of user freedom. But it may backfire in terms of compatibility and also makes things more difficult for novice users who can't understand why certain schemes would or would not fit them.

The user should never pick his own random seed.

I very much disagree with this. I see your fear and agree with the possible dangers, but as some advanced option maybe, the user shall be given the option to set the seed. What if I want to use my seed that I already used with other applications and successfully memorized? Or better, what if I don't trust the wallet's (or my computer's) entropy and want to generate my own with my dices?

Pseudo-words.

This sounds like a good idea, but I fear that in reality, less people would choose this. It may be half the length of a regular seed, but it's more than two times more difficult to memorize.

@taoteh1221

Since you are doing this in a GUI in your example (which looks great BTW), a "Print" dialogue prompt with an Icon / Text Button to print the seed phrase would be a good idea to display after generating the brain wallet. I could see typos writing it down by hand occurring. I personally agree with @rfikki that it is a good idea to be backed up in places other than the brain (like an encrypted / password-protected zip or rar file). 😄

I wouldn't go with this. The file to be printed would have to leave the safe memory space of the wallet, and it would remain in 1) the operating system's temp files 2) the memory (or what) of the printer (think of today's smart printers). Mnemonics are engineered with the purpose to be able to write them down easily with pen and paper – they are short and use common, short words.

@trapp: I've been eyeing with your EIP for long, dude, thank you for it. I agree, we shouldn't reinvent the wheel, let's use already working solutions.

Suggestion: in the wallet hierarchy, please use accounts (or, as they are called more appropriately in Dark Wallet, "pockets"). It would be important, in order to protect privacy through separating blockchain traces.

@taoteh1221
Copy link

@leafcutterant

Since you are doing this in a GUI in your example (which looks great BTW), a "Print" dialogue prompt with an Icon / Text Button to print the seed phrase would be a good idea to display after generating the brain wallet. I could see typos writing it down by hand occurring. I personally agree with @rfikki that it is a good idea to be backed up in places other than the brain (like an encrypted / password-protected zip or rar file). 😄

I wouldn't go with this. The file to be printed would have to leave the safe memory space of the wallet, and it would remain in 1) the operating system's temp files 2) the memory (or what) of the printer (think of today's smart printers). Mnemonics are engineered with the purpose to be able to write them down easily with pen and paper – they are short and use common, short words.

Very good point, but I think considering inexperienced new end users are required for mass adoption, coming up with some kind of a balance between ease-of-use with failsafes and security may be good to consider. Maybe just do some heavy backup prompting textually, with a warning there is no password recovery etc etc.

@alexvandesande
Copy link
Author

@leafcutterant @taoteh1221 I think it's a bit too early to discuss printing but I think it's solvable: have a safer option where you print a PDF with some information like the salt and a list of the generated wallets, and leave a blank space for the user to write the seed down. Of course, the UI needs to make sure the user wrote the seed down after printing. Armoury does a similar thing

@taoteh1221
Copy link

👍

@coder5876
Copy link

I'm also favoring BIP32 and BIP44 (at least at this point). In Lightwallet a different BIP32 derivation path is used ATM by default but I plan on using BIP44 specifically for addresses that are used to send/receive ETH value.

There is a long discussion to be had about HD key derivation paths for various purposes: Ethereum keys used for dapp interactions / keys used for value transfer / keys used for encryption.

@axic I am staunchly against letting the user pick their own passphrase. People will pick "password" and their son's name (these are the two passwords one of my friends likes to use) and they will lose their money instantly.

@cubedro
Copy link
Member

cubedro commented Mar 11, 2016

👍

@axic
Copy link
Member

axic commented Mar 11, 2016

@christianlundkvist I am still sticking to my point that different use cases may require different solutions.

If someone is looking forward to create a proper HD wallet, that should just work based off BIP32 + BIP39. This issue got fully transformed into a discussion about mnemonic seed wallets and for that I fully agree to follow these.

If the wallet is for the purpose of paying for gas and storing insignificant amounts, then it might not be the best solution in my opinion. In my use case, the user has to enter the "seed" every single time trying to use the app. If it is a BIP39 mnemonic based seed they will just copy & paste that. Who would try to remember that for a wallet worth <1 ETH?

It is possible that this use case is very limited and no one else is facing that apart from me.

(This issue started out with a different title, namely brain wallet. The use case I describe fits the "brain wallet" scenario and not the "mnemonic seed wallet" one. Maybe better to move this part of the discussion to #76 to avoid confusion.)

@coder5876
Copy link

@axic I think in future use cases the amount of Ether in an address will have little correlation to the value or sensitivity of that address. Think about having an address that is used to digitally signing important documents or an admin key for an important smart contract. You only need < 1 ETH in that address, but it is vitally important to safeguard that private key. In my "dream" scenario the user would never have to see or interact with their private keys, they would be randomly generated on their devices with backup systems in place to allow them to replace their keys if all their devices are lost. It will take some time to get there though...

@axic
Copy link
Member

axic commented Mar 18, 2016

@christianlundkvist to clarify, by "worth < 1 ETH" I not only meant that it stores < 1 ETH in that address, rather that the overall impact it has is around that value. If, through a contract its impact is bigger, then it doesn't fall under the low impact account criteria.

A master key for a wallet contract would clearly not mean it is low impact.

@coder5876
Copy link

@axic Cool, understood! I guess I wanted to convey that in general it might be hard to know in advance if a key will be used for something trivial or important, so it may be better to make sure that it's hard for the user to get confused and use an insecure method.

@wanderer wanderer changed the title ERC: Standard Writeable Mnemonic Seed Proposal Standard Writeable Mnemonic Seed Proposal Apr 14, 2016
@wanderer wanderer added the ERC label Apr 14, 2016
@leafcutterant
Copy link

Any news on this? I suppose I'm not the only one who thinks it's unsafe to store ether on addresses derived from non-deterministic private keys.

@fulldecent
Copy link
Contributor

@Arachnid You nominated this as an "EIPs that should be merged". Can you please share your notes on that here?

Is there an actual EIP here to discuss? I think this is a great idea but I don't know if this is the right EIP to standardize it or if there is another one.

@leafcutterant
Copy link

Actually, is there any need to keep this issue open? In the two years since the opening, the industry went ahead and integrated BIP39 into pretty much everything where an HD Ethereum wallet is needed.

Coming up with a new standard would lead to confusion and fragmentation. I think it would be a good idea only if it provides some quintessential or significant improvements. (That is not to say it doesn't provide such. But apart from my earlier comments, I'm not one to judge this.)

@alexvandesande
Copy link
Author

This EIP doesn't need to be open. I wanted to share this as an idea and I still believe its a better experience than 12 words. But maybe I can simply make this into a little website for generating keys and that's it. Should I close it? Not sure why arachnid added the tag

@fulldecent
Copy link
Contributor

Thank you for the quick reply. I think it is reasonable to close the issue and it can always be reopened if necessary.

@Arachnid
Copy link
Contributor

@alexvandesande This issue is referenced from the readme as an example EIP. We need to either merge it as a historical interest obsolete eip, or remove the reference from the readme.

@alexvandesande
Copy link
Author

Really? Oh! 🤩☺️

Either way, merging this will not make this into a more adopted standard either way. We should use ERC20 as the example EIP then

@Arachnid
Copy link
Contributor

@alexvandesande ERC20 is too: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1.md

We can remove this from eip 1 and the new index page if desired. Merging it as obsolete might be of historical interest, though.

@alexvandesande
Copy link
Author

alexvandesande commented Mar 23, 2018 via email

@Arachnid
Copy link
Contributor

Removing it from the index, instead, since the current proposal isn't formatted as a modern EIP.

bumblefudge added a commit to bumblefudge/EIPs that referenced this issue Feb 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests