diff --git a/account_manager/src/wallet/create.rs b/account_manager/src/wallet/create.rs index 04d141b48b4..74491024756 100644 --- a/account_manager/src/wallet/create.rs +++ b/account_manager/src/wallet/create.rs @@ -23,6 +23,14 @@ pub const PASSWORD_FLAG: &str = "password-file"; pub const TYPE_FLAG: &str = "type"; pub const MNEMONIC_FLAG: &str = "mnemonic-output-path"; pub const STDIN_INPUTS_FLAG: &str = "stdin-inputs"; +pub const MNEMONIC_LENGTH_FLAG: &str = "mnemonic-length"; +pub const MNEMONIC_TYPES: &[MnemonicType] = &[ + MnemonicType::Words12, + MnemonicType::Words15, + MnemonicType::Words18, + MnemonicType::Words21, + MnemonicType::Words24, +]; pub const NEW_WALLET_PASSWORD_PROMPT: &str = "Enter a password for your new wallet that is at least 12 characters long:"; pub const RETYPE_PASSWORD_PROMPT: &str = "Please re-enter your wallet's new password:"; @@ -78,6 +86,20 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) + .arg( + Arg::with_name(MNEMONIC_LENGTH_FLAG) + .long(MNEMONIC_LENGTH_FLAG) + .value_name("MNEMONIC_LENGTH") + .help("The number of words to use for the mnemonic phrase.") + .takes_value(true) + .validator(|len| { + match len.parse::().ok().and_then(|words| MnemonicType::for_word_count(words).ok()) { + Some(_) => Ok(()), + None => Err(format!("Mnemonic length must be one of {}", MNEMONIC_TYPES.iter().map(|t| t.word_count().to_string()).collect::>().join(", "))), + } + }) + .default_value("24"), + ) } pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> { @@ -86,7 +108,11 @@ pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> { // Create a new random mnemonic. // // The `tiny-bip39` crate uses `thread_rng()` for this entropy. - let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English); + let mnemonic_length = clap_utils::parse_required(matches, MNEMONIC_LENGTH_FLAG)?; + let mnemonic = Mnemonic::new( + MnemonicType::for_word_count(mnemonic_length).expect("Mnemonic length already validated"), + Language::English, + ); let wallet = create_wallet_from_mnemonic(matches, &base_dir.as_path(), &mnemonic)?; @@ -95,7 +121,7 @@ pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> { .map_err(|e| format!("Unable to write mnemonic to {:?}: {:?}", path, e))?; } - println!("Your wallet's 12-word BIP-39 mnemonic is:"); + println!("Your wallet's {}-word BIP-39 mnemonic is:", mnemonic_length); println!(); println!("\t{}", mnemonic.phrase()); println!(); diff --git a/book/src/become-a-validator-source.md b/book/src/become-a-validator-source.md index 8b116985517..6dc661035c9 100644 --- a/book/src/become-a-validator-source.md +++ b/book/src/become-a-validator-source.md @@ -97,9 +97,9 @@ lighthouse --testnet medalla account wallet create You will be prompted for a wallet name and a password. The output will look like this: ``` -Your wallet's 12-word BIP-39 mnemonic is: +Your wallet's 24-word BIP-39 mnemonic is: - thank beach essence clerk gun library key grape hotel wise dutch segment + glad marble art pelican nurse large guilt response brave affair kite essence welcome gauge peace once picnic debris devote ticket blood bike solar junk This mnemonic can be used to fully restore your wallet, should you lose the JSON file or your password. @@ -114,12 +114,12 @@ a piece of paper and storing it in a safe place would be prudent. Your wallet's UUID is: - e762671a-2a33-4922-901b-62a43dbd5227 + 1c8c13d5-d065-4ef7-bad3-14e9d8146140 You do not need to backup your UUID or keep it secret. ``` -**Don't forget to make a backup** of the 12-word BIP-39 mnemonic. It can be +**Don't forget to make a backup** of the 24-word BIP-39 mnemonic. It can be used to restore your validator if there is a data loss. ### 4.2 Create a Validator from the Wallet diff --git a/book/src/key-management.md b/book/src/key-management.md index 53edec221d9..412bcf9901e 100644 --- a/book/src/key-management.md +++ b/book/src/key-management.md @@ -3,7 +3,7 @@ Lighthouse uses a _hierarchical_ key management system for producing validator keys. It is hierarchical because each validator key can be _derived_ from a master key, making the validators keys _children_ of the master key. This -scheme means that a single 12-word mnemonic can be used to backup all of your +scheme means that a single 24-word mnemonic can be used to backup all of your validator keys without providing any observable link between them (i.e., it is privacy-retaining). Hierarchical key derivation schemes are common-place in cryptocurrencies, they are already used by most hardware and software wallets @@ -13,8 +13,10 @@ to secure BTC, ETH and many other coins. We defined some terms in the context of validator key management: -- **Mnemonic**: a string of 12-words that is designed to be easy to write down - and remember. E.g., _"enemy fog enlist laundry nurse hungry discover turkey holiday resemble glad discover"_. +- **Mnemonic**: a string of 24 words that is designed to be easy to write down + and remember. E.g., _"radar fly lottery mirror fat icon bachelor sadness + type exhaust mule six beef arrest you spirit clog mango snap fox citizen + already bird erase"_. - Defined in BIP-39 - **Wallet**: a wallet is a JSON file which stores an encrypted version of a mnemonic. @@ -49,7 +51,7 @@ In step (1), we created a wallet in `~/.lighthouse/wallets` with the name Thanks to the hierarchical key derivation scheme, we can delete all of the aforementioned directories and then regenerate them as long as we remembered -the 12-word mnemonic (we don't recommend doing this, though). +the 24-word mnemonic (we don't recommend doing this, though). Creating another validator is easy, it's just a matter of repeating step (2). The wallet keeps track of how many validators it has generated and ensures that diff --git a/book/src/wallet-create.md b/book/src/wallet-create.md index fe0ac6dc94a..668b10db8d9 100644 --- a/book/src/wallet-create.md +++ b/book/src/wallet-create.md @@ -1,10 +1,10 @@ # Create a wallet A wallet allows for generating practically unlimited validators from an -easy-to-remember 12-word string (a mnemonic). As long as that mnemonic is +easy-to-remember 24-word string (a mnemonic). As long as that mnemonic is backed up, all validator keys can be trivially re-generated. -The 12-word string is randomly generated during wallet creation and printed out +The 24-word string is randomly generated during wallet creation and printed out to the terminal. It's important to **make one or more backups of the mnemonic** to ensure your ETH is not lost in the case of data loss. It very important to **keep your mnemonic private** as it represents the ultimate control of your