github.com/InjectiveLabs/sdk-go@v1.53.0/chain/crypto/hd/algorithm.go (about) 1 package hd 2 3 import ( 4 "github.com/btcsuite/btcd/btcutil/hdkeychain" 5 "github.com/btcsuite/btcd/chaincfg" 6 "github.com/cosmos/cosmos-sdk/crypto/hd" 7 cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 8 ethaccounts "github.com/ethereum/go-ethereum/accounts" 9 ethcrypto "github.com/ethereum/go-ethereum/crypto" 10 "github.com/tyler-smith/go-bip39" 11 12 "github.com/cosmos/cosmos-sdk/crypto/keyring" 13 14 "github.com/InjectiveLabs/sdk-go/chain/crypto/ethsecp256k1" 15 ) 16 17 const ( 18 // EthSecp256k1Type defines the ECDSA secp256k1 used on Ethereum 19 EthSecp256k1Type = hd.PubKeyType(ethsecp256k1.KeyType) 20 ) 21 22 var ( 23 // SupportedAlgorithms defines the list of signing algorithms used on Ethermint: 24 // - eth_secp256k1 (Ethereum) 25 // - secp256k1 (Tendermint) 26 SupportedAlgorithms = keyring.SigningAlgoList{EthSecp256k1, hd.Secp256k1} 27 // SupportedAlgorithmsLedger defines the list of signing algorithms used on Ethermint for the Ledger device: 28 // - eth_secp256k1 (Ethereum) 29 // - secp256k1 (Tendermint) 30 SupportedAlgorithmsLedger = keyring.SigningAlgoList{EthSecp256k1, hd.Secp256k1} 31 ) 32 33 // EthSecp256k1Option defines a function keys options for the ethereum Secp256k1 curve. 34 func EthSecp256k1Option() keyring.Option { 35 return func(options *keyring.Options) { 36 options.SupportedAlgos = SupportedAlgorithms 37 options.SupportedAlgosLedger = SupportedAlgorithmsLedger 38 } 39 } 40 41 var ( 42 _ keyring.SignatureAlgo = EthSecp256k1 43 44 // EthSecp256k1 uses the Bitcoin secp256k1 ECDSA parameters. 45 EthSecp256k1 = ethSecp256k1Algo{} 46 ) 47 48 type ethSecp256k1Algo struct { 49 } 50 51 // Name returns eth_secp256k1 52 func (s ethSecp256k1Algo) Name() hd.PubKeyType { 53 return EthSecp256k1Type 54 } 55 56 // Derive derives and returns the eth_secp256k1 private key for the given mnemonic and HD path. 57 func (s ethSecp256k1Algo) Derive() hd.DeriveFn { 58 return func(mnemonic string, bip39Passphrase, path string) ([]byte, error) { 59 hdpath, err := ethaccounts.ParseDerivationPath(path) 60 if err != nil { 61 return nil, err 62 } 63 64 seed, err := bip39.NewSeedWithErrorChecking(mnemonic, bip39Passphrase) 65 if err != nil { 66 return nil, err 67 } 68 69 masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) 70 if err != nil { 71 return nil, err 72 } 73 74 key := masterKey 75 // todo: Child method incompatible, see 76 // https://pkg.go.dev/github.com/btcsuite/btcd/btcutil/hdkeychain@v1.1.2#ExtendedKey.Derive:~:text=the%20given%20index.-,IMPORTANT,-%3A%20if%20you%20were 77 for _, n := range hdpath { 78 key, err = key.Derive(n) 79 if err != nil { 80 return nil, err 81 } 82 } 83 84 privateKey, err := key.ECPrivKey() 85 if err != nil { 86 return nil, err 87 } 88 89 privateKeyECDSA := privateKey.ToECDSA() 90 derivedKey := ethcrypto.FromECDSA(privateKeyECDSA) 91 92 return derivedKey, nil 93 } 94 } 95 96 // Generate generates a secp256k1 private key from the given bytes. 97 func (s ethSecp256k1Algo) Generate() hd.GenerateFn { 98 return func(bz []byte) cryptotypes.PrivKey { 99 var bzArr = make([]byte, ethsecp256k1.PrivKeySize) 100 copy(bzArr, bz) 101 102 return ðsecp256k1.PrivKey{Key: bzArr} 103 } 104 }