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

[Merged by Bors] - Wallet creation: Make mnemonic length configurable, default to 24 words. #1697

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 28 additions & 2 deletions account_manager/src/wallet/create.rs
Expand Up @@ -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:";
Expand Down Expand Up @@ -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::<usize>().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::<Vec<_>>().join(", "))),
}
})
.default_value("24"),
)
}

pub fn cli_run(matches: &ArgMatches, base_dir: PathBuf) -> Result<(), String> {
Expand All @@ -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)?;

Expand All @@ -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!();
Expand Down
8 changes: 4 additions & 4 deletions book/src/become-a-validator-source.md
Expand Up @@ -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.
Expand All @@ -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
Expand Down
10 changes: 6 additions & 4 deletions book/src/key-management.md
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions 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
Expand Down