github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/crypto/keys/types.go (about)

     1  package keys
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
     7  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/multisig"
     8  
     9  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys/hd"
    10  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    11  )
    12  
    13  // Keybase exposes operations on a generic keystore
    14  type Keybase interface {
    15  	// CRUD on the keystore
    16  	List() ([]Info, error)
    17  	// Get returns the public information about one key.
    18  	Get(name string) (Info, error)
    19  	// Get performs a by-address lookup and returns the public
    20  	// information about one key if there's any.
    21  	GetByAddress(address types.AccAddress) (Info, error)
    22  	// Delete removes a key.
    23  	Delete(name, passphrase string, skipPass bool) error
    24  	// Sign bytes, looking up the private key to use.
    25  	Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)
    26  
    27  	// CreateMnemonic generates a new mnemonic, derives a hierarchical deterministic
    28  	// key from that. and persists it to storage, encrypted using the provided password.
    29  	// It returns the generated mnemonic and the key Info. It returns an error if it fails to
    30  	// generate a key for the given algo type, or if another key is already stored under the
    31  	// same name.
    32  	CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo, mnemonic string) (info Info, seed string, err error)
    33  
    34  	// CreateMnemonicWithHDPath generates a new mnemonic, derives a hierarchical deterministic
    35  	// key from that. and persists it to storage, encrypted using the provided password.
    36  	// It returns the generated mnemonic and the key Info. It returns an error if it fails to
    37  	// generate a key for the given algo type, or if another key is already stored under the
    38  	// same name.
    39  	CreateMnemonicWithHDPath(name string, language Language, passwd string, algo SigningAlgo, mnemonic string, hdPath string) (info Info, seed string, err error)
    40  
    41  	// CreateAccount converts a mnemonic to a private key and BIP 32 HD Path
    42  	// and persists it, encrypted with the given password.
    43  	CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, hdPath string, algo SigningAlgo) (Info, error)
    44  
    45  	// CreateLedger creates, stores, and returns a new Ledger key reference
    46  	CreateLedger(name string, algo SigningAlgo, hrp string, account, index uint32) (info Info, err error)
    47  
    48  	// CreateOffline creates, stores, and returns a new offline key reference
    49  	CreateOffline(name string, pubkey crypto.PubKey, algo SigningAlgo) (info Info, err error)
    50  
    51  	// CreateMulti creates, stores, and returns a new multsig (offline) key reference
    52  	CreateMulti(name string, pubkey crypto.PubKey) (info Info, err error)
    53  
    54  	// The following operations will *only* work on locally-stored keys
    55  	Update(name, oldpass string, getNewpass func() (string, error)) error
    56  
    57  	// Import imports ASCII armored Info objects.
    58  	Import(name string, armor string) (err error)
    59  
    60  	// ImportPrivKey imports a private key in ASCII armor format.
    61  	// It returns an error if a key with the same name exists or a wrong encryption passphrase is
    62  	// supplied.
    63  	ImportPrivKey(name, armor, passphrase string) error
    64  
    65  	// ImportPubKey imports ASCII-armored public keys.
    66  	// Store a new Info object holding a public key only, i.e. it will
    67  	// not be possible to sign with it as it lacks the secret key.
    68  	ImportPubKey(name string, armor string) (err error)
    69  
    70  	// Export exports an Info object in ASCII armored format.
    71  	Export(name string) (armor string, err error)
    72  
    73  	// ExportPubKey returns public keys in ASCII armored format.
    74  	// Retrieve a Info object by its name and return the public key in
    75  	// a portable format.
    76  	ExportPubKey(name string) (armor string, err error)
    77  
    78  	// ExportPrivKey returns a private key in ASCII armored format.
    79  	// It returns an error if the key does not exist or a wrong encryption passphrase is supplied.
    80  	ExportPrivKey(name, decryptPassphrase, encryptPassphrase string) (armor string, err error)
    81  
    82  	// ExportPrivateKeyObject *only* works on locally-stored keys. Temporary method until we redo the exporting API
    83  	ExportPrivateKeyObject(name string, passphrase string) (crypto.PrivKey, error)
    84  
    85  	// SupportedAlgos returns a list of signing algorithms supported by the keybase
    86  	SupportedAlgos() []SigningAlgo
    87  
    88  	// SupportedAlgosLedger returns a list of signing algorithms supported by the keybase's ledger integration
    89  	SupportedAlgosLedger() []SigningAlgo
    90  
    91  	// CloseDB closes the database.
    92  	CloseDB()
    93  
    94  	//FileDir show where keybase storage a new key
    95  	FileDir() (string, error)
    96  }
    97  
    98  // KeyType reflects a human-readable type for key listing.
    99  type KeyType uint
   100  
   101  // Info KeyTypes
   102  const (
   103  	TypeLocal   KeyType = 0
   104  	TypeLedger  KeyType = 1
   105  	TypeOffline KeyType = 2
   106  	TypeMulti   KeyType = 3
   107  )
   108  
   109  var keyTypes = map[KeyType]string{
   110  	TypeLocal:   "local",
   111  	TypeLedger:  "ledger",
   112  	TypeOffline: "offline",
   113  	TypeMulti:   "multi",
   114  }
   115  
   116  // String implements the stringer interface for KeyType.
   117  func (kt KeyType) String() string {
   118  	return keyTypes[kt]
   119  }
   120  
   121  // Info is the publicly exposed information about a keypair
   122  type Info interface {
   123  	// Human-readable type for key listing
   124  	GetType() KeyType
   125  	// Name of the key
   126  	GetName() string
   127  	// Public key
   128  	GetPubKey() crypto.PubKey
   129  	// Address
   130  	GetAddress() types.AccAddress
   131  	// Bip44 Path
   132  	GetPath() (*hd.BIP44Params, error)
   133  	// Algo
   134  	GetAlgo() SigningAlgo
   135  }
   136  
   137  var (
   138  	_ Info = &localInfo{}
   139  	_ Info = &ledgerInfo{}
   140  	_ Info = &offlineInfo{}
   141  	_ Info = &multiInfo{}
   142  )
   143  
   144  // localInfo is the public information about a locally stored key
   145  // Note: Algo must be last field in struct for backwards amino compatibility
   146  type localInfo struct {
   147  	Name         string        `json:"name"`
   148  	PubKey       crypto.PubKey `json:"pubkey"`
   149  	PrivKeyArmor string        `json:"privkey.armor"`
   150  	Algo         SigningAlgo   `json:"algo"`
   151  }
   152  
   153  func newLocalInfo(name string, pub crypto.PubKey, privArmor string, algo SigningAlgo) Info {
   154  	return &localInfo{
   155  		Name:         name,
   156  		PubKey:       pub,
   157  		PrivKeyArmor: privArmor,
   158  		Algo:         algo,
   159  	}
   160  }
   161  
   162  // GetType implements Info interface
   163  func (i localInfo) GetType() KeyType {
   164  	return TypeLocal
   165  }
   166  
   167  // GetType implements Info interface
   168  func (i localInfo) GetName() string {
   169  	return i.Name
   170  }
   171  
   172  // GetType implements Info interface
   173  func (i localInfo) GetPubKey() crypto.PubKey {
   174  	return i.PubKey
   175  }
   176  
   177  // GetType implements Info interface
   178  func (i localInfo) GetAddress() types.AccAddress {
   179  	return i.PubKey.Address().Bytes()
   180  }
   181  
   182  // GetType implements Info interface
   183  func (i localInfo) GetAlgo() SigningAlgo {
   184  	return i.Algo
   185  }
   186  
   187  // GetType implements Info interface
   188  func (i localInfo) GetPath() (*hd.BIP44Params, error) {
   189  	return nil, fmt.Errorf("BIP44 Paths are not available for this type")
   190  }
   191  
   192  // ledgerInfo is the public information about a Ledger key
   193  // Note: Algo must be last field in struct for backwards amino compatibility
   194  type ledgerInfo struct {
   195  	Name   string         `json:"name"`
   196  	PubKey crypto.PubKey  `json:"pubkey"`
   197  	Path   hd.BIP44Params `json:"path"`
   198  	Algo   SigningAlgo    `json:"algo"`
   199  }
   200  
   201  func newLedgerInfo(name string, pub crypto.PubKey, path hd.BIP44Params, algo SigningAlgo) Info {
   202  	return &ledgerInfo{
   203  		Name:   name,
   204  		PubKey: pub,
   205  		Path:   path,
   206  		Algo:   algo,
   207  	}
   208  }
   209  
   210  // GetType implements Info interface
   211  func (i ledgerInfo) GetType() KeyType {
   212  	return TypeLedger
   213  }
   214  
   215  // GetName implements Info interface
   216  func (i ledgerInfo) GetName() string {
   217  	return i.Name
   218  }
   219  
   220  // GetPubKey implements Info interface
   221  func (i ledgerInfo) GetPubKey() crypto.PubKey {
   222  	return i.PubKey
   223  }
   224  
   225  // GetAddress implements Info interface
   226  func (i ledgerInfo) GetAddress() types.AccAddress {
   227  	return i.PubKey.Address().Bytes()
   228  }
   229  
   230  // GetPath implements Info interface
   231  func (i ledgerInfo) GetAlgo() SigningAlgo {
   232  	return i.Algo
   233  }
   234  
   235  // GetPath implements Info interface
   236  func (i ledgerInfo) GetPath() (*hd.BIP44Params, error) {
   237  	tmp := i.Path
   238  	return &tmp, nil
   239  }
   240  
   241  // offlineInfo is the public information about an offline key
   242  // Note: Algo must be last field in struct for backwards amino compatibility
   243  type offlineInfo struct {
   244  	Name   string        `json:"name"`
   245  	PubKey crypto.PubKey `json:"pubkey"`
   246  	Algo   SigningAlgo   `json:"algo"`
   247  }
   248  
   249  func newOfflineInfo(name string, pub crypto.PubKey, algo SigningAlgo) Info {
   250  	return &offlineInfo{
   251  		Name:   name,
   252  		PubKey: pub,
   253  		Algo:   algo,
   254  	}
   255  }
   256  
   257  // GetType implements Info interface
   258  func (i offlineInfo) GetType() KeyType {
   259  	return TypeOffline
   260  }
   261  
   262  // GetName implements Info interface
   263  func (i offlineInfo) GetName() string {
   264  	return i.Name
   265  }
   266  
   267  // GetPubKey implements Info interface
   268  func (i offlineInfo) GetPubKey() crypto.PubKey {
   269  	return i.PubKey
   270  }
   271  
   272  // GetAlgo returns the signing algorithm for the key
   273  func (i offlineInfo) GetAlgo() SigningAlgo {
   274  	return i.Algo
   275  }
   276  
   277  // GetAddress implements Info interface
   278  func (i offlineInfo) GetAddress() types.AccAddress {
   279  	return i.PubKey.Address().Bytes()
   280  }
   281  
   282  // GetPath implements Info interface
   283  func (i offlineInfo) GetPath() (*hd.BIP44Params, error) {
   284  	return nil, fmt.Errorf("BIP44 Paths are not available for this type")
   285  }
   286  
   287  type multisigPubKeyInfo struct {
   288  	PubKey crypto.PubKey `json:"pubkey"`
   289  	Weight uint          `json:"weight"`
   290  }
   291  
   292  // multiInfo is the public information about a multisig key
   293  type multiInfo struct {
   294  	Name      string               `json:"name"`
   295  	PubKey    crypto.PubKey        `json:"pubkey"`
   296  	Threshold uint                 `json:"threshold"`
   297  	PubKeys   []multisigPubKeyInfo `json:"pubkeys"`
   298  }
   299  
   300  // NewMultiInfo creates a new multiInfo instance
   301  func NewMultiInfo(name string, pub crypto.PubKey) Info {
   302  	multiPK := pub.(multisig.PubKeyMultisigThreshold)
   303  
   304  	pubKeys := make([]multisigPubKeyInfo, len(multiPK.PubKeys))
   305  	for i, pk := range multiPK.PubKeys {
   306  		// TODO: Recursively check pk for total weight?
   307  		pubKeys[i] = multisigPubKeyInfo{pk, 1}
   308  	}
   309  
   310  	return &multiInfo{
   311  		Name:      name,
   312  		PubKey:    pub,
   313  		Threshold: multiPK.K,
   314  		PubKeys:   pubKeys,
   315  	}
   316  }
   317  
   318  // GetType implements Info interface
   319  func (i multiInfo) GetType() KeyType {
   320  	return TypeMulti
   321  }
   322  
   323  // GetName implements Info interface
   324  func (i multiInfo) GetName() string {
   325  	return i.Name
   326  }
   327  
   328  // GetPubKey implements Info interface
   329  func (i multiInfo) GetPubKey() crypto.PubKey {
   330  	return i.PubKey
   331  }
   332  
   333  // GetAddress implements Info interface
   334  func (i multiInfo) GetAddress() types.AccAddress {
   335  	return i.PubKey.Address().Bytes()
   336  }
   337  
   338  // GetPath implements Info interface
   339  func (i multiInfo) GetAlgo() SigningAlgo {
   340  	return MultiAlgo
   341  }
   342  
   343  // GetPath implements Info interface
   344  func (i multiInfo) GetPath() (*hd.BIP44Params, error) {
   345  	return nil, fmt.Errorf("BIP44 Paths are not available for this type")
   346  }
   347  
   348  // encoding info
   349  func marshalInfo(i Info) []byte {
   350  	return CryptoCdc.MustMarshalBinaryLengthPrefixed(i)
   351  }
   352  
   353  // decoding info
   354  func unmarshalInfo(bz []byte) (info Info, err error) {
   355  	err = CryptoCdc.UnmarshalBinaryLengthPrefixed(bz, &info)
   356  	return
   357  }
   358  
   359  type (
   360  	// DeriveKeyFunc defines the function to derive a new key from a seed and hd path
   361  	DeriveKeyFunc func(mnemonic string, bip39Passphrase, hdPath string, algo SigningAlgo) ([]byte, error)
   362  	// PrivKeyGenFunc defines the function to convert derived key bytes to a tendermint private key
   363  	PrivKeyGenFunc func(bz []byte, algo SigningAlgo) (crypto.PrivKey, error)
   364  
   365  	// KeybaseOption overrides options for the db
   366  	KeybaseOption func(*kbOptions)
   367  )