/
cosigner_key_shares.go
151 lines (138 loc) · 4.07 KB
/
cosigner_key_shares.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
146
147
148
149
150
151
package signer
import (
"crypto/rand"
"crypto/rsa"
"encoding/json"
"os"
cometjson "github.com/cometbft/cometbft/libs/json"
"github.com/cometbft/cometbft/privval"
"github.com/ethereum/go-ethereum/crypto/ecies"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
tsed25519 "gitlab.com/unit410/threshold-ed25519/pkg"
"golang.org/x/sync/errgroup"
)
// CreateCosignerEd25519ShardsFromFile creates CosignerEd25519Key objects from a priv_validator_key.json file
func CreateCosignerEd25519ShardsFromFile(priv string, threshold, shards uint8) ([]CosignerEd25519Key, error) {
pv, err := ReadPrivValidatorFile(priv)
if err != nil {
return nil, err
}
return CreateCosignerEd25519Shards(pv, threshold, shards), nil
}
// CreateCosignerEd25519Shards creates CosignerEd25519Key objects from a privval.FilePVKey
func CreateCosignerEd25519Shards(pv privval.FilePVKey, threshold, shards uint8) []CosignerEd25519Key {
privShards := tsed25519.DealShares(tsed25519.ExpandSecret(pv.PrivKey.Bytes()[:32]), threshold, shards)
out := make([]CosignerEd25519Key, shards)
for i, shard := range privShards {
out[i] = CosignerEd25519Key{
PubKey: pv.PubKey,
PrivateShard: shard,
ID: i + 1,
}
}
return out
}
// CreateCosignerRSAShards generate CosignerRSAKey objects.
func CreateCosignerRSAShards(shards int) ([]CosignerRSAKey, error) {
rsaKeys, pubKeys, err := makeRSAKeys(shards)
if err != nil {
return nil, err
}
out := make([]CosignerRSAKey, shards)
for i, key := range rsaKeys {
out[i] = CosignerRSAKey{
ID: i + 1,
RSAKey: *key,
RSAPubs: pubKeys,
}
}
return out, nil
}
// ReadPrivValidatorFile reads in a privval.FilePVKey from a given file.
func ReadPrivValidatorFile(priv string) (out privval.FilePVKey, err error) {
var bz []byte
if bz, err = os.ReadFile(priv); err != nil {
return
}
if err = cometjson.Unmarshal(bz, &out); err != nil {
return
}
return
}
// WriteCosignerEd25519ShardFile writes a cosigner Ed25519 key to a given file name.
func WriteCosignerEd25519ShardFile(cosigner CosignerEd25519Key, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
if err != nil {
return err
}
return os.WriteFile(file, jsonBytes, 0600)
}
// WriteCosignerRSAShardFile writes a cosigner RSA key to a given file name.
func WriteCosignerRSAShardFile(cosigner CosignerRSAKey, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
if err != nil {
return err
}
return os.WriteFile(file, jsonBytes, 0600)
}
// CreateCosignerECIESShards generates CosignerECIESKey objects.
func CreateCosignerECIESShards(shards int) ([]CosignerECIESKey, error) {
eciesKeys, pubKeys, err := makeECIESKeys(shards)
if err != nil {
return nil, err
}
out := make([]CosignerECIESKey, shards)
for i, key := range eciesKeys {
out[i] = CosignerECIESKey{
ID: i + 1,
ECIESKey: key,
ECIESPubs: pubKeys,
}
}
return out, nil
}
// WriteCosignerECIESShardFile writes a cosigner ECIES key to a given file name.
func WriteCosignerECIESShardFile(cosigner CosignerECIESKey, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
if err != nil {
return err
}
return os.WriteFile(file, jsonBytes, 0600)
}
func makeRSAKeys(num int) (rsaKeys []*rsa.PrivateKey, pubKeys []*rsa.PublicKey, err error) {
rsaKeys = make([]*rsa.PrivateKey, num)
pubKeys = make([]*rsa.PublicKey, num)
var eg errgroup.Group
bitSize := 4096
for i := 0; i < num; i++ {
i := i
eg.Go(func() error {
rsaKey, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
return err
}
rsaKeys[i] = rsaKey
pubKeys[i] = &rsaKey.PublicKey
return nil
})
}
return rsaKeys, pubKeys, eg.Wait()
}
func makeECIESKeys(num int) ([]*ecies.PrivateKey, []*ecies.PublicKey, error) {
eciesKeys := make([]*ecies.PrivateKey, num)
pubKeys := make([]*ecies.PublicKey, num)
var eg errgroup.Group
for i := 0; i < num; i++ {
i := i
eg.Go(func() error {
eciesKey, err := ecies.GenerateKey(rand.Reader, secp256k1.S256(), nil)
if err != nil {
return err
}
eciesKeys[i] = eciesKey
pubKeys[i] = &eciesKey.PublicKey
return nil
})
}
return eciesKeys, pubKeys, eg.Wait()
}