github.com/status-im/status-go/extkeys@v1.1.2/mnemonic_test.go (about) 1 package extkeys 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "testing" 8 ) 9 10 type VectorsFile struct { 11 Data map[string][][6]string 12 vectors []*Vector 13 } 14 15 type Vector struct { 16 language, password, input, mnemonic, seed, xprv string 17 } 18 19 func TestNewMnemonic(t *testing.T) { 20 m1 := NewMnemonic() 21 if m1.salt != defaultSalt { 22 t.Errorf("expected default salt, got: %q", m1.salt) 23 } 24 } 25 26 func TestMnemonic_WordList(t *testing.T) { 27 m := NewMnemonic() 28 _, err := m.WordList(EnglishLanguage) 29 if err != nil { 30 t.Errorf("expected WordList to return WordList without errors, got: %s", err) 31 } 32 33 indexes := []Language{-1, Language(len(m.wordLists))} 34 for _, index := range indexes { 35 _, err := m.WordList(index) 36 if err == nil { 37 t.Errorf("expected WordList to return an error with index %d", index) 38 } 39 } 40 } 41 42 // TestMnemonicPhrase 43 func TestMnemonicPhrase(t *testing.T) { 44 45 mnemonic := NewMnemonic() 46 47 // test strength validation 48 strengths := []EntropyStrength{127, 129, 257} 49 for _, s := range strengths { 50 _, err := mnemonic.MnemonicPhrase(s, EnglishLanguage) 51 if err != ErrInvalidEntropyStrength { 52 t.Errorf("Entropy strength '%d' should be invalid", s) 53 } 54 } 55 56 // test mnemonic generation 57 t.Log("Test mnemonic generation:") 58 for _, language := range mnemonic.AvailableLanguages() { 59 phrase, err := mnemonic.MnemonicPhrase(EntropyStrength128, language) 60 t.Logf("Mnemonic (%s): %s", Languages[language], phrase) 61 62 if err != nil { 63 t.Errorf("Test failed: could not create seed: %s", err) 64 } 65 66 if !mnemonic.ValidMnemonic(phrase, language) { 67 t.Error("Seed is not valid Mnenomic") 68 } 69 } 70 71 // run against test vectors 72 vectorsFile, err := LoadVectorsFile("mnemonic_vectors.json") 73 if err != nil { 74 t.Error(err) 75 } 76 77 t.Log("Test against pre-computed seed vectors:") 78 stats := map[string]int{} 79 for _, vector := range vectorsFile.vectors { 80 stats[vector.language]++ 81 mnemonic := NewMnemonic() 82 seed := mnemonic.MnemonicSeed(vector.mnemonic, vector.password) 83 if fmt.Sprintf("%x", seed) != vector.seed { 84 t.Errorf("Test failed (%s): incorrect seed (%x) generated (expected: %s)", vector.language, seed, vector.seed) 85 return 86 } 87 //t.Logf("Test passed: correct seed (%x) generated (expected: %s)", seed, vector.seed) 88 89 rootKey, err := NewMaster(seed) 90 if err != nil { 91 t.Error(err) 92 } 93 94 if rootKey.String() != vector.xprv { 95 t.Errorf("Test failed (%s): incorrect xprv (%s) generated (expected: %s)", vector.language, rootKey, vector.xprv) 96 } 97 } 98 for language, count := range stats { 99 t.Logf("[%s]: %d tests completed", language, count) 100 } 101 } 102 103 func LoadVectorsFile(path string) (*VectorsFile, error) { 104 fp, err := os.Open(path) 105 if err != nil { 106 return nil, fmt.Errorf("Test failed: cannot open vectors file: %s", err) 107 } 108 109 var vectorsFile VectorsFile 110 if err := json.NewDecoder(fp).Decode(&vectorsFile); err != nil { 111 return nil, fmt.Errorf("Test failed: cannot parse vectors file: %s", err) 112 } 113 114 // load data into Vector structs 115 for language, data := range vectorsFile.Data { 116 for _, item := range data { 117 vectorsFile.vectors = append(vectorsFile.vectors, &Vector{language, item[0], item[1], item[2], item[3], item[4]}) 118 } 119 } 120 121 return &vectorsFile, nil 122 } 123 124 func (v *Vector) String() string { 125 return fmt.Sprintf("{password: %s, input: %s, mnemonic: %s, seed: %s, xprv: %s}", 126 v.password, v.input, v.mnemonic, v.seed, v.xprv) 127 }