aboutsummaryrefslogtreecommitdiffstats
path: root/core/crypto/dkg
diff options
context:
space:
mode:
authorSonic <sonic@dexon.org>2018-10-20 16:07:37 +0800
committerWei-Ning Huang <aitjcize@gmail.com>2018-10-20 16:07:37 +0800
commit9fbe8f9e561a64429eb15431782eb4280d0ffbad (patch)
tree035495fdc970b7ad6f2cb1c6b9cc42cbd36526cb /core/crypto/dkg
parent1f7491df37caf974ffa0c824c4c02a8fe2aafcd9 (diff)
downloaddexon-consensus-9fbe8f9e561a64429eb15431782eb4280d0ffbad.tar
dexon-consensus-9fbe8f9e561a64429eb15431782eb4280d0ffbad.tar.gz
dexon-consensus-9fbe8f9e561a64429eb15431782eb4280d0ffbad.tar.bz2
dexon-consensus-9fbe8f9e561a64429eb15431782eb4280d0ffbad.tar.lz
dexon-consensus-9fbe8f9e561a64429eb15431782eb4280d0ffbad.tar.xz
dexon-consensus-9fbe8f9e561a64429eb15431782eb4280d0ffbad.tar.zst
dexon-consensus-9fbe8f9e561a64429eb15431782eb4280d0ffbad.zip
core: types: implement rlp.Encoder and rlp.Decoder (#232)
* core: types: implement rlp.Encoder and rlp.Decoder * crypto: dkg: fix PublicKey.Bytes
Diffstat (limited to 'core/crypto/dkg')
-rw-r--r--core/crypto/dkg/dkg.go98
-rw-r--r--core/crypto/dkg/dkg_test.go25
2 files changed, 120 insertions, 3 deletions
diff --git a/core/crypto/dkg/dkg.go b/core/crypto/dkg/dkg.go
index 55199a9..8d0e088 100644
--- a/core/crypto/dkg/dkg.go
+++ b/core/crypto/dkg/dkg.go
@@ -20,8 +20,10 @@ package dkg
import (
"encoding/json"
"fmt"
+ "io"
"github.com/Spiderpowa/bls/ffi/go/bls"
+ "github.com/dexon-foundation/dexon/rlp"
"github.com/dexon-foundation/dexon-consensus-core/common"
"github.com/dexon-foundation/dexon-consensus-core/core/crypto"
@@ -92,6 +94,72 @@ type PublicKeyShares struct {
masterPublicKey []bls.PublicKey
}
+type rlpPublicKeyShares struct {
+ Shares [][]byte
+ ShareIndexK [][]byte
+ ShareIndexV []uint32
+ MasterPublicKey [][]byte
+}
+
+// EncodeRLP implements rlp.Encoder
+func (pubs *PublicKeyShares) EncodeRLP(w io.Writer) error {
+ var rps rlpPublicKeyShares
+ for _, share := range pubs.shares {
+ rps.Shares = append(rps.Shares, share.Serialize())
+ }
+
+ for id, v := range pubs.shareIndex {
+ rps.ShareIndexK = append(rps.ShareIndexK, id.GetLittleEndian())
+ rps.ShareIndexV = append(rps.ShareIndexV, uint32(v))
+ }
+
+ for _, m := range pubs.masterPublicKey {
+ rps.MasterPublicKey = append(rps.MasterPublicKey, m.Serialize())
+ }
+
+ return rlp.Encode(w, rps)
+}
+
+// DecodeRLP implements rlp.Decoder
+func (pubs *PublicKeyShares) DecodeRLP(s *rlp.Stream) error {
+ var dec rlpPublicKeyShares
+ if err := s.Decode(&dec); err != nil {
+ return err
+ }
+
+ if len(dec.ShareIndexK) != len(dec.ShareIndexV) {
+ return fmt.Errorf("invalid shareIndex")
+ }
+
+ ps := NewEmptyPublicKeyShares()
+ for _, share := range dec.Shares {
+ var publicKey PublicKey
+ if err := publicKey.Deserialize(share); err != nil {
+ return err
+ }
+ ps.shares = append(ps.shares, publicKey)
+ }
+
+ for i, k := range dec.ShareIndexK {
+ id, err := BytesID(k)
+ if err != nil {
+ return err
+ }
+ ps.shareIndex[id] = int(dec.ShareIndexV[i])
+ }
+
+ for _, k := range dec.MasterPublicKey {
+ var key bls.PublicKey
+ if err := key.Deserialize(k); err != nil {
+ return err
+ }
+ ps.masterPublicKey = append(ps.masterPublicKey, key)
+ }
+
+ *pubs = *ps
+ return nil
+}
+
// MarshalJSON implements json.Marshaller.
func (pubs *PublicKeyShares) MarshalJSON() ([]byte, error) {
type Alias PublicKeyShares
@@ -130,6 +198,14 @@ func NewID(id []byte) ID {
return blsID
}
+// BytesID creates a new ID structure,
+// It returns err if the byte slice is not valid.
+func BytesID(id []byte) (ID, error) {
+ var blsID bls.ID
+ err := blsID.SetLittleEndian(id)
+ return blsID, err
+}
+
// NewPrivateKey creates a new PrivateKey structure.
func NewPrivateKey() *PrivateKey {
var key bls.SecretKey
@@ -327,6 +403,14 @@ func newPublicKey(prvKey *bls.SecretKey) *PublicKey {
}
}
+// newPublicKeyFromBytes create a new PublicKey structure
+// from bytes representation of bls.PublicKey
+func newPublicKeyFromBytes(b []byte) (*PublicKey, error) {
+ var pub PublicKey
+ err := pub.publicKey.Deserialize(b)
+ return &pub, err
+}
+
// PublicKey returns the public key associate this private key.
func (prv *PrivateKey) PublicKey() crypto.PublicKey {
return prv.publicKey
@@ -380,7 +464,15 @@ func (pub PublicKey) VerifySignature(
// Bytes returns []byte representation of public key.
func (pub PublicKey) Bytes() []byte {
- var bytes []byte
- pub.publicKey.Deserialize(bytes)
- return bytes
+ return pub.publicKey.Serialize()
+}
+
+// Serialize return bytes representation of public key.
+func (pub *PublicKey) Serialize() []byte {
+ return pub.publicKey.Serialize()
+}
+
+// Deserialize parses bytes representation of public key.
+func (pub *PublicKey) Deserialize(b []byte) error {
+ return pub.publicKey.Deserialize(b)
}
diff --git a/core/crypto/dkg/dkg_test.go b/core/crypto/dkg/dkg_test.go
index 84a78f4..fe7ec73 100644
--- a/core/crypto/dkg/dkg_test.go
+++ b/core/crypto/dkg/dkg_test.go
@@ -20,10 +20,12 @@ package dkg
import (
"encoding/binary"
"math/rand"
+ "reflect"
"sort"
"sync"
"testing"
+ "github.com/dexon-foundation/dexon/rlp"
"github.com/stretchr/testify/suite"
"github.com/dexon-foundation/dexon-consensus-core/common"
@@ -290,6 +292,29 @@ func (s *DKGTestSuite) TestSignature() {
s.False(pubKey.VerifySignature(hash, sig))
}
+func (s *DKGTestSuite) TestPublicKeySharesRLPEncodeDecode() {
+ p := NewEmptyPublicKeyShares()
+ for i, id := range s.genID(1) {
+ privkey := NewPrivateKey()
+ pubkey := privkey.PublicKey().(PublicKey)
+ p.shares = append(p.shares, pubkey)
+ p.shareIndex[id] = i
+ p.masterPublicKey = append(p.masterPublicKey, pubkey.publicKey)
+ }
+
+ b, err := rlp.EncodeToBytes(p)
+ s.Require().NoError(err)
+
+ var pp PublicKeyShares
+ err = rlp.DecodeBytes(b, &pp)
+ s.Require().NoError(err)
+
+ bb, err := rlp.EncodeToBytes(&pp)
+ s.Require().NoError(err)
+
+ s.Require().True(reflect.DeepEqual(b, bb))
+}
+
func TestDKG(t *testing.T) {
suite.Run(t, new(DKGTestSuite))
}