cosmos-sdk/client/keys/mnemonic.go

75 lines
1.8 KiB
Go

package keys
import (
"crypto/sha256"
"fmt"
bip39 "github.com/bartekn/go-bip39"
"github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/cobra"
)
const (
flagUserEntropy = "unsafe-entropy"
mnemonicEntropySize = 256
)
func mnemonicKeyCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "mnemonic",
Short: "Compute the bip39 mnemonic for some input entropy",
Long: "Create a bip39 mnemonic, sometimes called a seed phrase, by reading from the system entropy. To pass your own entropy, use --unsafe-entropy",
RunE: runMnemonicCmd,
}
cmd.Flags().Bool(flagUserEntropy, false, "Prompt the user to supply their own entropy, instead of relying on the system")
return cmd
}
func runMnemonicCmd(cmd *cobra.Command, args []string) error {
flags := cmd.Flags()
userEntropy, _ := flags.GetBool(flagUserEntropy)
var entropySeed []byte
if userEntropy {
// prompt the user to enter some entropy
buf := client.BufferStdin()
inputEntropy, err := client.GetString("> WARNING: Generate at least 256-bits of entropy and enter the results here:", buf)
if err != nil {
return err
}
if len(inputEntropy) < 43 {
return fmt.Errorf("256-bits is 43 characters in Base-64, and 100 in Base-6. You entered %v, and probably want more", len(inputEntropy))
}
conf, err := client.GetConfirmation(fmt.Sprintf("> Input length: %d", len(inputEntropy)), buf)
if err != nil {
return err
}
if !conf {
return nil
}
// hash input entropy to get entropy seed
hashedEntropy := sha256.Sum256([]byte(inputEntropy))
entropySeed = hashedEntropy[:]
} else {
// read entropy seed straight from crypto.Rand
var err error
entropySeed, err = bip39.NewEntropy(mnemonicEntropySize)
if err != nil {
return err
}
}
mnemonic, err := bip39.NewMnemonic(entropySeed[:])
if err != nil {
return err
}
fmt.Println(mnemonic)
return nil
}