diff options
-rw-r--r-- | core/dkg-tsig-protocol.go | 20 | ||||
-rw-r--r-- | core/dkg-tsig-protocol_test.go | 74 |
2 files changed, 83 insertions, 11 deletions
diff --git a/core/dkg-tsig-protocol.go b/core/dkg-tsig-protocol.go index c549ecb..2db18f1 100644 --- a/core/dkg-tsig-protocol.go +++ b/core/dkg-tsig-protocol.go @@ -67,6 +67,7 @@ type dkgProtocol struct { mpkMap map[types.ValidatorID]*dkg.PublicKeyShares masterPrivateShare *dkg.PrivateKeyShares prvShares *dkg.PrivateKeyShares + prvSharesReceived map[types.ValidatorID]struct{} } type dkgShareSecret struct { @@ -119,6 +120,7 @@ func newDKGProtocol( mpkMap: make(map[types.ValidatorID]*dkg.PublicKeyShares), masterPrivateShare: prvShare, prvShares: dkg.NewEmptyPrivateKeyShares(), + prvSharesReceived: make(map[types.ValidatorID]struct{}), } } @@ -126,6 +128,7 @@ func (d *dkgProtocol) processMasterPublicKeys( mpks []*types.DKGMasterPublicKey) error { d.idMap = make(map[types.ValidatorID]dkg.ID, len(mpks)) d.mpkMap = make(map[types.ValidatorID]*dkg.PublicKeyShares, len(mpks)) + d.prvSharesReceived = make(map[types.ValidatorID]struct{}, len(mpks)) ids := make(dkg.IDs, len(mpks)) for i := range mpks { vID := mpks[i].ProposerID @@ -148,6 +151,22 @@ func (d *dkgProtocol) processMasterPublicKeys( return nil } +func (d *dkgProtocol) proposeNackComplaints() { + for vID := range d.mpkMap { + if _, exist := d.prvSharesReceived[vID]; exist { + continue + } + d.recv.ProposeDKGComplaint(&types.DKGComplaint{ + ProposerID: d.ID, + Round: d.round, + PrivateShare: types.DKGPrivateShare{ + ProposerID: vID, + Round: d.round, + }, + }) + } +} + func (d *dkgProtocol) sanityCheck(prvShare *types.DKGPrivateShare) error { if _, exist := d.idMap[prvShare.ProposerID]; !exist { return ErrNotDKGParticipant @@ -180,6 +199,7 @@ func (d *dkgProtocol) processPrivateShare( if err != nil { return err } + d.prvSharesReceived[prvShare.ProposerID] = struct{}{} if !ok { complaint := &types.DKGComplaint{ ProposerID: d.ID, diff --git a/core/dkg-tsig-protocol_test.go b/core/dkg-tsig-protocol_test.go index f1c0017..1ea65b2 100644 --- a/core/dkg-tsig-protocol_test.go +++ b/core/dkg-tsig-protocol_test.go @@ -60,7 +60,7 @@ func (r *testDKGReceiver) ProposeDKGComplaint(complaint *types.DKGComplaint) { var err error complaint.Signature, err = r.prvKey.Sign(hashDKGComplaint(complaint)) r.s.Require().NoError(err) - r.complaints[complaint.ProposerID] = complaint + r.complaints[complaint.PrivateShare.ProposerID] = complaint } func (r *testDKGReceiver) ProposeDKGMasterPublicKey( @@ -95,16 +95,8 @@ func (s *DKGTSIGProtocolTestSuite) setupDKGParticipants(n int) { } } -// TestDKGTSIGProtocol will test the entire DKG+TISG protocol including -// exchanging private shares, recovering share secret, creating partial sign and -// recovering threshold signature. -// All participants are good people in this test. -func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() { - k := 3 - n := 10 - round := uint64(1) - gov, err := test.NewGovernance(5, 100) - s.Require().NoError(err) +func (s *DKGTSIGProtocolTestSuite) newProtocols(k, n int, round uint64) ( + map[types.ValidatorID]*testDKGReceiver, map[types.ValidatorID]*dkgProtocol) { s.setupDKGParticipants(n) receivers := make(map[types.ValidatorID]*testDKGReceiver, n) @@ -120,6 +112,21 @@ func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() { ) s.Require().NotNil(receivers[vID].mpk) } + return receivers, protocols +} + +// TestDKGTSIGProtocol will test the entire DKG+TISG protocol including +// exchanging private shares, recovering share secret, creating partial sign and +// recovering threshold signature. +// All participants are good people in this test. +func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() { + k := 3 + n := 10 + round := uint64(1) + gov, err := test.NewGovernance(5, 100) + s.Require().NoError(err) + + receivers, protocols := s.newProtocols(k, n, round) for _, receiver := range receivers { gov.AddDKGMasterPublicKey(receiver.mpk) @@ -137,6 +144,10 @@ func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() { } } + for _, protocol := range protocols { + protocol.proposeNackComplaints() + } + for _, recv := range receivers { s.Require().Len(recv.complaints, 0) } @@ -186,6 +197,47 @@ func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() { s.True(gpk.verifySignature(msgHash, sig)) } +func (s *DKGTSIGProtocolTestSuite) TestNackComplaint() { + k := 3 + n := 10 + round := uint64(1) + gov, err := test.NewGovernance(5, 100) + s.Require().NoError(err) + + receivers, protocols := s.newProtocols(k, n, round) + + byzantineID := s.vIDs[0] + + for _, receiver := range receivers { + gov.AddDKGMasterPublicKey(receiver.mpk) + } + + for _, protocol := range protocols { + s.Require().NoError( + protocol.processMasterPublicKeys(gov.DKGMasterPublicKeys(round))) + } + + for senderID, receiver := range receivers { + s.Require().Len(receiver.prvShare, n) + if senderID == byzantineID { + continue + } + for vID, prvShare := range receiver.prvShare { + s.Require().NoError(protocols[vID].processPrivateShare(prvShare)) + } + } + + for _, protocol := range protocols { + protocol.proposeNackComplaints() + } + + for _, recv := range receivers { + complaint, exist := recv.complaints[byzantineID] + s.Require().True(exist) + s.True(verifyDKGComplaintSignature(complaint, eth.SigToPub)) + } +} + func TestDKGTSIGProtocol(t *testing.T) { suite.Run(t, new(DKGTSIGProtocolTestSuite)) } |