github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/crypto/hd/algorithm.go (about) 1 package hd 2 3 import ( 4 "github.com/pkg/errors" 5 6 "github.com/btcsuite/btcd/chaincfg" 7 "github.com/btcsuite/btcutil/hdkeychain" 8 "github.com/tyler-smith/go-bip39" 9 10 ethaccounts "github.com/ethereum/go-ethereum/accounts" 11 ethcrypto "github.com/ethereum/go-ethereum/crypto" 12 13 tmcrypto "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 14 15 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys" 16 17 "github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1" 18 ) 19 20 const ( 21 // EthSecp256k1 defines the ECDSA secp256k1 used on Ethereum 22 EthSecp256k1 = keys.SigningAlgo(ethsecp256k1.KeyType) 23 ) 24 25 // SupportedAlgorithms defines the list of signing algorithms used on Ethermint: 26 // - eth_secp256k1 (Ethereum) 27 // - secp256k1 (Tendermint) 28 var SupportedAlgorithms = []keys.SigningAlgo{EthSecp256k1, keys.Secp256k1} 29 30 // EthSecp256k1Options defines a keys options for the ethereum Secp256k1 curve. 31 func EthSecp256k1Options() []keys.KeybaseOption { 32 return []keys.KeybaseOption{ 33 keys.WithKeygenFunc(EthermintKeygenFunc), 34 keys.WithDeriveFunc(DeriveKey), 35 keys.WithSupportedAlgos(SupportedAlgorithms), 36 keys.WithSupportedAlgosLedger(SupportedAlgorithms), 37 } 38 } 39 40 func DeriveKey(mnemonic, bip39Passphrase, hdPath string, algo keys.SigningAlgo) ([]byte, error) { 41 switch algo { 42 case keys.Secp256k1: 43 return keys.StdDeriveKey(mnemonic, bip39Passphrase, hdPath, algo) 44 case EthSecp256k1: 45 return DeriveSecp256k1(mnemonic, bip39Passphrase, hdPath) 46 default: 47 return nil, errors.Wrap(keys.ErrUnsupportedSigningAlgo, string(algo)) 48 } 49 } 50 51 // EthermintKeygenFunc is the key generation function to generate secp256k1. 52 func EthermintKeygenFunc(bz []byte, algo keys.SigningAlgo) (tmcrypto.PrivKey, error) { 53 switch algo { 54 case keys.Secp256k1: 55 return keys.StdPrivKeyGen(bz, algo) 56 case EthSecp256k1: 57 return ethsecp256k1.PrivKey(bz), nil 58 default: 59 return nil, errors.Wrap(keys.ErrUnsupportedSigningAlgo, string(algo)) 60 } 61 } 62 63 // DeriveSecp256k1 derives and returns the eth_secp256k1 private key for the given mnemonic and HD path. 64 func DeriveSecp256k1(mnemonic, bip39Passphrase, path string) ([]byte, error) { 65 hdpath, err := ethaccounts.ParseDerivationPath(path) 66 if err != nil { 67 return nil, err 68 } 69 70 seed, err := bip39.NewSeedWithErrorChecking(mnemonic, bip39Passphrase) 71 if err != nil { 72 return nil, err 73 } 74 75 masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) 76 if err != nil { 77 return nil, err 78 } 79 80 key := masterKey 81 for _, n := range hdpath { 82 key, err = key.Derive(n) 83 if err != nil { 84 return nil, err 85 } 86 } 87 88 privateKey, err := key.ECPrivKey() 89 if err != nil { 90 return nil, err 91 } 92 93 privateKeyECDSA := privateKey.ToECDSA() 94 derivedKey := ethsecp256k1.PrivKey(ethcrypto.FromECDSA(privateKeyECDSA)) 95 return derivedKey, nil 96 }