/
cube_signature.go
117 lines (98 loc) · 2.56 KB
/
cube_signature.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
package stake
import (
"bytes"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/json"
"encoding/pem"
"fmt"
"github.com/blockservice/echoin/utils"
"github.com/ethereum/go-ethereum/common"
"math/big"
"strings"
)
var bigZero = big.NewInt(0)
var bigOne = big.NewInt(1)
func VerifyCubeSignature(address common.Address, nonce uint64, cubeBatch string, sig string) error {
message := fmt.Sprintf("%s|%d", strings.ToLower(address.String()), nonce)
//fmt.Printf("message: %s\n", message)
hashed := sha256.Sum256([]byte(message))
publicKeyStr, err := getCubePublicKeyString(cubeBatch)
if err != nil {
fmt.Printf("Error occurred while retrieving public key string: %s\n", err)
return err
}
pk, err := loadPublicKey(publicKeyStr)
if err != nil {
fmt.Printf("Error occurred while loading public key: %s\n", err)
return err
}
m := new(big.Int)
bs, err := hex.DecodeString(sig)
if err != nil {
fmt.Printf("decode signature error: %v\n", err)
return err
}
m.SetBytes(bs)
c := encrypt(new(big.Int), pk, m)
if !bytes.Equal(c.Bytes(), bytes.TrimLeft(hashed[:], "\x00")) {
return ErrInvalidCubeSignature()
}
return nil
}
func getCubePublicKeyString(cubeBatch string) (string, error) {
pksBytes := utils.GetParams().CubePubKeys
var pks []CubePubKey
err := json.Unmarshal([]byte(pksBytes), &pks)
if err != nil {
return "", err
}
for _, pk := range pks {
if pk.CubeBatch == cubeBatch {
return pk.PubKey, nil
}
}
return "", nil
}
func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
g := new(big.Int)
x := new(big.Int)
g.GCD(x, nil, a, n)
if g.Cmp(bigOne) != 0 {
// In this case, a and n aren't coprime and we cannot calculate
// the inverse. This happens because the values of n are nearly
// prime (being the product of two primes) rather than truly
// prime.
return
}
if x.Cmp(bigOne) < 0 {
// 0 is not the multiplicative inverse of any element so, if x
// < 1, then x is negative.
x.Add(x, n)
}
return x, true
}
func digest(message string) []byte {
sha_256 := sha256.New()
sha_256.Write(bytes.NewBufferString(message).Bytes())
return sha_256.Sum(nil)
}
func encrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}
func loadPublicKey(publicKeyStr string) (*rsa.PublicKey, error) {
block, _ := pem.Decode([]byte(publicKeyStr))
if block == nil {
return nil, fmt.Errorf("public key error")
}
pkInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
pk := pkInterface.(*rsa.PublicKey)
return pk, nil
}