91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
package crypto
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"github.com/anytypeio/go-slip10"
|
|
"github.com/tyler-smith/go-bip39"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidWordCount = errors.New("error invalid word count for mnemonic")
|
|
ErrInvalidMnemonic = errors.New("error invalid mnemonic")
|
|
)
|
|
|
|
type MnemonicGenerator struct {
|
|
mnemonic string
|
|
}
|
|
|
|
func NewMnemonicGenerator() MnemonicGenerator {
|
|
return MnemonicGenerator{}
|
|
}
|
|
|
|
type Mnemonic string
|
|
|
|
func (g MnemonicGenerator) WithWordCount(wc int) (Mnemonic, error) {
|
|
size := 0
|
|
switch wc {
|
|
case 12:
|
|
size = 128
|
|
case 15:
|
|
size = 160
|
|
case 18:
|
|
size = 192
|
|
case 21:
|
|
size = 224
|
|
case 24:
|
|
size = 256
|
|
default:
|
|
return "", ErrInvalidWordCount
|
|
}
|
|
return g.WithRandomEntropy(size)
|
|
}
|
|
|
|
func (g MnemonicGenerator) WithRandomEntropy(size int) (Mnemonic, error) {
|
|
entropy, err := bip39.NewEntropy(size)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
mnemonic, err := bip39.NewMnemonic(entropy)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return Mnemonic(mnemonic), nil
|
|
}
|
|
|
|
func (g MnemonicGenerator) WithEntropy(b []byte) (Mnemonic, error) {
|
|
mnemonic, err := bip39.NewMnemonic(b)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return Mnemonic(mnemonic), nil
|
|
}
|
|
|
|
func (m Mnemonic) DeriveEd25519Key(index int) (PrivKey, error) {
|
|
seed, err := bip39.NewSeedWithErrorChecking(string(m), "")
|
|
if err != nil {
|
|
if err == bip39.ErrInvalidMnemonic {
|
|
return nil, ErrInvalidMnemonic
|
|
}
|
|
return nil, err
|
|
}
|
|
masterKey, err := slip10.DeriveForPath(AnytypeAccountPrefix, seed)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
key, err := masterKey.Derive(slip10.FirstHardenedIndex + uint32(index))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
reader := bytes.NewReader(key.RawSeed())
|
|
privKey, _, err := GenerateEd25519Key(reader)
|
|
|
|
return privKey, err
|
|
}
|
|
|
|
func (m Mnemonic) Bytes() ([]byte, error) {
|
|
return bip39.MnemonicToByteArray(string(m), true)
|
|
}
|