121 lines
3.3 KiB
Go
121 lines
3.3 KiB
Go
package bip39
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/hex"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
// TestEntropyToMnemonicVectors uses the canonical BIP-39 English test vectors,
|
||
|
|
// which the tronpy-adjacent `mnemonic` package also satisfies.
|
||
|
|
func TestEntropyToMnemonicVectors(t *testing.T) {
|
||
|
|
cases := []struct {
|
||
|
|
entropy string
|
||
|
|
mnemonic string
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
"00000000000000000000000000000000",
|
||
|
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
||
|
|
"legal winner thank year wave sausage worth useful legal winner thank yellow",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"80808080808080808080808080808080",
|
||
|
|
"letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"ffffffffffffffffffffffffffffffff",
|
||
|
|
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"000000000000000000000000000000000000000000000000",
|
||
|
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
for _, tc := range cases {
|
||
|
|
entropy, err := hex.DecodeString(tc.entropy)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("decode entropy: %v", err)
|
||
|
|
}
|
||
|
|
got, err := entropyToMnemonic(entropy)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("entropyToMnemonic: %v", err)
|
||
|
|
}
|
||
|
|
if got != tc.mnemonic {
|
||
|
|
t.Fatalf("mnemonic = %q, want %q", got, tc.mnemonic)
|
||
|
|
}
|
||
|
|
if !Validate(got) {
|
||
|
|
t.Fatalf("Validate rejected generated mnemonic %q", got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestValidateRejectsBadChecksum(t *testing.T) {
|
||
|
|
// Replace the final word with a different valid word to break the checksum.
|
||
|
|
bad := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"
|
||
|
|
if Validate(bad) {
|
||
|
|
t.Fatalf("expected invalid checksum")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestValidateRejectsUnknownWord(t *testing.T) {
|
||
|
|
bad := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon notaword"
|
||
|
|
if Validate(bad) {
|
||
|
|
t.Fatalf("expected unknown word rejection")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestValidateRejectsWrongCount(t *testing.T) {
|
||
|
|
if Validate("abandon abandon abandon") {
|
||
|
|
t.Fatalf("expected wrong-count rejection")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestNewMnemonicRoundTrips(t *testing.T) {
|
||
|
|
for _, wc := range []int{12, 15, 18, 21, 24} {
|
||
|
|
m, err := NewMnemonic(wc)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("NewMnemonic(%d): %v", wc, err)
|
||
|
|
}
|
||
|
|
if fields := len(splitFields(m)); fields != wc {
|
||
|
|
t.Fatalf("NewMnemonic(%d) produced %d words", wc, fields)
|
||
|
|
}
|
||
|
|
if !Validate(m) {
|
||
|
|
t.Fatalf("Validate rejected a freshly generated mnemonic")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if _, err := NewMnemonic(13); err == nil {
|
||
|
|
t.Fatalf("expected error for unsupported word count")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestWordlistShape(t *testing.T) {
|
||
|
|
if got := len(Words()); got != 2048 {
|
||
|
|
t.Fatalf("wordlist size = %d, want 2048", got)
|
||
|
|
}
|
||
|
|
if !ValidWordCount(12) || ValidWordCount(13) {
|
||
|
|
t.Fatalf("ValidWordCount misreported")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// splitFields is a tiny local helper to avoid importing strings twice.
|
||
|
|
func splitFields(s string) []string {
|
||
|
|
var out []string
|
||
|
|
cur := ""
|
||
|
|
for i := 0; i < len(s); i++ {
|
||
|
|
if s[i] == ' ' {
|
||
|
|
if cur != "" {
|
||
|
|
out = append(out, cur)
|
||
|
|
cur = ""
|
||
|
|
}
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
cur += string(s[i])
|
||
|
|
}
|
||
|
|
if cur != "" {
|
||
|
|
out = append(out, cur)
|
||
|
|
}
|
||
|
|
return out
|
||
|
|
}
|