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 }