/
crypt.go
93 lines (70 loc) · 1.74 KB
/
crypt.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
package utils
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/md5"
"crypto/rand"
"io"
"math/big"
)
func SignData(privKey ecdsa.PrivateKey, dataToSign []byte) ([]byte, error) {
h := md5.New()
str := string(dataToSign)
io.WriteString(h, str)
data := h.Sum(nil)
r, s, err := ecdsa.Sign(rand.Reader, &privKey, data)
if err != nil {
return nil, err
}
signature := append(r.Bytes(), s.Bytes()...)
return signature, nil
}
func VerifySignature(signature []byte, message []byte, PubKey []byte) (bool, error) {
h := md5.New()
str := string(message)
io.WriteString(h, str)
data := h.Sum(nil)
// build key and verify data
r := big.Int{}
s := big.Int{}
sigLen := len(signature)
r.SetBytes(signature[:(sigLen / 2)])
s.SetBytes(signature[(sigLen / 2):])
x := big.Int{}
y := big.Int{}
keyLen := len(PubKey)
x.SetBytes(PubKey[:(keyLen / 2)])
y.SetBytes(PubKey[(keyLen / 2):])
curve := elliptic.P256()
rawPubKey := ecdsa.PublicKey{Curve: curve, X: &x, Y: &y}
return ecdsa.Verify(&rawPubKey, data, &r, &s), nil
}
func SignDataSet(PubKey []byte, privKey ecdsa.PrivateKey, dataSetsToSign [][]byte) ([][]byte, error) {
signatures := [][]byte{}
for _, dataToSign := range dataSetsToSign {
attempt := 1
var signature []byte
var err error
for {
// we can do more 1 attempt to sign. we found some cases where verification of signature fails
// we don't know the reason
signature, err = SignData(privKey, dataToSign)
if err != nil {
return nil, err
}
attempt = attempt + 1
v, err := VerifySignature(signature, dataToSign, PubKey)
if err != nil {
return nil, err
}
if v {
break
}
if attempt > 10 {
break
}
}
signatures = append(signatures, signature)
}
return signatures, nil
}