github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/crypto/ledger_mock.go (about) 1 //go:build ledger && test_ledger_mock 2 // +build ledger,test_ledger_mock 3 4 package crypto 5 6 import ( 7 "fmt" 8 9 "github.com/btcsuite/btcd/btcec" 10 "github.com/pkg/errors" 11 12 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 13 tmsecp256k1 "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1" 14 secp256k1 "github.com/tendermint/btcd/btcec" 15 16 bip39 "github.com/cosmos/go-bip39" 17 18 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys/hd" 19 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/tests" 20 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 21 ) 22 23 // If ledger support (build tag) has been enabled, which implies a CGO dependency, 24 // set the discoverLedger function which is responsible for loading the Ledger 25 // device at runtime or returning an error. 26 func init() { 27 discoverLedger = func() (LedgerSECP256K1, error) { 28 return LedgerSECP256K1Mock{}, nil 29 } 30 } 31 32 type LedgerSECP256K1Mock struct { 33 } 34 35 func (mock LedgerSECP256K1Mock) Close() error { 36 return nil 37 } 38 39 // GetPublicKeySECP256K1 mocks a ledger device 40 // as per the original API, it returns an uncompressed key 41 func (mock LedgerSECP256K1Mock) GetPublicKeySECP256K1(derivationPath []uint32) ([]byte, error) { 42 if derivationPath[0] != 44 { 43 return nil, errors.New("Invalid derivation path") 44 } 45 46 if derivationPath[1] != sdk.GetConfig().GetCoinType() { 47 return nil, errors.New("Invalid derivation path") 48 } 49 50 seed, err := bip39.NewSeedWithErrorChecking(tests.TestMnemonic, "") 51 if err != nil { 52 return nil, err 53 } 54 55 path := hd.NewParams(derivationPath[0], derivationPath[1], derivationPath[2], derivationPath[3] != 0, derivationPath[4]) 56 masterPriv, ch := hd.ComputeMastersFromSeed(seed) 57 derivedPriv, err := hd.DerivePrivateKeyForPath(masterPriv, ch, path.String()) 58 if err != nil { 59 return nil, err 60 } 61 62 _, pubkeyObject := secp256k1.PrivKeyFromBytes(secp256k1.S256(), derivedPriv[:]) 63 64 return pubkeyObject.SerializeUncompressed(), nil 65 } 66 67 // GetAddressPubKeySECP256K1 mocks a ledger device 68 // as per the original API, it returns a compressed key and a bech32 address 69 func (mock LedgerSECP256K1Mock) GetAddressPubKeySECP256K1(derivationPath []uint32, hrp string) ([]byte, string, error) { 70 pk, err := mock.GetPublicKeySECP256K1(derivationPath) 71 if err != nil { 72 return nil, "", err 73 } 74 75 // re-serialize in the 33-byte compressed format 76 cmp, err := btcec.ParsePubKey(pk[:], btcec.S256()) 77 if err != nil { 78 return nil, "", fmt.Errorf("error parsing public key: %v", err) 79 } 80 81 var compressedPublicKey tmsecp256k1.PubKeySecp256k1 82 copy(compressedPublicKey[:], cmp.SerializeCompressed()) 83 84 // Generate the bech32 addr using existing tmcrypto/etc. 85 addr := sdk.AccAddress(compressedPublicKey.Address()).String() 86 return pk, addr, err 87 } 88 89 func (mock LedgerSECP256K1Mock) SignSECP256K1(derivationPath []uint32, message []byte) ([]byte, error) { 90 path := hd.NewParams(derivationPath[0], derivationPath[1], derivationPath[2], derivationPath[3] != 0, derivationPath[4]) 91 seed, err := bip39.NewSeedWithErrorChecking(tests.TestMnemonic, "") 92 if err != nil { 93 return nil, err 94 } 95 96 masterPriv, ch := hd.ComputeMastersFromSeed(seed) 97 derivedPriv, err := hd.DerivePrivateKeyForPath(masterPriv, ch, path.String()) 98 if err != nil { 99 return nil, err 100 } 101 102 priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), derivedPriv[:]) 103 104 sig, err := priv.Sign(crypto.Sha256(message)) 105 if err != nil { 106 return nil, err 107 } 108 109 // Need to return DER as the ledger does 110 sig2 := btcec.Signature{R: sig.R, S: sig.S} 111 return sig2.Serialize(), nil 112 } 113 114 // ShowAddressSECP256K1 shows the address for the corresponding bip32 derivation path 115 func (mock LedgerSECP256K1Mock) ShowAddressSECP256K1(bip32Path []uint32, hrp string) error { 116 fmt.Printf("Request to show address for %v at %v", hrp, bip32Path) 117 return nil 118 }