1package bip39
2
3import (
4	"crypto/rand"
5	"encoding/hex"
6	"testing"
7
8	"github.com/tyler-smith/go-bip39/wordlists"
9)
10
11type vector struct {
12	entropy  string
13	mnemonic string
14	seed     string
15}
16
17func TestGetWordList(t *testing.T) {
18	assertEqualStringSlices(t, wordlists.English, GetWordList())
19}
20
21func TestGetWordIndex(t *testing.T) {
22	for expectedIdx, word := range wordList {
23		actualIdx, ok := GetWordIndex(word)
24		assertTrue(t, ok)
25		assertEqual(t, actualIdx, expectedIdx)
26	}
27
28	for _, word := range []string{"a", "set", "of", "invalid", "words"} {
29		actualIdx, ok := GetWordIndex(word)
30		assertFalse(t, ok)
31		assertEqual(t, actualIdx, 0)
32	}
33}
34
35func TestNewMnemonic(t *testing.T) {
36	for _, vector := range testVectors() {
37		entropy, err := hex.DecodeString(vector.entropy)
38		assertNil(t, err)
39
40		mnemonic, err := NewMnemonic(entropy)
41		assertNil(t, err)
42		assertEqualString(t, vector.mnemonic, mnemonic)
43
44		_, err = NewSeedWithErrorChecking(mnemonic, "TREZOR")
45		assertNil(t, err)
46
47		seed := NewSeed(mnemonic, "TREZOR")
48		assertEqualString(t, vector.seed, hex.EncodeToString(seed))
49	}
50}
51
52func TestNewMnemonicInvalidEntropy(t *testing.T) {
53	_, err := NewMnemonic([]byte{})
54	assertNotNil(t, err)
55}
56
57func TestNewSeedWithErrorCheckingInvalidMnemonics(t *testing.T) {
58	for _, vector := range badMnemonicSentences() {
59		_, err := NewSeedWithErrorChecking(vector.mnemonic, "TREZOR")
60		assertNotNil(t, err)
61	}
62}
63
64func TestIsMnemonicValid(t *testing.T) {
65	for _, vector := range badMnemonicSentences() {
66		assertFalse(t, IsMnemonicValid(vector.mnemonic))
67	}
68
69	for _, vector := range testVectors() {
70		assertTrue(t, IsMnemonicValid(vector.mnemonic))
71	}
72}
73
74func TestMnemonicToByteArrayInvalidMnemonic(t *testing.T) {
75	for _, vector := range badMnemonicSentences() {
76		_, err := MnemonicToByteArray(vector.mnemonic)
77		assertNotNil(t, err)
78	}
79
80	_, err := MnemonicToByteArray("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon yellow")
81	assertNotNil(t, err)
82	assertEqual(t, err, ErrChecksumIncorrect)
83}
84
85func TestNewEntropy(t *testing.T) {
86	// Good tests.
87	for i := 128; i <= 256; i += 32 {
88		_, err := NewEntropy(i)
89		assertNil(t, err)
90	}
91	// Bad Values
92	for i := 0; i <= 256; i++ {
93		if i%8 != 0 {
94			_, err := NewEntropy(i)
95			assertNotNil(t, err)
96		}
97	}
98}
99
100func TestMnemonicToByteArrayForDifferentArrayLangths(t *testing.T) {
101	max := 1000
102	for i := 0; i < max; i++ {
103		//16, 20, 24, 28, 32
104		length := 16 + (i%5)*4
105		seed := make([]byte, length)
106		if n, err := rand.Read(seed); err != nil {
107			t.Errorf("%v", err)
108		} else if n != length {
109			t.Errorf("Wrong number of bytes read: %d", n)
110		}
111
112		mnemonic, err := NewMnemonic(seed)
113		if err != nil {
114			t.Errorf("%v", err)
115		}
116
117		_, err = MnemonicToByteArray(mnemonic)
118		if err != nil {
119			t.Errorf("Failed for %x - %v", seed, mnemonic)
120		}
121	}
122}
123func TestPadByteSlice(t *testing.T) {
124	assertEqualByteSlices(t, []byte{0}, padByteSlice([]byte{}, 1))
125	assertEqualByteSlices(t, []byte{0, 1}, padByteSlice([]byte{1}, 2))
126	assertEqualByteSlices(t, []byte{1, 1}, padByteSlice([]byte{1, 1}, 2))
127	assertEqualByteSlices(t, []byte{1, 1, 1}, padByteSlice([]byte{1, 1, 1}, 2))
128}
129
130func TestCompareByteSlices(t *testing.T) {
131	assertTrue(t, compareByteSlices([]byte{}, []byte{}))
132	assertTrue(t, compareByteSlices([]byte{1}, []byte{1}))
133	assertFalse(t, compareByteSlices([]byte{1}, []byte{0}))
134	assertFalse(t, compareByteSlices([]byte{1}, []byte{}))
135	assertFalse(t, compareByteSlices([]byte{1}, nil))
136}
137
138func TestMnemonicToByteArrayForZeroLeadingSeeds(t *testing.T) {
139	ms := []string{
140		"00000000000000000000000000000000",
141		"00a84c51041d49acca66e6160c1fa999",
142		"00ca45df1673c76537a2020bfed1dafd",
143		"0019d5871c7b81fd83d474ef1c1e1dae",
144		"00dcb021afb35ffcdd1d032d2056fc86",
145		"0062be7bd09a27288b6cf0eb565ec739",
146		"00dc705b5efa0adf25b9734226ba60d4",
147		"0017747418d54c6003fa64fade83374b",
148		"000d44d3ee7c3dfa45e608c65384431b",
149		"008241c1ef976b0323061affe5bf24b9",
150		"00a6aec77e4d16bea80b50a34991aaba",
151		"0011527b8c6ddecb9d0c20beccdeb58d",
152		"001c938c503c8f5a2bba2248ff621546",
153		"0002f90aaf7a8327698f0031b6317c36",
154		"00bff43071ed7e07f77b14f615993bac",
155		"00da143e00ef17fc63b6fb22dcc2c326",
156		"00ffc6764fb32a354cab1a3ddefb015d",
157		"0062ef47e0985e8953f24760b7598cdd",
158		"003bf9765064f71d304908d906c065f5",
159		"00993851503471439d154b3613947474",
160		"007ad0ffe9eae753a483a76af06dfa67",
161		"00091824db9ec19e663bee51d64c83cc",
162		"00f48ac621f7e3cb39b2012ac3121543",
163		"0072917415cdca24dfa66c4a92c885b4",
164		"0027ced2b279ea8a91d29364487cdbf4",
165		"00b9c0d37fb10ba272e55842ad812583",
166		"004b3d0d2b9285946c687a5350479c8c",
167		"00c7c12a37d3a7f8c1532b17c89b724c",
168		"00f400c5545f06ae17ad00f3041e4e26",
169		"001e290be10df4d209f247ac5878662b",
170		"00bf0f74568e582a7dd1ee64f792ec8b",
171		"00d2e43ecde6b72b847db1539ed89e23",
172		"00cecba6678505bb7bfec8ed307251f6",
173		"000aeed1a9edcbb4bc88f610d3ce84eb",
174		"00d06206aadfc25c2b21805d283f15ae",
175		"00a31789a2ab2d54f8fadd5331010287",
176		"003493c5f520e8d5c0483e895a121dc9",
177		"004706112800b76001ece2e268bc830e",
178		"00ab31e28bb5305be56e38337dbfa486",
179		"006872fe85df6b0fa945248e6f9379d1",
180		"00717e5e375da6934e3cfdf57edaf3bd",
181		"007f1b46e7b9c4c76e77c434b9bccd6b",
182		"00dc93735aa35def3b9a2ff676560205",
183		"002cd5dcd881a49c7b87714c6a570a76",
184		"0013b5af9e13fac87e0c505686cfb6bf",
185		"007ab1ec9526b0bc04b64ae65fd42631",
186		"00abb4e11d8385c1cca905a6a65e9144",
187		"00574fc62a0501ad8afada2e246708c3",
188		"005207e0a815bb2da6b4c35ec1f2bf52",
189		"00f3460f136fb9700080099cbd62bc18",
190		"007a591f204c03ca7b93981237112526",
191		"00cfe0befd428f8e5f83a5bfc801472e",
192		"00987551ac7a879bf0c09b8bc474d9af",
193		"00cadd3ce3d78e49fbc933a85682df3f",
194		"00bfbf2e346c855ccc360d03281455a1",
195		"004cdf55d429d028f715544ce22d4f31",
196		"0075c84a7d15e0ac85e1e41025eed23b",
197		"00807dddd61f71725d336cab844d2cb5",
198		"00422f21b77fe20e367467ed98c18410",
199		"00b44d0ac622907119c626c850a462fd",
200		"00363f5e7f22fc49f3cd662a28956563",
201		"000fe5837e68397bbf58db9f221bdc4e",
202		"0056af33835c888ef0c22599686445d3",
203		"00790a8647fd3dfb38b7e2b6f578f2c6",
204		"00da8d9009675cb7beec930e263014fb",
205		"00d4b384540a5bb54aa760edaa4fb2fe",
206		"00be9b1479ed680fdd5d91a41eb926d0",
207		"009182347502af97077c40a6e74b4b5c",
208		"00f5c90ee1c67fa77fd821f8e9fab4f1",
209		"005568f9a2dd6b0c0cc2f5ba3d9cac38",
210		"008b481f8678577d9cf6aa3f6cd6056b",
211		"00c4323ece5e4fe3b6cd4c5c932931af",
212		"009791f7550c3798c5a214cb2d0ea773",
213		"008a7baab22481f0ad8167dd9f90d55c",
214		"00f0e601519aafdc8ff94975e64c946d",
215		"0083b61e0daa9219df59d697c270cd31",
216	}
217
218	for _, m := range ms {
219		seed, _ := hex.DecodeString(m)
220
221		mnemonic, err := NewMnemonic(seed)
222		if err != nil {
223			t.Errorf("%v", err)
224		}
225
226		_, err = MnemonicToByteArray(mnemonic)
227		if err != nil {
228			t.Errorf("Failed for %x - %v", seed, mnemonic)
229		}
230	}
231}
232func TestEntropyFromMnemonic128(t *testing.T) {
233	testEntropyFromMnemonic(t, 128)
234}
235
236func TestEntropyFromMnemonic160(t *testing.T) {
237	testEntropyFromMnemonic(t, 160)
238}
239
240func TestEntropyFromMnemonic192(t *testing.T) {
241	testEntropyFromMnemonic(t, 192)
242}
243
244func TestEntropyFromMnemonic224(t *testing.T) {
245	testEntropyFromMnemonic(t, 224)
246}
247
248func TestEntropyFromMnemonic256(t *testing.T) {
249	testEntropyFromMnemonic(t, 256)
250}
251
252func TestEntropyFromMnemonicInvalidChecksum(t *testing.T) {
253	_, err := EntropyFromMnemonic("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon yellow")
254	assertEqual(t, ErrChecksumIncorrect, err)
255}
256
257func TestEntropyFromMnemonicInvalidMnemonicSize(t *testing.T) {
258	for _, mnemonic := range []string{
259		"a a a a a a a a a a a a a a a a a a a a a a a a a", // Too many words
260		"a", // Too few
261		"a a a a a a a a a a a a a a", // Not multiple of 3
262	} {
263		_, err := EntropyFromMnemonic(mnemonic)
264		assertEqual(t, ErrInvalidMnemonic, err)
265	}
266}
267
268func testEntropyFromMnemonic(t *testing.T, bitSize int) {
269	for i := 0; i < 512; i++ {
270		expectedEntropy, err := NewEntropy(bitSize)
271		assertNil(t, err)
272		assertTrue(t, len(expectedEntropy) != 0)
273
274		mnemonic, err := NewMnemonic(expectedEntropy)
275		assertNil(t, err)
276		assertTrue(t, len(mnemonic) != 0)
277
278		actualEntropy, err := EntropyFromMnemonic(mnemonic)
279		assertNil(t, err)
280		assertEqualByteSlices(t, expectedEntropy, actualEntropy)
281	}
282}
283
284func testVectors() []vector {
285	return []vector{
286		{
287			entropy:  "00000000000000000000000000000000",
288			mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
289			seed:     "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04",
290		},
291		{
292			entropy:  "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
293			mnemonic: "legal winner thank year wave sausage worth useful legal winner thank yellow",
294			seed:     "2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607",
295		},
296		{
297			entropy:  "80808080808080808080808080808080",
298			mnemonic: "letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
299			seed:     "d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8",
300		},
301		{
302			entropy:  "ffffffffffffffffffffffffffffffff",
303			mnemonic: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
304			seed:     "ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069",
305		},
306		{
307			entropy:  "000000000000000000000000000000000000000000000000",
308			mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
309			seed:     "035895f2f481b1b0f01fcf8c289c794660b289981a78f8106447707fdd9666ca06da5a9a565181599b79f53b844d8a71dd9f439c52a3d7b3e8a79c906ac845fa",
310		},
311		{
312			entropy:  "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
313			mnemonic: "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
314			seed:     "f2b94508732bcbacbcc020faefecfc89feafa6649a5491b8c952cede496c214a0c7b3c392d168748f2d4a612bada0753b52a1c7ac53c1e93abd5c6320b9e95dd",
315		},
316		{
317			entropy:  "808080808080808080808080808080808080808080808080",
318			mnemonic: "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
319			seed:     "107d7c02a5aa6f38c58083ff74f04c607c2d2c0ecc55501dadd72d025b751bc27fe913ffb796f841c49b1d33b610cf0e91d3aa239027f5e99fe4ce9e5088cd65",
320		},
321		{
322			entropy:  "ffffffffffffffffffffffffffffffffffffffffffffffff",
323			mnemonic: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
324			seed:     "0cd6e5d827bb62eb8fc1e262254223817fd068a74b5b449cc2f667c3f1f985a76379b43348d952e2265b4cd129090758b3e3c2c49103b5051aac2eaeb890a528",
325		},
326		{
327			entropy:  "0000000000000000000000000000000000000000000000000000000000000000",
328			mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
329			seed:     "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8",
330		},
331		{
332			entropy:  "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
333			mnemonic: "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
334			seed:     "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87",
335		},
336		{
337			entropy:  "8080808080808080808080808080808080808080808080808080808080808080",
338			mnemonic: "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
339			seed:     "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f",
340		},
341		{
342			entropy:  "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
343			mnemonic: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
344			seed:     "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad",
345		},
346		{
347			entropy:  "77c2b00716cec7213839159e404db50d",
348			mnemonic: "jelly better achieve collect unaware mountain thought cargo oxygen act hood bridge",
349			seed:     "b5b6d0127db1a9d2226af0c3346031d77af31e918dba64287a1b44b8ebf63cdd52676f672a290aae502472cf2d602c051f3e6f18055e84e4c43897fc4e51a6ff",
350		},
351		{
352			entropy:  "b63a9c59a6e641f288ebc103017f1da9f8290b3da6bdef7b",
353			mnemonic: "renew stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap",
354			seed:     "9248d83e06f4cd98debf5b6f010542760df925ce46cf38a1bdb4e4de7d21f5c39366941c69e1bdbf2966e0f6e6dbece898a0e2f0a4c2b3e640953dfe8b7bbdc5",
355		},
356		{
357			entropy:  "3e141609b97933b66a060dcddc71fad1d91677db872031e85f4c015c5e7e8982",
358			mnemonic: "dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic",
359			seed:     "ff7f3184df8696d8bef94b6c03114dbee0ef89ff938712301d27ed8336ca89ef9635da20af07d4175f2bf5f3de130f39c9d9e8dd0472489c19b1a020a940da67",
360		},
361		{
362			entropy:  "0460ef47585604c5660618db2e6a7e7f",
363			mnemonic: "afford alter spike radar gate glance object seek swamp infant panel yellow",
364			seed:     "65f93a9f36b6c85cbe634ffc1f99f2b82cbb10b31edc7f087b4f6cb9e976e9faf76ff41f8f27c99afdf38f7a303ba1136ee48a4c1e7fcd3dba7aa876113a36e4",
365		},
366		{
367			entropy:  "72f60ebac5dd8add8d2a25a797102c3ce21bc029c200076f",
368			mnemonic: "indicate race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left",
369			seed:     "3bbf9daa0dfad8229786ace5ddb4e00fa98a044ae4c4975ffd5e094dba9e0bb289349dbe2091761f30f382d4e35c4a670ee8ab50758d2c55881be69e327117ba",
370		},
371		{
372			entropy:  "2c85efc7f24ee4573d2b81a6ec66cee209b2dcbd09d8eddc51e0215b0b68e416",
373			mnemonic: "clutch control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste",
374			seed:     "fe908f96f46668b2d5b37d82f558c77ed0d69dd0e7e043a5b0511c48c2f1064694a956f86360c93dd04052a8899497ce9e985ebe0c8c52b955e6ae86d4ff4449",
375		},
376		{
377			entropy:  "eaebabb2383351fd31d703840b32e9e2",
378			mnemonic: "turtle front uncle idea crush write shrug there lottery flower risk shell",
379			seed:     "bdfb76a0759f301b0b899a1e3985227e53b3f51e67e3f2a65363caedf3e32fde42a66c404f18d7b05818c95ef3ca1e5146646856c461c073169467511680876c",
380		},
381		{
382			entropy:  "7ac45cfe7722ee6c7ba84fbc2d5bd61b45cb2fe5eb65aa78",
383			mnemonic: "kiss carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment",
384			seed:     "ed56ff6c833c07982eb7119a8f48fd363c4a9b1601cd2de736b01045c5eb8ab4f57b079403485d1c4924f0790dc10a971763337cb9f9c62226f64fff26397c79",
385		},
386		{
387			entropy:  "4fa1a8bc3e6d80ee1316050e862c1812031493212b7ec3f3bb1b08f168cabeef",
388			mnemonic: "exile ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top",
389			seed:     "095ee6f817b4c2cb30a5a797360a81a40ab0f9a4e25ecd672a3f58a0b5ba0687c096a6b14d2c0deb3bdefce4f61d01ae07417d502429352e27695163f7447a8c",
390		},
391		{
392			entropy:  "18ab19a9f54a9274f03e5209a2ac8a91",
393			mnemonic: "board flee heavy tunnel powder denial science ski answer betray cargo cat",
394			seed:     "6eff1bb21562918509c73cb990260db07c0ce34ff0e3cc4a8cb3276129fbcb300bddfe005831350efd633909f476c45c88253276d9fd0df6ef48609e8bb7dca8",
395		},
396		{
397			entropy:  "18a2e1d81b8ecfb2a333adcb0c17a5b9eb76cc5d05db91a4",
398			mnemonic: "board blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief",
399			seed:     "f84521c777a13b61564234bf8f8b62b3afce27fc4062b51bb5e62bdfecb23864ee6ecf07c1d5a97c0834307c5c852d8ceb88e7c97923c0a3b496bedd4e5f88a9",
400		},
401		{
402			entropy:  "15da872c95a13dd738fbf50e427583ad61f18fd99f628c417a61cf8343c90419",
403			mnemonic: "beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut",
404			seed:     "b15509eaa2d09d3efd3e006ef42151b30367dc6e3aa5e44caba3fe4d3e352e65101fbdb86a96776b91946ff06f8eac594dc6ee1d3e82a42dfe1b40fef6bcc3fd",
405		},
406	}
407}
408
409func badMnemonicSentences() []vector {
410	return []vector{
411		{mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"},
412		{mnemonic: "legal winner thank year wave sausage worth useful legal winner thank yellow yellow"},
413		{mnemonic: "letter advice cage absurd amount doctor acoustic avoid letter advice caged above"},
414		{mnemonic: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo, wrong"},
415		{mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"},
416		{mnemonic: "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will will will"},
417		{mnemonic: "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always."},
418		{mnemonic: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo why"},
419		{mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art art"},
420		{mnemonic: "legal winner thank year wave sausage worth useful legal winner thanks year wave worth useful legal winner thank year wave sausage worth title"},
421		{mnemonic: "letter advice cage absurd amount doctor acoustic avoid letters advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless"},
422		{mnemonic: "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo voted"},
423		{mnemonic: "jello better achieve collect unaware mountain thought cargo oxygen act hood bridge"},
424		{mnemonic: "renew, stay, biology, evidence, goat, welcome, casual, join, adapt, armor, shuffle, fault, little, machine, walk, stumble, urge, swap"},
425		{mnemonic: "dignity pass list indicate nasty"},
426	}
427}
428
429func assertNil(t *testing.T, object interface{}) {
430	if object != nil {
431		t.Errorf("Expected nil, got %v", object)
432	}
433}
434
435func assertNotNil(t *testing.T, object interface{}) {
436	if object == nil {
437		t.Error("Expected not nil")
438	}
439}
440
441func assertTrue(t *testing.T, a bool) {
442	if !a {
443		t.Error("Expected true, got false")
444	}
445}
446
447func assertFalse(t *testing.T, a bool) {
448	if a {
449		t.Error("Expected false, got true")
450	}
451}
452
453func assertEqual(t *testing.T, a, b interface{}) {
454	if a != b {
455		t.Errorf("Objects not equal, expected `%s` and got `%s`", a, b)
456	}
457}
458
459func assertEqualString(t *testing.T, a, b string) {
460	if a != b {
461		t.Errorf("Strings not equal, expected `%s` and got `%s`", a, b)
462	}
463}
464
465func assertEqualStringSlices(t *testing.T, a, b []string) {
466	if len(a) != len(b) {
467		t.Errorf("String slices not equal, expected %v and got %v", a, b)
468		return
469	}
470	for i := range a {
471		if a[i] != b[i] {
472			t.Errorf("String slices not equal, expected %v and got %v", a, b)
473			return
474		}
475	}
476}
477
478func assertEqualByteSlices(t *testing.T, a, b []byte) {
479	if len(a) != len(b) {
480		t.Errorf("Byte slices not equal, expected %v and got %v", a, b)
481		return
482	}
483	for i := range a {
484		if a[i] != b[i] {
485			t.Errorf("Byte slices not equal, expected %v and got %v", a, b)
486			return
487		}
488	}
489}
490