-
Notifications
You must be signed in to change notification settings - Fork 29
/
ed255190chain.go
136 lines (122 loc) · 3.58 KB
/
ed255190chain.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package zcncrypto
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"time"
"github.com/0chain/gosdk/core/encryption"
"github.com/tyler-smith/go-bip39"
"golang.org/x/crypto/ed25519"
)
//ED255190chainScheme - a signature scheme based on ED25519
type ED255190chainScheme struct {
privateKey []byte
publicKey []byte
mnemonic string
}
//NewED25519Scheme - create a ED255219Scheme object
func NewED255190chainScheme() *ED255190chainScheme {
return &ED255190chainScheme{}
}
//GenerateKeys - implement interface
func (ed *ED255190chainScheme) GenerateKeys() (*Wallet, error) {
// Check for recovery
if len(ed.mnemonic) == 0 {
entropy, err := bip39.NewEntropy(256)
if err != nil {
return nil, fmt.Errorf("Getting entropy failed")
}
ed.mnemonic, err = bip39.NewMnemonic(entropy)
if err != nil {
return nil, fmt.Errorf("Getting mnemonic failed")
}
}
seed := bip39.NewSeed(ed.mnemonic, "0chain-client-ed25519-key")
r := bytes.NewReader(seed)
public, private, err := ed25519.GenerateKey(r)
if err != nil {
return nil, fmt.Errorf("Generate keys failed - %s", err.Error())
}
// New Wallet
w := &Wallet{}
w.Keys = make([]KeyPair, 1)
w.Keys[0].PublicKey = hex.EncodeToString(public)
w.Keys[0].PrivateKey = hex.EncodeToString(private)
w.ClientKey = w.Keys[0].PublicKey
w.ClientID = encryption.Hash([]byte(public))
w.Mnemonic = ed.mnemonic
w.Version = CryptoVersion
w.DateCreated = time.Now().String()
return w, nil
}
func (ed *ED255190chainScheme) RecoverKeys(mnemonic string) (*Wallet, error) {
if mnemonic == "" {
return nil, errors.New("Set mnemonic key failed")
}
if len(ed.privateKey) > 0 || len(ed.publicKey) > 0 {
return nil, errors.New("Cannot recover when there are keys")
}
ed.mnemonic = mnemonic
return ed.GenerateKeys()
}
func (ed *ED255190chainScheme) SetPrivateKey(privateKey string) error {
if len(ed.privateKey) > 0 {
return errors.New("cannot set private key when there is a public key")
}
if len(ed.publicKey) > 0 {
return errors.New("private key already exists")
}
var err error
ed.privateKey, err = hex.DecodeString(privateKey)
return err
}
func (ed *ED255190chainScheme) SetPublicKey(publicKey string) error {
if len(ed.privateKey) > 0 {
return errors.New("cannot set public key when there is a private key")
}
if len(ed.publicKey) > 0 {
return errors.New("public key already exists")
}
var err error
ed.publicKey, err = hex.DecodeString(publicKey)
return err
}
func (ed *ED255190chainScheme) Sign(hash string) (string, error) {
if len(ed.privateKey) == 0 {
return "", errors.New("private key does not exists for signing")
}
rawHash, err := hex.DecodeString(hash)
if err != nil {
return "", err
}
if rawHash == nil {
return "", errors.New("Failed hash while signing")
}
return hex.EncodeToString(ed25519.Sign(ed.privateKey, rawHash)), nil
}
func (ed *ED255190chainScheme) Verify(signature, msg string) (bool, error) {
if len(ed.publicKey) == 0 {
return false, errors.New("public key does not exists for verification")
}
sign, err := hex.DecodeString(signature)
if err != nil {
return false, err
}
data, err := hex.DecodeString(msg)
if err != nil {
return false, err
}
return ed25519.Verify(ed.publicKey, data, sign), nil
}
func (ed *ED255190chainScheme) Add(signature, msg string) (string, error) {
return "", fmt.Errorf("Not supported by signature scheme")
}
//GetPublicKey - implement interface
func (ed *ED255190chainScheme) GetPublicKey() string {
return hex.EncodeToString(ed.publicKey)
}
//GetPrivateKey - implement interface
func (ed *ED255190chainScheme) GetPrivateKey() string {
return hex.EncodeToString(ed.privateKey)
}