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  }