/
dash_consensus_key.go
116 lines (92 loc) · 3.46 KB
/
dash_consensus_key.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
package privval
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"github.com/dashpay/dashd-go/btcjson"
tmcrypto "github.com/dashpay/tenderdash/crypto"
tmbytes "github.com/dashpay/tenderdash/libs/bytes"
)
type dashConsensusPrivateKey struct {
quorumHash tmcrypto.QuorumHash
privval DashPrivValidator
quorumType btcjson.LLMQType
}
var _ tmcrypto.PrivKey = &dashConsensusPrivateKey{}
func (key dashConsensusPrivateKey) Bytes() []byte {
quorumType := make([]byte, 8)
binary.LittleEndian.PutUint64(quorumType, uint64(key.quorumType))
ourType := key.TypeTag()
bytes := make([]byte, len(key.quorumHash)+len(ourType)+8)
bytes = append(bytes, quorumType...)
bytes = append(bytes, []byte(ourType)...)
bytes = append(bytes, key.quorumHash...)
return bytes
}
// Sign implements tmcrypto.PrivKey
func (key dashConsensusPrivateKey) Sign(messageBytes []byte) ([]byte, error) {
messageHash := tmcrypto.Checksum(messageBytes)
return key.SignDigest(messageHash)
}
// SignDigest implements tmcrypto.PrivKey
func (key dashConsensusPrivateKey) SignDigest(messageHash []byte) ([]byte, error) {
requestIDhash := messageHash
decodedSignature, _, err := key.privval.QuorumSign(context.TODO(), messageHash, requestIDhash, key.quorumType, key.quorumHash)
return decodedSignature, err
}
// PubKey implements tmcrypto.PrivKey
func (key dashConsensusPrivateKey) PubKey() tmcrypto.PubKey {
pubkey, err := key.privval.GetPubKey(context.TODO(), key.quorumHash)
if err != nil {
panic("cannot retrieve public key: " + err.Error()) // not nice, but this iface doesn;t support error handling
}
// return NewDashConsensusPublicKey(pubkey, key.quorumHash, key.quorumType)
return pubkey
}
// Equals implements tmcrypto.PrivKey
func (key dashConsensusPrivateKey) Equals(other tmcrypto.PrivKey) bool {
return bytes.Equal(key.Bytes(), other.Bytes())
}
// Type implements tmcrypto.PrivKey
func (key dashConsensusPrivateKey) Type() string {
return "dashCoreRPCPrivateKey"
}
// TypeTag implements jsontypes.Tagged interface.
func (key dashConsensusPrivateKey) TypeTag() string { return key.Type() }
func (key dashConsensusPrivateKey) String() string {
return fmt.Sprintf("%s(quorumHash:%s,quorumType:%d)", key.Type(), key.quorumHash.ShortString(), key.quorumType)
}
// DashConesensusPublicKey is a public key that constructs SignID in the background, to avoid this additional step
// when verifying signatures.
type DashConsensusPublicKey struct {
tmcrypto.PubKey
quorumHash tmcrypto.QuorumHash
quorumType btcjson.LLMQType
}
var _ tmcrypto.PubKey = DashConsensusPublicKey{}
// NewDashConsensusPublicKey wraps a public key with transparent handling of SignID according to DIP-7
func NewDashConsensusPublicKey(baseKey tmcrypto.PubKey, quorumHash tmcrypto.QuorumHash, quorumType btcjson.LLMQType) *DashConsensusPublicKey {
if key, ok := baseKey.(*DashConsensusPublicKey); ok {
// don't wrap ourselves, but allow change of quorum hash and type
baseKey = key.PubKey
}
return &DashConsensusPublicKey{
PubKey: baseKey,
quorumHash: quorumHash,
quorumType: quorumType,
}
}
func (pub DashConsensusPublicKey) VerifySignature(msg []byte, sig []byte) bool {
hash := tmcrypto.Checksum(msg)
return pub.VerifySignatureDigest(hash, sig)
}
func (pub DashConsensusPublicKey) VerifySignatureDigest(hash []byte, sig []byte) bool {
signID := tmcrypto.SignID(
pub.quorumType,
tmbytes.Reverse(pub.quorumHash),
tmbytes.Reverse(hash[:]),
tmbytes.Reverse(hash[:]),
)
return pub.PubKey.VerifySignatureDigest(signID, sig)
}