Skip to content

Commit 9ddc120

Browse files
authored
feat: implemented sharesData format for keyshare file (#20)
1 parent fa4730c commit 9ddc120

File tree

6 files changed

+80
-18
lines changed

6 files changed

+80
-18
lines changed

cli/internal/cmd/sign.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func Sign(cmd *cobra.Command, _ []string) {
110110
if err != nil {
111111
shared.Exit(fmt.Sprintf("couldn't turn the keyshare into json: %v", err))
112112
}
113-
log.MaybeLog("keyfile JSON for use with the SSV UI:")
113+
log.MaybeLog("📄 here is a keyfile JSON for use with the SSV UI >")
114114
log.Log(string(j))
115115
}
116116

cli/internal/state/share.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package state
33
import (
44
"encoding/base64"
55
"encoding/hex"
6+
"fmt"
67
"time"
78

89
"github.com/randa-mu/ssv-dkg/shared/api"
@@ -46,33 +47,38 @@ func CreateKeyshareFile(ownerConfig api.OwnerConfig, signingOutput api.SigningOu
4647

4748
operators := make([]operator, len(signingOutput.OperatorShares))
4849
operatorIDs := make([]uint32, len(signingOutput.OperatorShares))
50+
var publicKeys []byte
51+
var encryptedShares []byte
4952

5053
for i, share := range signingOutput.OperatorShares {
51-
operatorKey := make([]byte, base64.StdEncoding.EncodedLen(len(share.Identity.Public)))
52-
base64.StdEncoding.Encode(operatorKey, share.Identity.Public)
54+
operatorKey := make([]byte, base64.RawStdEncoding.EncodedLen(len(share.Identity.Public)))
55+
base64.RawStdEncoding.Encode(operatorKey, share.Identity.Public)
5356
operators[i] = operator{
5457
Id: uint32(i),
5558
OperatorKey: operatorKey,
5659
}
5760
operatorIDs[i] = uint32(i)
61+
publicKeys = append(publicKeys, share.Identity.Public...)
62+
encryptedShares = append(encryptedShares, share.EncryptedShare...)
5863
}
5964

65+
sharesData := append(append(signingOutput.ValidatorNonceSignature, publicKeys...), encryptedShares...)
66+
6067
return KeyshareFile{
6168
Version: KeyshareFileVersion,
6269
CreatedAt: time.Now().UTC().String(),
6370
Shares: []keyShare{
6471
{
6572
Data: data{
6673
OwnerNonce: ownerConfig.ValidatorNonce,
67-
OwnerAddress: hex.EncodeToString(ownerConfig.Address),
74+
OwnerAddress: fmt.Sprintf("0x%s", hex.EncodeToString(ownerConfig.Address)),
6875
PublicKey: publicKey,
6976
Operators: operators,
7077
},
7178
Payload: payload{
7279
PublicKey: publicKey,
7380
OperatorIDs: operatorIDs,
74-
// TODO: work out how this is actually encoded from the encrypted sahres
75-
SharesData: "0xdeadbeefdeadbeef",
81+
SharesData: fmt.Sprintf("0x%s", hex.EncodeToString(sharesData)),
7682
},
7783
},
7884
},

shared/api/cli.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package api
22

33
import (
44
"github.com/randa-mu/ssv-dkg/shared/crypto"
5+
"github.com/randa-mu/ssv-dkg/shared/json"
56
)
67

78
type OwnerConfig struct {
8-
Address []byte
9-
ValidatorNonce uint32
9+
Address json.HexBytes `json:"address"`
10+
ValidatorNonce uint32 `json:"validator_nonce"`
1011
}
1112

1213
type UnsignedDepositData struct {
@@ -26,16 +27,16 @@ type SignedDepositData struct {
2627
}
2728

2829
type SigningOutput struct {
29-
SessionID []byte `json:"session_id"`
30-
GroupPublicKey []byte `json:"group_public_commitments"`
31-
OperatorShares []OperatorShare `json:"operator_shares"`
32-
DepositDataSignature []byte `json:"deposit_data_signature"`
33-
ValidatorNonceSignature []byte `json:"validator_nonce_signature"`
30+
SessionID json.UnpaddedBytes `json:"session_id"`
31+
GroupPublicKey json.UnpaddedBytes `json:"group_public_commitments"`
32+
OperatorShares []OperatorShare `json:"operator_shares"`
33+
DepositDataSignature json.UnpaddedBytes `json:"deposit_data_signature"`
34+
ValidatorNonceSignature json.UnpaddedBytes `json:"validator_nonce_signature"`
3435
}
3536

3637
type OperatorShare struct {
37-
Identity crypto.Identity `json:"identity"`
38-
EncryptedShare []byte `json:"encrypted_share"`
38+
Identity crypto.Identity `json:"identity"`
39+
EncryptedShare json.UnpaddedBytes `json:"encrypted_share"`
3940
}
4041

4142
type OperatorResponse struct {

shared/api/sidecar.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,15 @@ func createSignAPI(node Sidecar) http.HandlerFunc {
116116
bytes, err := io.ReadAll(request.Body)
117117
if err != nil {
118118
writer.WriteHeader(http.StatusBadRequest)
119+
slog.Debug("error reading signing body", "body", bytes, "err", err)
119120
return
120121
}
121122

122123
var requestBody SignRequest
123124
err = json.Unmarshal(bytes, &requestBody)
124125
if err != nil {
125126
writer.WriteHeader(http.StatusBadRequest)
127+
slog.Debug("error marshalling signing body", "body", bytes, "err", err)
126128
return
127129
}
128130

shared/crypto/keys.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/binary"
77

88
"github.com/drand/kyber"
9+
"github.com/randa-mu/ssv-dkg/shared/json"
910
)
1011

1112
// SigningScheme represents a cryptographic scheme used for signing and verification operations
@@ -56,9 +57,9 @@ func (k Keypair) SelfSign(suite SigningScheme, address string) (Identity, error)
5657
}
5758

5859
type Identity struct {
59-
Address string `json:"address"`
60-
Public []byte `json:"public"`
61-
Signature []byte `json:"signature"`
60+
Address string `json:"address"`
61+
Public json.UnpaddedBytes `json:"public"`
62+
Signature json.UnpaddedBytes `json:"signature"`
6263
}
6364

6465
// Verify checks the signature for a given identity is valid, if e.g. pulled from a remote file

shared/json/bytes.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package json
2+
3+
import (
4+
"encoding/base64"
5+
"encoding/hex"
6+
"encoding/json"
7+
)
8+
9+
// UnpaddedBytes is a wrapper type that ensures bytes are marshalled to base64
10+
// in json with padding characters
11+
type UnpaddedBytes []byte
12+
13+
func (b *UnpaddedBytes) MarshalJSON() ([]byte, error) {
14+
encoded := base64.RawStdEncoding.EncodeToString(*b)
15+
return json.Marshal(encoded)
16+
}
17+
18+
func (b *UnpaddedBytes) UnmarshalJSON(data []byte) error {
19+
var encoded string
20+
if err := json.Unmarshal(data, &encoded); err != nil {
21+
return err
22+
}
23+
24+
decoded, err := base64.RawStdEncoding.DecodeString(encoded)
25+
if err != nil {
26+
return err
27+
}
28+
*b = decoded
29+
return nil
30+
}
31+
32+
// HexBytes is a wrapper type that ensures bytes are marshalled to
33+
// hex in json
34+
type HexBytes []byte
35+
36+
func (b HexBytes) MarshalJSON() ([]byte, error) {
37+
return json.Marshal(hex.EncodeToString(b))
38+
}
39+
40+
func (b *HexBytes) UnmarshalJSON(data []byte) error {
41+
var encoded string
42+
if err := json.Unmarshal(data, &encoded); err != nil {
43+
return err
44+
}
45+
46+
decoded, err := hex.DecodeString(encoded)
47+
if err != nil {
48+
return err
49+
}
50+
*b = decoded
51+
return nil
52+
}

0 commit comments

Comments
 (0)