-
Notifications
You must be signed in to change notification settings - Fork 0
/
ecck1.go
122 lines (109 loc) · 2.8 KB
/
ecck1.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
package cryptosuite
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"golang.org/x/crypto/sha3"
"hash"
)
type EccK1 struct {
curve elliptic.Curve
sigAlgorithm x509.SignatureAlgorithm
hashFunction func() hash.Hash
}
func NewEccK1() *EccK1 {
return &EccK1{
curve: crypto.S256(),
sigAlgorithm: x509.ECDSAWithSHA256,
hashFunction: sha3.New256,
}
}
func (c EccK1) GenerateKey() (priKeyByte []byte, pubKeyByte []byte, err error) {
key, err := ecdsa.GenerateKey(c.curve, rand.Reader)
if err != nil {
return nil, nil, err
}
priKeyByte = crypto.FromECDSA(key)
pubKeyByte = crypto.FromECDSAPub(&key.PublicKey)
return priKeyByte, pubKeyByte, nil
}
func (c EccK1) Sign(priKey []byte, digest []byte) (signature []byte, err error) {
priKeyIns, err := crypto.ToECDSA(priKey)
if err != nil {
return nil, err
}
return crypto.Sign(digest[:], priKeyIns)
}
func (c EccK1) Verify(from []byte, digest []byte, sig []byte) (bool, error) {
if sig[64] == 27 || sig[64] == 28 {
sig[64] -= 27
}
key, err := crypto.SigToPub(digest, sig)
if err != nil {
return false, err
}
addr := crypto.PubkeyToAddress(*key)
if from != nil {
if !bytes.Equal(from, addr.Bytes()) {
return false, errors.New("public key not matching signature")
}
}
parsedKey := crypto.FromECDSAPub(key)
flag := crypto.VerifySignature(parsedKey, digest[:], sig[:len(sig)-1])
return flag, nil
}
func Hash(data []byte) []byte {
msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
return crypto.Keccak256([]byte(msg))
}
func (c EccK1) GetPriKeyPem(key interface{}) ([]byte, error) {
if eccKey, ok := key.(*ecdsa.PrivateKey); !ok {
return nil, ErrInvalidKeyType
} else {
keyBytes := crypto.FromECDSA(eccKey)
block := pem.Block{
Type: "EC PRIVATE KEY",
Bytes: keyBytes,
}
pemBytes := pem.EncodeToMemory(&block)
return pemBytes, nil
}
}
func (c EccK1) GetPubKeyPem(key interface{}) ([]byte, error) {
if eccKey, ok := key.(*ecdsa.PublicKey); !ok {
return nil, ErrInvalidKeyType
} else {
keyBytes := crypto.FromECDSAPub(eccKey)
block := pem.Block{
Type: "PUBLIC KEY",
Bytes: keyBytes,
}
pemBytes := pem.EncodeToMemory(&block)
return pemBytes, nil
}
}
func (c EccK1) ParsePemPriKey(key []byte) (interface{}, error) {
//p, _ := pem.Decode(key)
//if p == nil || len(p.Bytes) == 0 {
// return nil, errors.New("key parse error")
//}
//panic("implement me")
p, _ := pem.Decode(key)
if p == nil || len(p.Bytes) == 0 {
return nil, errors.New("key parse error")
}
ecdsaPrivateKey, err := crypto.ToECDSA(p.Bytes)
if err != nil {
return nil, err
}
return ecdsaPrivateKey, nil
}
func (c EccK1) ParsePemPubKey(key []byte) (interface{}, error) {
return crypto.UnmarshalPubkey(key)
}