Skip to content
54 changes: 54 additions & 0 deletions internal/v3marshaling.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package internal

import (
"fmt"
"math"
"reflect"

"go.dedis.ch/kyber/v4"
"go.dedis.ch/kyber/v4/internal/protobuf"
"go.dedis.ch/kyber/v4/share"
)

type Suite interface {
Comment thread
thehoul marked this conversation as resolved.
kyber.Group
kyber.HashFactory
kyber.XOFFactory
kyber.Random
}

// compatiblePriShare is a struct for PriShare used when marshaling to
// ensure compatibility with V3
type compatiblePriShare struct {
I int64
V kyber.Scalar
}

func MarshalPriShare(priShare *share.PriShare) ([]byte, error) {
Comment thread
thehoul marked this conversation as resolved.
toEncode := &compatiblePriShare{
I: int64(priShare.I),
V: priShare.V,
}
return protobuf.Encode(toEncode)
}

func UnmarshalPriShare(data []byte, suite Suite) (*share.PriShare, error) {
Comment thread
thehoul marked this conversation as resolved.
compatiblePriShare := &compatiblePriShare{}
constructors := make(protobuf.Constructors)
constructors[reflect.TypeFor[kyber.Scalar]()] = func() interface{} { return suite.Scalar() }
err := protobuf.DecodeWithConstructors(data, compatiblePriShare, constructors)

// Check for overflow on I
if compatiblePriShare.I < 0 || compatiblePriShare.I > math.MaxUint32 {
return nil, fmt.Errorf("cannot cast I as int64 to uint32 due to overflow")
}

if err != nil {
return nil, err
}
priShare := &share.PriShare{
I: uint32(compatiblePriShare.I),
Comment thread
thehoul marked this conversation as resolved.
V: compatiblePriShare.V,
}
return priShare, nil
}
3 changes: 1 addition & 2 deletions share/dkg/rabin/dkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import (
"fmt"

"go.dedis.ch/kyber/v4"
"go.dedis.ch/kyber/v4/internal/protobuf"
"go.dedis.ch/kyber/v4/share"
vss "go.dedis.ch/kyber/v4/share/vss/rabin"
"go.dedis.ch/kyber/v4/sign/schnorr"
Expand Down Expand Up @@ -681,7 +680,7 @@ func (cc *ComplaintCommits) Hash(s Suite) []byte {
_, _ = h.Write([]byte("commitcomplaint"))
_ = binary.Write(h, binary.LittleEndian, cc.Index)
_ = binary.Write(h, binary.LittleEndian, cc.DealerIndex)
buff, _ := protobuf.Encode(cc.Deal)
buff, _ := cc.Deal.Marshal()
_, _ = h.Write(buff)
return h.Sum(nil)
}
Expand Down
61 changes: 48 additions & 13 deletions share/vss/pedersen/vss.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"reflect"

"go.dedis.ch/kyber/v4"
"go.dedis.ch/kyber/v4/internal"
"go.dedis.ch/kyber/v4/internal/protobuf"
"go.dedis.ch/kyber/v4/share"
"go.dedis.ch/kyber/v4/sign/schnorr"
Expand Down Expand Up @@ -58,6 +59,49 @@ type Deal struct {
Commitments []kyber.Point
}

// pedersenCompatibleDeal is a struct for Deal used when marshaling
// to ensure compatibility with Kyber V3.
type pedersenCompatibleDeal struct {
SessionID []byte
SecShare []byte
T uint32
Commitments []kyber.Point
}

func (d *Deal) Marshal() ([]byte, error) {
Comment thread
thehoul marked this conversation as resolved.
secShareBytes, err := internal.MarshalPriShare(d.SecShare)
if err != nil {
return nil, err
}
compatibleDeal := &pedersenCompatibleDeal{
SessionID: d.SessionID,
SecShare: secShareBytes,
T: d.T,
Commitments: d.Commitments,
}
return protobuf.Encode(compatibleDeal)
}

func (d *Deal) Unmarshal(data []byte, suite Suite) error {
Comment thread
thehoul marked this conversation as resolved.
compatibleDeal := &pedersenCompatibleDeal{}
constructors := make(protobuf.Constructors)
constructors[reflect.TypeFor[kyber.Point]()] = func() interface{} { return suite.Point() }
err := protobuf.DecodeWithConstructors(data, compatibleDeal, constructors)
if err != nil {
return err
}
secShare, err := internal.UnmarshalPriShare(compatibleDeal.SecShare, suite)
if err != nil {
return err
}

d.SessionID = compatibleDeal.SessionID
d.T = compatibleDeal.T
d.SecShare = secShare
d.Commitments = compatibleDeal.Commitments
return nil
}

// EncryptedDeal contains the deal in a encrypted form only decipherable by the
// correct recipient. The encryption is performed in a similar manner as what is
// done in TLS. The dealer generates a temporary key pair, signs it with its
Expand All @@ -67,7 +111,7 @@ type EncryptedDeal struct {
DHKey []byte
// Signature of the DH key by the longterm key of the dealer
Signature []byte
// AEAD encryption of the deal marshalled by protobuf
// AEAD encryption of the deal marshalled
Cipher []byte
}

Expand Down Expand Up @@ -193,7 +237,7 @@ func (d *Dealer) EncryptedDeal(i int) (*EncryptedDeal, error) {
}

nonce := make([]byte, gcm.NonceSize())
dealBuff, err := protobuf.Encode(d.deals[i])
dealBuff, err := d.deals[i].Marshal()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -408,7 +452,7 @@ func (v *Verifier) decryptDeal(e *EncryptedDeal) (*Deal, error) {
return nil, err
}
deal := &Deal{}
err = deal.decode(v.suite, decrypted)
err = deal.Unmarshal(decrypted, v.suite)
return deal, err
}

Expand Down Expand Up @@ -772,22 +816,13 @@ func (r *Response) Hash(s Suite) []byte {
return h.Sum(nil)
}

func (d *Deal) decode(s Suite, buff []byte) error {
constructors := make(protobuf.Constructors)
var point kyber.Point
var secret kyber.Scalar
constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return s.Point() }
constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return s.Scalar() }
return protobuf.DecodeWithConstructors(buff, d, constructors)
}

// Hash returns the hash of a Justification.
func (j *Justification) Hash(s Suite) []byte {
h := s.Hash()
_, _ = h.Write([]byte("justification"))
_, _ = h.Write(j.SessionID)
_ = binary.Write(h, binary.LittleEndian, j.Index)
buff, _ := protobuf.Encode(j.Deal)
buff, _ := j.Deal.Marshal()
_, _ = h.Write(buff)
return h.Sum(nil)
}
73 changes: 60 additions & 13 deletions share/vss/rabin/vss.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"reflect"

"go.dedis.ch/kyber/v4"
"go.dedis.ch/kyber/v4/internal"
"go.dedis.ch/kyber/v4/internal/protobuf"
"go.dedis.ch/kyber/v4/share"
"go.dedis.ch/kyber/v4/sign/schnorr"
Expand Down Expand Up @@ -86,6 +87,61 @@ type Deal struct {
Commitments []kyber.Point
}

// rabinCompatibleDeal is a struct for Deal used when marshaling
// to ensure compatibility with Kyber V3.
type rabinCompatibleDeal struct {
SessionID []byte
SecShare []byte
RndShare []byte
T uint32
Commitments []kyber.Point
}

func (deal *Deal) Marshal() ([]byte, error) {
Comment thread
thehoul marked this conversation as resolved.
secShareBytes, err := internal.MarshalPriShare(deal.SecShare)
if err != nil {
return nil, err
}
rndShareBytes, err := internal.MarshalPriShare(deal.RndShare)
if err != nil {
return nil, err
}
compatibleDeal := &rabinCompatibleDeal{
SessionID: deal.SessionID,
SecShare: secShareBytes,
RndShare: rndShareBytes,
T: deal.T,
Commitments: deal.Commitments,
}
return protobuf.Encode(compatibleDeal)
}

func (deal *Deal) Unmarshal(data []byte, suite Suite) error {
Comment thread
thehoul marked this conversation as resolved.
compatibleDeal := &rabinCompatibleDeal{}
constructors := make(protobuf.Constructors)
constructors[reflect.TypeFor[kyber.Point]()] = func() interface{} { return suite.Point() }
err := protobuf.DecodeWithConstructors(data, compatibleDeal, constructors)
if err != nil {
return err
}

secShare, err := internal.UnmarshalPriShare(compatibleDeal.SecShare, suite)
if err != nil {
return err
}

rndShare, err := internal.UnmarshalPriShare(compatibleDeal.RndShare, suite)
if err != nil {
return err
}
deal.SessionID = compatibleDeal.SessionID
deal.SecShare = secShare
deal.RndShare = rndShare
deal.T = compatibleDeal.T
deal.Commitments = compatibleDeal.Commitments
return nil
}

// EncryptedDeal contains the deal in a encrypted form only decipherable by the
// correct recipient. The encryption is performed in a similar manner as what is
// done in TLS. The dealer generates a temporary key pair, signs it with its
Expand All @@ -95,7 +151,7 @@ type EncryptedDeal struct {
DHKey kyber.Point
// Signature of the DH key by the longterm key of the dealer
Signature []byte
// AEAD encryption of the deal marshalled by protobuf
// AEAD encryption of the deal marshalled
Cipher []byte
}

Expand Down Expand Up @@ -222,7 +278,7 @@ func (d *Dealer) EncryptedDeal(i int) (*EncryptedDeal, error) {
}

nonce := make([]byte, gcm.NonceSize())
dealBuff, err := protobuf.Encode(d.deals[i])
dealBuff, err := d.deals[i].Marshal()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -438,7 +494,7 @@ func (v *Verifier) decryptDeal(e *EncryptedDeal) (*Deal, error) {
return nil, err
}
deal := &Deal{}
err = deal.decode(v.suite, decrypted)
err = deal.Unmarshal(decrypted, v.suite)
return deal, err
}

Expand Down Expand Up @@ -763,22 +819,13 @@ func (r *Response) Hash(s Suite) []byte {
return h.Sum(nil)
}

func (d *Deal) decode(s Suite, buff []byte) error {
constructors := make(protobuf.Constructors)
var point kyber.Point
var secret kyber.Scalar
constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return s.Point() }
constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return s.Scalar() }
return protobuf.DecodeWithConstructors(buff, d, constructors)
}

// Hash returns the hash of a Justification.
func (j *Justification) Hash(s Suite) []byte {
h := s.Hash()
_, _ = h.Write([]byte("justification"))
_, _ = h.Write(j.SessionID)
_ = binary.Write(h, binary.LittleEndian, j.Index)
buff, _ := protobuf.Encode(j.Deal)
buff, _ := j.Deal.Marshal()
_, _ = h.Write(buff)
return h.Sum(nil)
}
Loading