OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-crypto / keys / wordcodec_test.go
1 package keys
2
3 import (
4         "testing"
5
6         "github.com/stretchr/testify/assert"
7         "github.com/stretchr/testify/require"
8
9         cmn "github.com/tendermint/tmlibs/common"
10 )
11
12 func TestLengthCalc(t *testing.T) {
13         assert := assert.New(t)
14
15         cases := []struct {
16                 bytes, words int
17                 flexible     bool
18         }{
19                 {1, 1, false},
20                 {2, 2, false},
21                 // bytes pairs with same word count
22                 {3, 3, true},
23                 {4, 3, true},
24                 {5, 4, false},
25                 // bytes pairs with same word count
26                 {10, 8, true},
27                 {11, 8, true},
28                 {12, 9, false},
29                 {13, 10, false},
30                 {20, 15, false},
31                 // bytes pairs with same word count
32                 {21, 16, true},
33                 {32, 24, true},
34         }
35
36         for _, tc := range cases {
37                 wl := wordlenFromBytes(tc.bytes)
38                 assert.Equal(tc.words, wl, "%d", tc.bytes)
39
40                 bl, flex := bytelenFromWords(tc.words)
41                 assert.Equal(tc.flexible, flex, "%d", tc.words)
42                 if !flex {
43                         assert.Equal(tc.bytes, bl, "%d", tc.words)
44                 } else {
45                         // check if it is either tc.bytes or tc.bytes +1
46                         choices := []int{tc.bytes, tc.bytes + 1}
47                         assert.Contains(choices, bl, "%d", tc.words)
48                 }
49         }
50 }
51
52 func TestEncodeDecode(t *testing.T) {
53         assert, require := assert.New(t), require.New(t)
54
55         codec, err := LoadCodec("english")
56         require.Nil(err, "%+v", err)
57
58         cases := [][]byte{
59                 {7, 8, 9},                         // TODO: 3 words -> 3 or 4 bytes
60                 {12, 54, 99, 11},                  // TODO: 3 words -> 3 or 4 bytes
61                 {0, 54, 99, 11},                   // TODO: 3 words -> 3 or 4 bytes, detect leading 0
62                 {1, 2, 3, 4, 5},                   // normal
63                 {0, 0, 0, 0, 122, 23, 82, 195},    // leading 0s (8 chars, unclear)
64                 {0, 0, 0, 0, 5, 22, 123, 55, 22},  // leading 0s (9 chars, clear)
65                 {22, 44, 55, 1, 13, 0, 0, 0, 0},   // trailing 0s (9 chars, clear)
66                 {0, 5, 253, 2, 0},                 // leading and trailing zeros
67                 {255, 196, 172, 234, 192, 255},    // big numbers
68                 {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices
69                 // others?
70         }
71
72         for i, tc := range cases {
73                 w, err := codec.BytesToWords(tc)
74                 if assert.Nil(err, "%d: %v", i, err) {
75                         b, err := codec.WordsToBytes(w)
76                         if assert.Nil(err, "%d: %v", i, err) {
77                                 assert.Equal(len(tc), len(b))
78                                 assert.Equal(tc, b)
79                         }
80                 }
81         }
82 }
83
84 func TestCheckInvalidLists(t *testing.T) {
85         assert := assert.New(t)
86
87         trivial := []string{"abc", "def"}
88         short := make([]string, 1234)
89         long := make([]string, BankSize+1)
90         right := make([]string, BankSize)
91         dups := make([]string, BankSize)
92
93         for _, list := range [][]string{short, long, right, dups} {
94                 for i := range list {
95                         list[i] = cmn.RandStr(8)
96                 }
97         }
98         // create one single duplicate
99         dups[192] = dups[782]
100
101         cases := []struct {
102                 words    []string
103                 loadable bool
104                 valid    bool
105         }{
106                 {trivial, false, false},
107                 {short, false, false},
108                 {long, false, false},
109                 {dups, true, false}, // we only check dups on first use...
110                 {right, true, true},
111         }
112
113         for i, tc := range cases {
114                 codec, err := NewCodec(tc.words)
115                 if !tc.loadable {
116                         assert.NotNil(err, "%d", i)
117                 } else if assert.Nil(err, "%d: %+v", i, err) {
118                         data := cmn.RandBytes(32)
119                         w, err := codec.BytesToWords(data)
120                         if tc.valid {
121                                 assert.Nil(err, "%d: %+v", i, err)
122                                 b, err1 := codec.WordsToBytes(w)
123                                 assert.Nil(err1, "%d: %+v", i, err1)
124                                 assert.Equal(data, b)
125                         } else {
126                                 assert.NotNil(err, "%d", i)
127                         }
128                 }
129         }
130
131 }
132
133 func getRandWord(c *WordCodec) string {
134         idx := cmn.RandInt() % BankSize
135         return c.words[idx]
136 }
137
138 func getDiffWord(c *WordCodec, not string) string {
139         w := getRandWord(c)
140         if w == not {
141                 w = getRandWord(c)
142         }
143         return w
144 }
145
146 func TestCheckTypoDetection(t *testing.T) {
147         assert, require := assert.New(t), require.New(t)
148
149         banks := []string{"english", "spanish", "japanese", "chinese_simplified"}
150
151         for _, bank := range banks {
152                 codec, err := LoadCodec(bank)
153                 require.Nil(err, "%s: %+v", bank, err)
154                 for i := 0; i < 1000; i++ {
155                         numBytes := cmn.RandInt()%60 + 4
156                         data := cmn.RandBytes(numBytes)
157
158                         words, err := codec.BytesToWords(data)
159                         assert.Nil(err, "%s: %+v", bank, err)
160                         good, err := codec.WordsToBytes(words)
161                         assert.Nil(err, "%s: %+v", bank, err)
162                         assert.Equal(data, good, bank)
163
164                         // now try some tweaks...
165                         cut := words[1:]
166                         _, err = codec.WordsToBytes(cut)
167                         assert.NotNil(err, "%s: %s", bank, words)
168
169                         // swap a word within the bank, should fails
170                         words[3] = getDiffWord(codec, words[3])
171                         _, err = codec.WordsToBytes(words)
172                         assert.NotNil(err, "%s: %s", bank, words)
173
174                         // put a random word here, must fail
175                         words[3] = cmn.RandStr(10)
176                         _, err = codec.WordsToBytes(words)
177                         assert.NotNil(err, "%s: %s", bank, words)
178                 }
179         }
180 }