github.com/0chain/gosdk@v1.17.11/core/zcncrypto/ed255190chain.go (about)

     1  package zcncrypto
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"time"
     7  
     8  	"github.com/0chain/errors"
     9  
    10  	"github.com/0chain/gosdk/core/encryption"
    11  	"github.com/tyler-smith/go-bip39"
    12  	"golang.org/x/crypto/ed25519"
    13  )
    14  
    15  //ED255190chainScheme - a signature scheme based on ED25519
    16  type ED255190chainScheme struct {
    17  	privateKey []byte
    18  	publicKey  []byte
    19  	mnemonic   string
    20  }
    21  
    22  // NewED255190chainScheme - create a ED255190chainScheme object
    23  func NewED255190chainScheme() *ED255190chainScheme {
    24  	return &ED255190chainScheme{}
    25  }
    26  
    27  //GenerateKeys - implement interface
    28  func (ed *ED255190chainScheme) GenerateKeys() (*Wallet, error) {
    29  	// Check for recovery
    30  	if len(ed.mnemonic) == 0 {
    31  		entropy, err := bip39.NewEntropy(256)
    32  		if err != nil {
    33  			return nil, errors.New("generate_keys", "Getting entropy failed")
    34  		}
    35  		ed.mnemonic, err = bip39.NewMnemonic(entropy)
    36  		if err != nil {
    37  			return nil, errors.New("generate_keys", "Getting mnemonic failed")
    38  		}
    39  	}
    40  
    41  	seed := bip39.NewSeed(ed.mnemonic, "0chain-client-ed25519-key")
    42  	r := bytes.NewReader(seed)
    43  	public, private, err := ed25519.GenerateKey(r)
    44  	if err != nil {
    45  		return nil, errors.Wrap(err, "Generate keys failed")
    46  	}
    47  	// New Wallet
    48  	w := &Wallet{}
    49  	w.Keys = make([]KeyPair, 1)
    50  	w.Keys[0].PublicKey = hex.EncodeToString(public)
    51  	w.Keys[0].PrivateKey = hex.EncodeToString(private)
    52  	w.ClientKey = w.Keys[0].PublicKey
    53  	w.ClientID = encryption.Hash([]byte(public))
    54  	w.Mnemonic = ed.mnemonic
    55  	w.Version = CryptoVersion
    56  	w.DateCreated = time.Now().Format(time.RFC3339)
    57  	return w, nil
    58  }
    59  
    60  //GenerateKeysWithEth - not implemented
    61  func (ed *ED255190chainScheme) GenerateKeysWithEth(mnemonic, password string) (*Wallet, error) {
    62  	return nil, errors.New("", "Not supported for this scheme")
    63  }
    64  
    65  func (ed *ED255190chainScheme) RecoverKeys(mnemonic string) (*Wallet, error) {
    66  	if mnemonic == "" {
    67  		return nil, errors.New("chain_scheme_recover_keys", "Set mnemonic key failed")
    68  	}
    69  	if len(ed.privateKey) > 0 || len(ed.publicKey) > 0 {
    70  		return nil, errors.New("chain_scheme_recover_keys", "Cannot recover when there are keys")
    71  	}
    72  	ed.mnemonic = mnemonic
    73  	return ed.GenerateKeys()
    74  }
    75  
    76  func (b0 *ED255190chainScheme) GetMnemonic() string {
    77  	if b0 == nil {
    78  		return ""
    79  	}
    80  
    81  	return b0.mnemonic
    82  }
    83  
    84  func (ed *ED255190chainScheme) SetPrivateKey(privateKey string) error {
    85  	if len(ed.privateKey) > 0 {
    86  		return errors.New("set_private_key", "cannot set private key when there is a public key")
    87  	}
    88  	if len(ed.publicKey) > 0 {
    89  		return errors.New("set_private_key", "private key already exists")
    90  	}
    91  	var err error
    92  	ed.privateKey, err = hex.DecodeString(privateKey)
    93  	return err
    94  }
    95  
    96  func (ed *ED255190chainScheme) SetPublicKey(publicKey string) error {
    97  	if len(ed.privateKey) > 0 {
    98  		return errors.New("set_public_key", "cannot set public key when there is a private key")
    99  	}
   100  	if len(ed.publicKey) > 0 {
   101  		return errors.New("set_public_key", "public key already exists")
   102  	}
   103  	var err error
   104  	ed.publicKey, err = hex.DecodeString(publicKey)
   105  	return err
   106  }
   107  
   108  func (b0 *ED255190chainScheme) SplitKeys(numSplits int) (*Wallet, error) {
   109  	return nil, errors.New("chain_scheme_splitkeys", "not implemented")
   110  }
   111  
   112  func (ed *ED255190chainScheme) Sign(hash string) (string, error) {
   113  	if len(ed.privateKey) == 0 {
   114  		return "", errors.New("chain_scheme_sign", "private key does not exists for signing")
   115  	}
   116  	rawHash, err := hex.DecodeString(hash)
   117  	if err != nil {
   118  		return "", err
   119  	}
   120  	if rawHash == nil {
   121  		return "", errors.New("chain_scheme_sign", "Failed hash while signing")
   122  	}
   123  	return hex.EncodeToString(ed25519.Sign(ed.privateKey, rawHash)), nil
   124  }
   125  
   126  func (ed *ED255190chainScheme) Verify(signature, msg string) (bool, error) {
   127  	if len(ed.publicKey) == 0 {
   128  		return false, errors.New("chain_scheme_verify", "public key does not exists for verification")
   129  	}
   130  	sign, err := hex.DecodeString(signature)
   131  	if err != nil {
   132  		return false, err
   133  	}
   134  	data, err := hex.DecodeString(msg)
   135  	if err != nil {
   136  		return false, err
   137  	}
   138  	return ed25519.Verify(ed.publicKey, data, sign), nil
   139  }
   140  
   141  func (ed *ED255190chainScheme) Add(signature, msg string) (string, error) {
   142  	return "", errors.New("chain_scheme_add", "Not supported by signature scheme")
   143  }
   144  
   145  //GetPublicKey - implement interface
   146  func (ed *ED255190chainScheme) GetPublicKey() string {
   147  	return hex.EncodeToString(ed.publicKey)
   148  }
   149  
   150  //GetPrivateKey - implement interface
   151  func (ed *ED255190chainScheme) GetPrivateKey() string {
   152  	return hex.EncodeToString(ed.privateKey)
   153  }
   154  
   155  //SetID sets ID in HexString format
   156  func (ed *ED255190chainScheme) SetID(id string) error {
   157  	// b0.Ids = id
   158  	// return b0.id.SetHexString(id)
   159  	return errors.New("chain_scheme_set_id", "it is not implemented yet")
   160  }
   161  
   162  //GetID gets ID in hex string format
   163  func (ed *ED255190chainScheme) GetID() string {
   164  	//return b0.id.GetHexString()
   165  	return ""
   166  }
   167  
   168  // GetPrivateKeyAsByteArray - converts private key into byte array
   169  func (ed *ED255190chainScheme) GetPrivateKeyAsByteArray() ([]byte, error) {
   170  	// if len(b0.PrivateKey) == 0 {
   171  	// 	return nil, errors.New("get_private_key_as_byte_array", "cannot convert empty private key to byte array")
   172  	// }
   173  	// privateKeyBytes, err := hex.DecodeString(b0.PrivateKey)
   174  	// if err != nil {
   175  	// 	return nil, err
   176  	// }
   177  	// return privateKeyBytes, nil
   178  	return nil, errors.New("chain_scheme_get_private_key_as_byte_array", "it is not implemented yet")
   179  }