From 407c9d316cb3f3588199339c10957c0764611a65 Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 27 Mar 2023 01:34:51 +0200 Subject: [PATCH] Add mnemonic --- go.mod | 16 ++++---- go.sum | 13 ++---- util/crypto/derived.go | 10 ++++- util/crypto/mnemonic.go | 90 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 20 deletions(-) create mode 100644 util/crypto/mnemonic.go diff --git a/go.mod b/go.mod index 58598953..769f49a0 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,12 @@ module github.com/anytypeio/any-sync go 1.19 require ( + filippo.io/edwards25519 v1.0.0 github.com/anytypeio/go-chash v0.0.2 - github.com/awalterschulze/gographviz v2.0.3+incompatible + github.com/anytypeio/go-slip10 v0.0.0-20200330112030-a352ca8495e4 + github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51 github.com/cespare/xxhash v1.1.0 github.com/cheggaaa/mb/v3 v3.0.1 - github.com/ethereum/go-ethereum v1.11.5 github.com/gobwas/glob v0.2.3 github.com/goccy/go-graphviz v0.1.0 github.com/gogo/protobuf v1.3.2 @@ -23,28 +24,25 @@ require ( github.com/ipfs/go-merkledag v0.10.0 github.com/ipfs/go-unixfs v0.4.4 github.com/libp2p/go-libp2p v0.24.1 - github.com/minio/sha256-simd v1.0.0 github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multihash v0.2.1 github.com/prometheus/client_golang v1.14.0 github.com/stretchr/testify v1.8.2 + github.com/tyler-smith/go-bip39 v1.1.0 github.com/zeebo/blake3 v0.2.3 github.com/zeebo/errs v1.3.0 go.uber.org/zap v1.24.0 + golang.org/x/crypto v0.4.0 golang.org/x/exp v0.0.0-20230206171751-46f607a40771 golang.org/x/net v0.8.0 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 - gopkg.in/yaml.v3 v3.0.1 storj.io/drpc v0.0.32 ) require ( - filippo.io/edwards25519 v1.0.0 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect - github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -57,7 +55,6 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/holiman/uint256 v1.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -81,6 +78,7 @@ require ( github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-pointer v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr v0.8.0 // indirect @@ -102,11 +100,11 @@ require ( go.opentelemetry.io/otel/trace v1.11.2 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.4.0 // indirect golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/go.sum b/go.sum index 28cff006..42f7b6e7 100644 --- a/go.sum +++ b/go.sum @@ -7,17 +7,14 @@ github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5K github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/anytypeio/go-chash v0.0.2 h1:BSpyMC3HXNkf2eosQrHM4svov0DrvxL9tb4gnHbdmbA= github.com/anytypeio/go-chash v0.0.2/go.mod h1:G+R6q7jYgNa52NqcRhnNm28pogfWW+cuHtgBktrc2QA= +github.com/anytypeio/go-slip10 v0.0.0-20200330112030-a352ca8495e4 h1:jB5Ke7NVoW52i65PtLFBr5Q5k6RskIY8L70pgnBcnWo= +github.com/anytypeio/go-slip10 v0.0.0-20200330112030-a352ca8495e4/go.mod h1:/8GIEJBE5wmdgcE49JPdupnHNUf7bEn6C+aArfWqvw8= github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51 h1:3Y+18zBC8LZgcL3l2dgoTEIzIUzCZa/kN0UV3ZWpbuA= github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51/go.mod h1:SoKy+W8Mf6v7XBV30xFWkIFMs7UnXwsNGrGV12yVkEs= -github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= -github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= -github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -38,8 +35,6 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6Uh github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -github.com/ethereum/go-ethereum v1.11.5 h1:3M1uan+LAUvdn+7wCEFrcMM4LJTeuxDrPTg/f31a5QQ= -github.com/ethereum/go-ethereum v1.11.5/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -81,8 +76,6 @@ github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfm github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= @@ -297,6 +290,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= diff --git a/util/crypto/derived.go b/util/crypto/derived.go index 1c3dbe93..62851296 100644 --- a/util/crypto/derived.go +++ b/util/crypto/derived.go @@ -1,9 +1,15 @@ package crypto -import "github.com/anytypeio/go-slip21" +import ( + "github.com/anytypeio/go-slip21" +) -const AnytypeAccountPath = "m/SLIP-0021/anytype/account" +const ( + AnytypeAccountPath = "m/SLIP-0021/anytype/account" + AnytypeAccountPrefix = "m/44'/607'" +) +// DeriveSymmetricKey derives a symmetric key from seed and path using slip-21 func DeriveSymmetricKey(seed []byte, path string) (SymKey, error) { master, err := slip21.DeriveForPath(path, seed) if err != nil { diff --git a/util/crypto/mnemonic.go b/util/crypto/mnemonic.go new file mode 100644 index 00000000..4f184bfb --- /dev/null +++ b/util/crypto/mnemonic.go @@ -0,0 +1,90 @@ +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.WithWordCount(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) +}