github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/keys/key.go (about)

     1  package keys
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	"github.com/hyperledger/burrow/crypto"
     8  	"github.com/tmthrgd/go-hex"
     9  )
    10  
    11  type Key struct {
    12  	CurveType  crypto.CurveType
    13  	Address    crypto.Address
    14  	PublicKey  crypto.PublicKey
    15  	PrivateKey crypto.PrivateKey
    16  }
    17  
    18  // json encodings - addresses should be hex encoded
    19  type keyJSON struct {
    20  	CurveType   string
    21  	Address     string
    22  	PublicKey   string
    23  	AddressHash string
    24  	PrivateKey  privateKeyJSON
    25  }
    26  
    27  type privateKeyJSON struct {
    28  	Crypto     string
    29  	Plain      string `json:",omitempty"`
    30  	Salt       []byte `json:",omitempty"`
    31  	Nonce      []byte `json:",omitempty"`
    32  	CipherText []byte `json:",omitempty"`
    33  }
    34  
    35  func NewKey(typ crypto.CurveType) (*Key, error) {
    36  	privKey, err := crypto.GeneratePrivateKey(nil, typ)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	pubKey := privKey.GetPublicKey()
    41  	return &Key{
    42  		CurveType:  typ,
    43  		PublicKey:  *pubKey,
    44  		Address:    pubKey.GetAddress(),
    45  		PrivateKey: privKey,
    46  	}, nil
    47  }
    48  
    49  func NewKeyFromPub(curveType crypto.CurveType, PubKeyBytes []byte) (*Key, error) {
    50  	pubKey, err := crypto.PublicKeyFromBytes(PubKeyBytes, curveType)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	return &Key{
    56  		CurveType: curveType,
    57  		PublicKey: *pubKey,
    58  		Address:   pubKey.GetAddress(),
    59  	}, nil
    60  }
    61  
    62  func NewKeyFromPriv(curveType crypto.CurveType, PrivKeyBytes []byte) (*Key, error) {
    63  	privKey, err := crypto.PrivateKeyFromRawBytes(PrivKeyBytes, curveType)
    64  
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	pubKey := privKey.GetPublicKey()
    70  
    71  	return &Key{
    72  		CurveType:  curveType,
    73  		Address:    pubKey.GetAddress(),
    74  		PublicKey:  *pubKey,
    75  		PrivateKey: privKey,
    76  	}, nil
    77  }
    78  
    79  func (k *Key) Pubkey() []byte {
    80  	return k.PublicKey.PublicKey
    81  }
    82  
    83  func (k *Key) MarshalJSON() (j []byte, err error) {
    84  	jStruct := keyJSON{
    85  		CurveType:   k.CurveType.String(),
    86  		Address:     hex.EncodeUpperToString(k.Address[:]),
    87  		PublicKey:   hex.EncodeUpperToString(k.Pubkey()),
    88  		AddressHash: k.PublicKey.AddressHashType(),
    89  		PrivateKey:  privateKeyJSON{Crypto: CryptoNone, Plain: hex.EncodeUpperToString(k.PrivateKey.RawBytes())},
    90  	}
    91  	j, err = json.Marshal(jStruct)
    92  	return j, err
    93  }
    94  
    95  func (k *Key) UnmarshalJSON(j []byte) (err error) {
    96  	keyJ := new(keyJSON)
    97  	err = json.Unmarshal(j, &keyJ)
    98  	if err != nil {
    99  		return err
   100  	}
   101  	if len(keyJ.PrivateKey.Plain) == 0 {
   102  		return fmt.Errorf("no private key")
   103  	}
   104  	curveType, err := crypto.CurveTypeFromString(keyJ.CurveType)
   105  	if err != nil {
   106  		curveType = crypto.CurveTypeEd25519
   107  	}
   108  	privKey, err := hex.DecodeString(keyJ.PrivateKey.Plain)
   109  	if err != nil {
   110  		return err
   111  	}
   112  	k2, err := NewKeyFromPriv(curveType, privKey)
   113  	if err != nil {
   114  		return err
   115  	}
   116  
   117  	k.Address = k2.Address
   118  	k.CurveType = curveType
   119  	k.PublicKey = *k2.PrivateKey.GetPublicKey()
   120  	k.PrivateKey = k2.PrivateKey
   121  
   122  	return nil
   123  }
   124  
   125  // returns the address if valid, nil otherwise
   126  func isValidKeyJson(j []byte) []byte {
   127  	j1 := new(keyJSON)
   128  	e1 := json.Unmarshal(j, &j1)
   129  	if e1 == nil {
   130  		addr, _ := hex.DecodeString(j1.Address)
   131  		return addr
   132  	}
   133  	return nil
   134  }