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  }