diff --git a/cmd/bnscli/cmd_key.go b/cmd/bnscli/cmd_key.go index 30e6d6e1..653d95f0 100644 --- a/cmd/bnscli/cmd_key.go +++ b/cmd/bnscli/cmd_key.go @@ -70,7 +70,7 @@ created. This command fails if the private key file already exists. // keygen returns a private key generated using given mnemonic and derivation // path. func keygen(mnemonic, derivationPath string) (ed25519.PrivateKey, error) { - if !bip39.IsMnemonicValid(string(mnemonic)) { + if !isMnemonicValid(string(mnemonic)) { return nil, errors.New("invalid mnemonic") } @@ -89,6 +89,15 @@ func keygen(mnemonic, derivationPath string) (ed25519.PrivateKey, error) { return priv, nil } +// isMnemonicValid returns true if given mnemonic string is valid. Whitespaces +// are ignored. +// Use this instead of bip39.IsMnemonicValid because this function ensures the +// checksum consistency. bip39.IsMnemonicValid does not test the checksum. +func isMnemonicValid(mnemonic string) bool { + _, err := bip39.EntropyFromMnemonic(mnemonic) + return err == nil +} + func cmdKeyaddr(input io.Reader, output io.Writer, args []string) error { fl := flag.NewFlagSet("", flag.ExitOnError) fl.Usage = func() { @@ -147,6 +156,7 @@ func cmdMnemonic(input io.Reader, output io.Writer, args []string) error { fmt.Fprint(flag.CommandLine.Output(), ` Generate and print out a mnemonic. Keep the result in safe place! `) + fl.PrintDefaults() } var ( bitSizeFl = fl.Uint("size", 256, "Bit size of the entropy. Must be between 128 and 256.") diff --git a/cmd/bnscli/cmd_key_test.go b/cmd/bnscli/cmd_key_test.go index 76bddec0..bd3bc980 100644 --- a/cmd/bnscli/cmd_key_test.go +++ b/cmd/bnscli/cmd_key_test.go @@ -45,19 +45,19 @@ func TestMnemonic(t *testing.T) { }{ "valid mnemonic 12 words": { - mnemonic: "usage mountain noodle inspire distance lyrics caution wait mansion never announce biology", + mnemonic: "super bulk plunge better rookie donor reward obscure rescue type trade pelican", wantErr: false, }, "valid mnemonic 15 words": { - mnemonic: "usage mountain noodle inspire distance lyrics caution wait mansion never announce biology squirrel guess key", + mnemonic: "say debris entry orange grief deer train until flock scrub volume artist skill obscure immense", wantErr: false, }, "valid mnemonic 18 words": { - mnemonic: "usage mountain noodle inspire distance lyrics caution wait mansion never announce biology squirrel guess key gain belt same", + mnemonic: "fetch height snow poverty space follow seven festival wasp pet asset tattoo cement twist exile trend bench eternal", wantErr: false, }, "valid mnemonic 21 words": { - mnemonic: "usage mountain noodle inspire distance lyrics caution wait mansion never announce biology squirrel guess key gain belt same matrix chase mom", + mnemonic: "increase shine pumpkin curtain trash cabbage juice canal ugly naive name insane indoor assault snap taxi casual unhappy buddy defense artefact", wantErr: false, }, "valid mnemonic 24 words": { @@ -66,11 +66,13 @@ func TestMnemonic(t *testing.T) { }, "additional whitespace around mnemonnic is ignored": { mnemonic: ` - usage - mountain - noodle - inspire distance lyrics caution wait mansion - never announce biology + forget + rely tiny + ostrich drop edit + assault mechanic pony extend + together twelve + observe bullet dream + short glide crack orchard exotic zero fly spice final `, wantErr: false, }, @@ -82,6 +84,10 @@ func TestMnemonic(t *testing.T) { mnemonic: " あつかう あっしゅく あつまり あつめる あてな あてはまる あひる あぶら あぶる あふれる あまい あまど ", wantErr: true, }, + "initially valid mnemonic that the last word was changed": { + mnemonic: "super bulk plunge better rookie donor reward obscure rescue type trade trade", + wantErr: true, + }, } for testName, tc := range cases { diff --git a/go.mod b/go.mod index bc94e572..96c610b8 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/tendermint/go-amino v0.15.0 github.com/tendermint/iavl v0.12.2 github.com/tendermint/tendermint v0.31.5 - github.com/tyler-smith/go-bip39 v1.0.0 + github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f google.golang.org/grpc v1.21.0 // indirect ) diff --git a/go.sum b/go.sum index 11266ab3..d2979bac 100644 --- a/go.sum +++ b/go.sum @@ -125,8 +125,8 @@ github.com/tendermint/iavl v0.12.2 h1:Ls5p5VINCM1HRT9g5Vvs2zmDOCU/CCIvIHzd/pZ8P0 github.com/tendermint/iavl v0.12.2/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= github.com/tendermint/tendermint v0.31.5 h1:vTet8tCq3B9/J9Yo11dNZ8pOB7NtSy++bVSfkP4KzR4= github.com/tendermint/tendermint v0.31.5/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpslATMVqiGgWbZrlc= -github.com/tyler-smith/go-bip39 v1.0.0 h1:FOHg9gaQLeBBRbHE/QrTLfEiBHy5pQ/yXzf9JG5pYFM= -github.com/tyler-smith/go-bip39 v1.0.0/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=