-
-
Notifications
You must be signed in to change notification settings - Fork 25
/
bip39.go
67 lines (57 loc) · 1.54 KB
/
bip39.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package encoding
import (
"strings"
"github.com/pkg/errors"
"github.com/tyler-smith/go-bip39"
)
// ErrInvalidPhrase if phrase is invalid.
type ErrInvalidPhrase struct {
cause error
}
// ErrInvalidBIP39Input if invalid number of bytes for encoding.
var ErrInvalidBIP39Input = errors.New("bip39 only accepts 16, 20, 24, 28, 32 bytes")
func (e ErrInvalidPhrase) Error() string {
return "invalid phrase"
}
// Cause for ErrInvalidPhrase
func (e ErrInvalidPhrase) Cause() error {
return e.cause
}
// BytesToPhrase returns a phrase for bytes
func BytesToPhrase(b []byte) (string, error) {
out, err := bip39.NewMnemonic(b)
if err != nil {
if err == bip39.ErrEntropyLengthInvalid {
return "", ErrInvalidBIP39Input
}
return "", err
}
return out, nil
}
// PhraseToBytes decodes a bip39 mnemonic into bytes
func PhraseToBytes(phrase string, sanitize bool) (*[32]byte, error) {
if sanitize {
phrase = sanitizePhrase(phrase)
}
b, err := bip39.MnemonicToByteArray(phrase, true)
if err != nil {
return nil, ErrInvalidPhrase{cause: err}
}
if l := len(b); l != 32 {
return nil, ErrInvalidPhrase{cause: errors.Errorf("invalid bip39 bytes length")}
}
var b32 [32]byte
copy(b32[:], b[:32])
return &b32, nil
}
func sanitizePhrase(phrase string) string {
phrase = strings.TrimSpace(strings.ToLower(phrase))
return strings.Join(strings.Fields(phrase), " ")
}
// IsValidPhrase checks is phrase is valid
func IsValidPhrase(phrase string, sanitize bool) bool {
if sanitize {
phrase = sanitizePhrase(phrase)
}
return bip39.IsMnemonicValid(phrase)
}