Skip to content

Commit 53dcd36

Browse files
committed
Fix slot decryption signature computation
Now we use SSZ as required by the spec. Before we did an easier encoding as a placeholder.
1 parent 7cc9556 commit 53dcd36

File tree

7 files changed

+331
-72
lines changed

7 files changed

+331
-72
lines changed

rolling-shutter/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/bitwurx/jrpc2 v0.0.0-20220302204700-52c6dbbeb536
1111
github.com/deepmap/oapi-codegen v1.9.1
1212
github.com/ethereum/go-ethereum v1.13.11
13+
github.com/ferranbt/fastssz v0.1.3
1314
github.com/getkin/kin-openapi v0.87.0
1415
github.com/go-chi/chi/v5 v5.0.10
1516
github.com/google/go-cmp v0.6.0

rolling-shutter/go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt
210210
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
211211
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
212212
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
213+
github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo=
214+
github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE=
213215
github.com/fjl/memsize v0.0.1 h1:+zhkb+dhUgx0/e+M8sF0QqiouvMQUiKR+QYvdxIOKcQ=
214216
github.com/fjl/memsize v0.0.1/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
215217
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -917,6 +919,8 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
917919
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
918920
github.com/ulope/jrpc2 v0.0.0-20230706135348-a95cf3d96bd2 h1:rk0z/6CEJbstiHqv8+4ZIMv4Sm2zBZ5v5C56P8JXd+I=
919921
github.com/ulope/jrpc2 v0.0.0-20230706135348-a95cf3d96bd2/go.mod h1:bzOCUO4YLqjPZbPM4jeZzu/WIEauP/ouNWLRysNQdc0=
922+
github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg=
923+
github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M=
920924
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
921925
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
922926
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// This package contains SSZ-encodable types used by the Gnosis keyper.
2+
// The encodings are automatically generated using FastSSZ (https://github.com/ferranbt/fastssz).
3+
// Command: `$ go run sszgen/*.go --path <path to package>`
4+
package gnosisssztypes
5+
6+
import (
7+
"crypto/ecdsa"
8+
9+
"github.com/ethereum/go-ethereum/common"
10+
"github.com/ethereum/go-ethereum/crypto"
11+
"github.com/pkg/errors"
12+
13+
"github.com/shutter-network/rolling-shutter/rolling-shutter/medley/identitypreimage"
14+
)
15+
16+
type IdentityPreimage struct {
17+
Bytes []byte `ssz-size:"52"`
18+
}
19+
20+
type SlotDecryptionSignatureData struct {
21+
InstanceID uint64
22+
Eon uint64
23+
Slot uint64
24+
TxPointer uint64
25+
IdentityPreimages []IdentityPreimage `ssz-max:"1024"`
26+
}
27+
28+
func NewSlotDecryptionSignatureData(
29+
instanceID uint64,
30+
eon uint64,
31+
slot uint64,
32+
txPointer uint64,
33+
identityPreimages []identitypreimage.IdentityPreimage,
34+
) (*SlotDecryptionSignatureData, error) {
35+
if len(identityPreimages) > 1024 {
36+
return nil, errors.New("too many identity preimages")
37+
}
38+
39+
wrappedPreimages := []IdentityPreimage{}
40+
for _, preimage := range identityPreimages {
41+
wrappedPreimage := IdentityPreimage{
42+
Bytes: preimage.Bytes(),
43+
}
44+
wrappedPreimages = append(wrappedPreimages, wrappedPreimage)
45+
}
46+
47+
return &SlotDecryptionSignatureData{
48+
InstanceID: instanceID,
49+
Eon: eon,
50+
Slot: slot,
51+
TxPointer: txPointer,
52+
IdentityPreimages: wrappedPreimages,
53+
}, nil
54+
}
55+
56+
func (d *SlotDecryptionSignatureData) ComputeSignature(key *ecdsa.PrivateKey) ([]byte, error) {
57+
h, err := d.HashTreeRoot()
58+
if err != nil {
59+
return nil, errors.Wrap(err, "failed to compute hash tree root of slot decryption signature data")
60+
}
61+
return crypto.Sign(h[:], key)
62+
}
63+
64+
func (d *SlotDecryptionSignatureData) CheckSignature(signature []byte, address common.Address) (bool, error) {
65+
h, err := d.HashTreeRoot()
66+
if err != nil {
67+
return false, errors.Wrap(err, "failed to compute hash tree root of slot decryption signature data")
68+
}
69+
signerPubkey, err := crypto.SigToPub(h[:], signature)
70+
if err != nil {
71+
return false, errors.Wrap(err, "failed to recover public key from slot decryption signature")
72+
}
73+
signerAddress := crypto.PubkeyToAddress(*signerPubkey)
74+
return signerAddress == address, nil
75+
}

rolling-shutter/keyperimpl/gnosis/gnosisssztypes/slotdecryptionsignatures_encoding.go

Lines changed: 219 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rolling-shutter/keyperimpl/gnosis/handlers.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
obskeyperdatabase "github.com/shutter-network/rolling-shutter/rolling-shutter/chainobserver/db/keyper"
1414
corekeyperdatabase "github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/database"
1515
"github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/gnosis/database"
16+
"github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/gnosis/gnosisssztypes"
1617
"github.com/shutter-network/rolling-shutter/rolling-shutter/medley/identitypreimage"
1718
"github.com/shutter-network/rolling-shutter/rolling-shutter/p2pmsg"
1819
"github.com/shutter-network/rolling-shutter/rolling-shutter/shdb"
@@ -76,14 +77,17 @@ func (h *DecryptionKeySharesHandler) ValidateMessage(ctx context.Context, msg p2
7677
identityPreimage := identitypreimage.IdentityPreimage(share.EpochID)
7778
identityPreimages = append(identityPreimages, identityPreimage)
7879
}
79-
slotDecryptionSignatureData := SlotDecryptionSignatureData{
80-
InstanceID: keyShares.InstanceID,
81-
Eon: keyShares.Eon,
82-
Slot: extra.Gnosis.Slot,
83-
TxPointer: extra.Gnosis.TxPointer,
84-
IdentityPreimages: identityPreimages,
80+
slotDecryptionSignatureData, err := gnosisssztypes.NewSlotDecryptionSignatureData(
81+
keyShares.InstanceID,
82+
keyShares.Eon,
83+
extra.Gnosis.Slot,
84+
extra.Gnosis.TxPointer,
85+
identityPreimages,
86+
)
87+
if err != nil {
88+
return pubsub.ValidationReject, errors.Wrap(err, "failed to create slot decryption signature data object")
8589
}
86-
signatureValid, err := CheckSlotDecryptionSignature(&slotDecryptionSignatureData, extra.Gnosis.Signature, keyperAddress)
90+
signatureValid, err := slotDecryptionSignatureData.CheckSignature(extra.Gnosis.Signature, keyperAddress)
8791
if err != nil {
8892
return pubsub.ValidationReject, errors.Wrap(err, "failed to check slot decryption signature")
8993
}
@@ -247,17 +251,20 @@ func (h *DecryptionKeysHandler) ValidateMessage(ctx context.Context, msg p2pmsg.
247251
identityPreimage := identitypreimage.IdentityPreimage(key.Identity)
248252
identityPreimages = append(identityPreimages, identityPreimage)
249253
}
250-
slotDecryptionSignatureData := SlotDecryptionSignatureData{
251-
InstanceID: keys.InstanceID,
252-
Eon: keys.Eon,
253-
Slot: extra.Gnosis.Slot,
254-
TxPointer: extra.Gnosis.TxPointer,
255-
IdentityPreimages: identityPreimages,
254+
slotDecryptionSignatureData, err := gnosisssztypes.NewSlotDecryptionSignatureData(
255+
keys.InstanceID,
256+
keys.Eon,
257+
extra.Gnosis.Slot,
258+
extra.Gnosis.TxPointer,
259+
identityPreimages,
260+
)
261+
if err != nil {
262+
return pubsub.ValidationReject, errors.Wrap(err, "failed to create slot decryption signature data object")
256263
}
257264
for signatureIndex := 0; signatureIndex < len(extra.Gnosis.Signatures); signatureIndex++ {
258265
signature := extra.Gnosis.Signatures[signatureIndex]
259266
signer := signers[signatureIndex]
260-
signatureValid, err := CheckSlotDecryptionSignature(&slotDecryptionSignatureData, signature, signer)
267+
signatureValid, err := slotDecryptionSignatureData.CheckSignature(signature, signer)
261268
if err != nil {
262269
return pubsub.ValidationReject, errors.Wrap(err, "failed to check slot decryption signature")
263270
}

0 commit comments

Comments
 (0)