Skip to content

Commit 6bad2b3

Browse files
authored
Merge pull request #610 from dedis/add-marshalling-for-deal
Add marshalling for deal
2 parents 562ac70 + 25caede commit 6bad2b3

4 files changed

Lines changed: 174 additions & 28 deletions

File tree

internal/v3marshaling.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package internal
2+
3+
import (
4+
"fmt"
5+
"math"
6+
"reflect"
7+
8+
"go.dedis.ch/kyber/v4"
9+
"go.dedis.ch/kyber/v4/internal/protobuf"
10+
"go.dedis.ch/kyber/v4/share"
11+
)
12+
13+
// Suite defines the capabilities required by the v3marshalling package.
14+
type Suite interface {
15+
// Group is needed for Group.Scalar
16+
kyber.Group
17+
}
18+
19+
// compatiblePriShare is a struct for PriShare used when marshaling to
20+
// ensure compatibility with V3
21+
type compatiblePriShare struct {
22+
I int64
23+
V kyber.Scalar
24+
}
25+
26+
// MarshalPriShare marshals a share.PriShare into bytes or returns an error
27+
// if the encoding did not work. Encoding is compatible with Kyber V3
28+
func MarshalPriShare(priShare *share.PriShare) ([]byte, error) {
29+
toEncode := &compatiblePriShare{
30+
I: int64(priShare.I),
31+
V: priShare.V,
32+
}
33+
return protobuf.Encode(toEncode)
34+
}
35+
36+
// UnmarshalPriShare unmarshals a share.PriShare from bytes or returns an error
37+
// if the decoding did not work. Decoding is compatible with Kyber V3
38+
func UnmarshalPriShare(data []byte, suite Suite) (*share.PriShare, error) {
39+
compatiblePriShare := &compatiblePriShare{}
40+
constructors := make(protobuf.Constructors)
41+
constructors[reflect.TypeFor[kyber.Scalar]()] = func() interface{} { return suite.Scalar() }
42+
err := protobuf.DecodeWithConstructors(data, compatiblePriShare, constructors)
43+
44+
// Check for overflow on I
45+
if compatiblePriShare.I < 0 || compatiblePriShare.I > math.MaxUint32 {
46+
return nil, fmt.Errorf("cannot cast I as int64 to uint32 due to overflow")
47+
}
48+
49+
if err != nil {
50+
return nil, err
51+
}
52+
priShare := &share.PriShare{
53+
I: uint32(compatiblePriShare.I),
54+
V: compatiblePriShare.V,
55+
}
56+
return priShare, nil
57+
}

share/dkg/rabin/dkg.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import (
4242
"fmt"
4343

4444
"go.dedis.ch/kyber/v4"
45-
"go.dedis.ch/kyber/v4/internal/protobuf"
4645
"go.dedis.ch/kyber/v4/share"
4746
vss "go.dedis.ch/kyber/v4/share/vss/rabin"
4847
"go.dedis.ch/kyber/v4/sign/schnorr"
@@ -681,7 +680,7 @@ func (cc *ComplaintCommits) Hash(s Suite) []byte {
681680
_, _ = h.Write([]byte("commitcomplaint"))
682681
_ = binary.Write(h, binary.LittleEndian, cc.Index)
683682
_ = binary.Write(h, binary.LittleEndian, cc.DealerIndex)
684-
buff, _ := protobuf.Encode(cc.Deal)
683+
buff, _ := cc.Deal.Marshal()
685684
_, _ = h.Write(buff)
686685
return h.Sum(nil)
687686
}

share/vss/pedersen/vss.go

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"reflect"
1313

1414
"go.dedis.ch/kyber/v4"
15+
"go.dedis.ch/kyber/v4/internal"
1516
"go.dedis.ch/kyber/v4/internal/protobuf"
1617
"go.dedis.ch/kyber/v4/share"
1718
"go.dedis.ch/kyber/v4/sign/schnorr"
@@ -58,6 +59,53 @@ type Deal struct {
5859
Commitments []kyber.Point
5960
}
6061

62+
// pedersenCompatibleDeal is a struct for Deal used when marshaling
63+
// to ensure compatibility with Kyber V3.
64+
type pedersenCompatibleDeal struct {
65+
SessionID []byte
66+
SecShare []byte
67+
T uint32
68+
Commitments []kyber.Point
69+
}
70+
71+
// Marshal marshals a Deal into bytes or return an error if encoding failed.
72+
// This encoding should always be preferred as it is compatible with Kyber V3.
73+
func (d *Deal) Marshal() ([]byte, error) {
74+
secShareBytes, err := internal.MarshalPriShare(d.SecShare)
75+
if err != nil {
76+
return nil, err
77+
}
78+
compatibleDeal := &pedersenCompatibleDeal{
79+
SessionID: d.SessionID,
80+
SecShare: secShareBytes,
81+
T: d.T,
82+
Commitments: d.Commitments,
83+
}
84+
return protobuf.Encode(compatibleDeal)
85+
}
86+
87+
// Unmarshal unmarshals a Deal from bytes or return an error if decoding failed.
88+
// This decoding should always be preferred as it is compatible with Kyber V3.
89+
func (d *Deal) Unmarshal(data []byte, suite Suite) error {
90+
compatibleDeal := &pedersenCompatibleDeal{}
91+
constructors := make(protobuf.Constructors)
92+
constructors[reflect.TypeFor[kyber.Point]()] = func() interface{} { return suite.Point() }
93+
err := protobuf.DecodeWithConstructors(data, compatibleDeal, constructors)
94+
if err != nil {
95+
return err
96+
}
97+
secShare, err := internal.UnmarshalPriShare(compatibleDeal.SecShare, suite)
98+
if err != nil {
99+
return err
100+
}
101+
102+
d.SessionID = compatibleDeal.SessionID
103+
d.T = compatibleDeal.T
104+
d.SecShare = secShare
105+
d.Commitments = compatibleDeal.Commitments
106+
return nil
107+
}
108+
61109
// EncryptedDeal contains the deal in a encrypted form only decipherable by the
62110
// correct recipient. The encryption is performed in a similar manner as what is
63111
// done in TLS. The dealer generates a temporary key pair, signs it with its
@@ -67,7 +115,7 @@ type EncryptedDeal struct {
67115
DHKey []byte
68116
// Signature of the DH key by the longterm key of the dealer
69117
Signature []byte
70-
// AEAD encryption of the deal marshalled by protobuf
118+
// AEAD encryption of the deal marshalled
71119
Cipher []byte
72120
}
73121

@@ -193,7 +241,7 @@ func (d *Dealer) EncryptedDeal(i int) (*EncryptedDeal, error) {
193241
}
194242

195243
nonce := make([]byte, gcm.NonceSize())
196-
dealBuff, err := protobuf.Encode(d.deals[i])
244+
dealBuff, err := d.deals[i].Marshal()
197245
if err != nil {
198246
return nil, err
199247
}
@@ -408,7 +456,7 @@ func (v *Verifier) decryptDeal(e *EncryptedDeal) (*Deal, error) {
408456
return nil, err
409457
}
410458
deal := &Deal{}
411-
err = deal.decode(v.suite, decrypted)
459+
err = deal.Unmarshal(decrypted, v.suite)
412460
return deal, err
413461
}
414462

@@ -772,22 +820,13 @@ func (r *Response) Hash(s Suite) []byte {
772820
return h.Sum(nil)
773821
}
774822

775-
func (d *Deal) decode(s Suite, buff []byte) error {
776-
constructors := make(protobuf.Constructors)
777-
var point kyber.Point
778-
var secret kyber.Scalar
779-
constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return s.Point() }
780-
constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return s.Scalar() }
781-
return protobuf.DecodeWithConstructors(buff, d, constructors)
782-
}
783-
784823
// Hash returns the hash of a Justification.
785824
func (j *Justification) Hash(s Suite) []byte {
786825
h := s.Hash()
787826
_, _ = h.Write([]byte("justification"))
788827
_, _ = h.Write(j.SessionID)
789828
_ = binary.Write(h, binary.LittleEndian, j.Index)
790-
buff, _ := protobuf.Encode(j.Deal)
829+
buff, _ := j.Deal.Marshal()
791830
_, _ = h.Write(buff)
792831
return h.Sum(nil)
793832
}

share/vss/rabin/vss.go

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"reflect"
3939

4040
"go.dedis.ch/kyber/v4"
41+
"go.dedis.ch/kyber/v4/internal"
4142
"go.dedis.ch/kyber/v4/internal/protobuf"
4243
"go.dedis.ch/kyber/v4/share"
4344
"go.dedis.ch/kyber/v4/sign/schnorr"
@@ -86,6 +87,65 @@ type Deal struct {
8687
Commitments []kyber.Point
8788
}
8889

90+
// rabinCompatibleDeal is a struct for Deal used when marshaling
91+
// to ensure compatibility with Kyber V3.
92+
type rabinCompatibleDeal struct {
93+
SessionID []byte
94+
SecShare []byte
95+
RndShare []byte
96+
T uint32
97+
Commitments []kyber.Point
98+
}
99+
100+
// Marshal marshals a Deal into bytes or return an error if encoding failed.
101+
// This encoding should always be preferred as it is compatible with Kyber V3.
102+
func (deal *Deal) Marshal() ([]byte, error) {
103+
secShareBytes, err := internal.MarshalPriShare(deal.SecShare)
104+
if err != nil {
105+
return nil, err
106+
}
107+
rndShareBytes, err := internal.MarshalPriShare(deal.RndShare)
108+
if err != nil {
109+
return nil, err
110+
}
111+
compatibleDeal := &rabinCompatibleDeal{
112+
SessionID: deal.SessionID,
113+
SecShare: secShareBytes,
114+
RndShare: rndShareBytes,
115+
T: deal.T,
116+
Commitments: deal.Commitments,
117+
}
118+
return protobuf.Encode(compatibleDeal)
119+
}
120+
121+
// Unmarshal unmarshals a Deal from bytes or return an error if decoding failed.
122+
// This decoding should always be preferred as it is compatible with Kyber V3.
123+
func (deal *Deal) Unmarshal(data []byte, suite Suite) error {
124+
compatibleDeal := &rabinCompatibleDeal{}
125+
constructors := make(protobuf.Constructors)
126+
constructors[reflect.TypeFor[kyber.Point]()] = func() interface{} { return suite.Point() }
127+
err := protobuf.DecodeWithConstructors(data, compatibleDeal, constructors)
128+
if err != nil {
129+
return err
130+
}
131+
132+
secShare, err := internal.UnmarshalPriShare(compatibleDeal.SecShare, suite)
133+
if err != nil {
134+
return err
135+
}
136+
137+
rndShare, err := internal.UnmarshalPriShare(compatibleDeal.RndShare, suite)
138+
if err != nil {
139+
return err
140+
}
141+
deal.SessionID = compatibleDeal.SessionID
142+
deal.SecShare = secShare
143+
deal.RndShare = rndShare
144+
deal.T = compatibleDeal.T
145+
deal.Commitments = compatibleDeal.Commitments
146+
return nil
147+
}
148+
89149
// EncryptedDeal contains the deal in a encrypted form only decipherable by the
90150
// correct recipient. The encryption is performed in a similar manner as what is
91151
// done in TLS. The dealer generates a temporary key pair, signs it with its
@@ -95,7 +155,7 @@ type EncryptedDeal struct {
95155
DHKey kyber.Point
96156
// Signature of the DH key by the longterm key of the dealer
97157
Signature []byte
98-
// AEAD encryption of the deal marshalled by protobuf
158+
// AEAD encryption of the deal marshalled
99159
Cipher []byte
100160
}
101161

@@ -222,7 +282,7 @@ func (d *Dealer) EncryptedDeal(i int) (*EncryptedDeal, error) {
222282
}
223283

224284
nonce := make([]byte, gcm.NonceSize())
225-
dealBuff, err := protobuf.Encode(d.deals[i])
285+
dealBuff, err := d.deals[i].Marshal()
226286
if err != nil {
227287
return nil, err
228288
}
@@ -438,7 +498,7 @@ func (v *Verifier) decryptDeal(e *EncryptedDeal) (*Deal, error) {
438498
return nil, err
439499
}
440500
deal := &Deal{}
441-
err = deal.decode(v.suite, decrypted)
501+
err = deal.Unmarshal(decrypted, v.suite)
442502
return deal, err
443503
}
444504

@@ -763,22 +823,13 @@ func (r *Response) Hash(s Suite) []byte {
763823
return h.Sum(nil)
764824
}
765825

766-
func (d *Deal) decode(s Suite, buff []byte) error {
767-
constructors := make(protobuf.Constructors)
768-
var point kyber.Point
769-
var secret kyber.Scalar
770-
constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return s.Point() }
771-
constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return s.Scalar() }
772-
return protobuf.DecodeWithConstructors(buff, d, constructors)
773-
}
774-
775826
// Hash returns the hash of a Justification.
776827
func (j *Justification) Hash(s Suite) []byte {
777828
h := s.Hash()
778829
_, _ = h.Write([]byte("justification"))
779830
_, _ = h.Write(j.SessionID)
780831
_ = binary.Write(h, binary.LittleEndian, j.Index)
781-
buff, _ := protobuf.Encode(j.Deal)
832+
buff, _ := j.Deal.Marshal()
782833
_, _ = h.Write(buff)
783834
return h.Sum(nil)
784835
}

0 commit comments

Comments
 (0)