-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
key_bundle.go
145 lines (125 loc) · 4.37 KB
/
key_bundle.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
137
138
139
140
141
142
143
144
145
package ocr2key
import (
"encoding/hex"
"encoding/json"
"fmt"
"io"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
)
type OCR3SignerVerifier interface {
Sign3(digest ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report) (signature []byte, err error)
Verify3(publicKey ocrtypes.OnchainPublicKey, cd ocrtypes.ConfigDigest, seqNr uint64, r ocrtypes.Report, signature []byte) bool
}
// nolint
type KeyBundle interface {
// OnchainKeyring is used for signing reports (groups of observations, verified onchain)
ocrtypes.OnchainKeyring
// OffchainKeyring is used for signing observations
ocrtypes.OffchainKeyring
OCR3SignerVerifier
ID() string
ChainType() chaintype.ChainType
Marshal() ([]byte, error)
Unmarshal(b []byte) (err error)
Raw() Raw
OnChainPublicKey() string
// Decrypts ciphertext using the encryptionKey from an OCR2 OffchainKeyring
NaclBoxOpenAnonymous(ciphertext []byte) (plaintext []byte, err error)
}
// check generic keybundle for each chain conforms to KeyBundle interface
var _ KeyBundle = &keyBundle[*evmKeyring]{}
var _ KeyBundle = &keyBundle[*cosmosKeyring]{}
var _ KeyBundle = &keyBundle[*solanaKeyring]{}
var _ KeyBundle = &keyBundle[*starkkey.OCR2Key]{}
var _ KeyBundle = &keyBundle[*aptosKeyring]{}
var curve = secp256k1.S256()
// New returns key bundle based on the chain type
func New(chainType chaintype.ChainType) (KeyBundle, error) {
switch chainType {
case chaintype.EVM:
return newKeyBundleRand(chaintype.EVM, newEVMKeyring)
case chaintype.Cosmos:
return newKeyBundleRand(chaintype.Cosmos, newCosmosKeyring)
case chaintype.Solana:
return newKeyBundleRand(chaintype.Solana, newSolanaKeyring)
case chaintype.StarkNet:
return newKeyBundleRand(chaintype.StarkNet, starkkey.NewOCR2Key)
case chaintype.Aptos:
return newKeyBundleRand(chaintype.Aptos, newAptosKeyring)
}
return nil, chaintype.NewErrInvalidChainType(chainType)
}
// MustNewInsecure returns key bundle based on the chain type or panics
func MustNewInsecure(reader io.Reader, chainType chaintype.ChainType) KeyBundle {
switch chainType {
case chaintype.EVM:
return mustNewKeyBundleInsecure(chaintype.EVM, newEVMKeyring, reader)
case chaintype.Cosmos:
return mustNewKeyBundleInsecure(chaintype.Cosmos, newCosmosKeyring, reader)
case chaintype.Solana:
return mustNewKeyBundleInsecure(chaintype.Solana, newSolanaKeyring, reader)
case chaintype.StarkNet:
return mustNewKeyBundleInsecure(chaintype.StarkNet, starkkey.NewOCR2Key, reader)
case chaintype.Aptos:
return mustNewKeyBundleInsecure(chaintype.Aptos, newAptosKeyring, reader)
}
panic(chaintype.NewErrInvalidChainType(chainType))
}
var _ fmt.GoStringer = &keyBundleBase{}
type keyBundleBase struct {
OffchainKeyring
id models.Sha256Hash
chainType chaintype.ChainType
}
func (kb keyBundleBase) ID() string {
return hex.EncodeToString(kb.id[:])
}
// ChainType gets the chain type from the key bundle
func (kb keyBundleBase) ChainType() chaintype.ChainType {
return kb.chainType
}
// String reduces the risk of accidentally logging the private key
func (kb keyBundleBase) String() string {
return fmt.Sprintf("KeyBundle{chainType: %s, id: %s}", kb.ChainType(), kb.ID())
}
// GoString reduces the risk of accidentally logging the private key
func (kb keyBundleBase) GoString() string {
return kb.String()
}
// nolint
type Raw []byte
func (raw Raw) Key() (kb KeyBundle) {
var temp struct{ ChainType chaintype.ChainType }
err := json.Unmarshal(raw, &temp)
if err != nil {
panic(err)
}
switch temp.ChainType {
case chaintype.EVM:
kb = newKeyBundle(new(evmKeyring))
case chaintype.Cosmos:
kb = newKeyBundle(new(cosmosKeyring))
case chaintype.Solana:
kb = newKeyBundle(new(solanaKeyring))
case chaintype.StarkNet:
kb = newKeyBundle(new(starkkey.OCR2Key))
case chaintype.Aptos:
kb = newKeyBundle(new(aptosKeyring))
default:
return nil
}
if err := kb.Unmarshal(raw); err != nil {
panic(err)
}
return
}
// type is added to the beginning of the passwords for OCR key bundles,
// so that the keys can't accidentally be mis-used in the wrong place
func adulteratedPassword(auth string) string {
s := "ocr2key" + auth
return s
}