From ac3187e706bc11f1b36e32015a6e51a96cc8cfe9 Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Sun, 10 Mar 2019 00:39:54 +0800 Subject: core: check if self's privateShare match MPK registered (#474) * core: check if self's privateShare match MPK registered * add test --- core/dkg-tsig-protocol.go | 32 ++++++++++ core/dkg-tsig-protocol_test.go | 136 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) (limited to 'core') diff --git a/core/dkg-tsig-protocol.go b/core/dkg-tsig-protocol.go index 4f15a74..45fe822 100644 --- a/core/dkg-tsig-protocol.go +++ b/core/dkg-tsig-protocol.go @@ -55,6 +55,12 @@ var ( "cache of round already been purged") ErrTSigNotReady = fmt.Errorf( "tsig not ready") + ErrSelfMPKNotRegister = fmt.Errorf( + "self mpk not registered") + ErrUnableGetSelfPrvShare = fmt.Errorf( + "unable to get self DKG PrivateShare") + ErrSelfPrvShareMismatch = fmt.Errorf( + "self privateShare does not match mpk registered") ) type dkgReceiver interface { @@ -186,6 +192,9 @@ func (d *dkgProtocol) processMasterPublicKeys( ids[i] = mpks[i].DKGID } d.masterPrivateShare.SetParticipants(ids) + if err = d.verifySelfPrvShare(); err != nil { + return + } for _, mpk := range mpks { share, ok := d.masterPrivateShare.Share(mpk.DKGID) if !ok { @@ -201,6 +210,26 @@ func (d *dkgProtocol) processMasterPublicKeys( return } +func (d *dkgProtocol) verifySelfPrvShare() error { + selfMPK, exist := d.mpkMap[d.ID] + if !exist { + return ErrSelfMPKNotRegister + } + share, ok := d.masterPrivateShare.Share(d.idMap[d.ID]) + if !ok { + return ErrUnableGetSelfPrvShare + } + ok, err := selfMPK.VerifyPrvShare( + d.idMap[d.ID], share) + if err != nil { + return err + } + if !ok { + return ErrSelfPrvShareMismatch + } + return nil +} + func (d *dkgProtocol) proposeNackComplaints() { for nID := range d.mpkMap { if _, exist := d.prvSharesReceived[nID]; exist { @@ -218,6 +247,9 @@ func (d *dkgProtocol) proposeNackComplaints() { func (d *dkgProtocol) processNackComplaints(complaints []*typesDKG.Complaint) ( err error) { + if err = d.verifySelfPrvShare(); err != nil { + return + } for _, complaint := range complaints { if !complaint.IsNack() { continue diff --git a/core/dkg-tsig-protocol_test.go b/core/dkg-tsig-protocol_test.go index 445a51c..1176bc4 100644 --- a/core/dkg-tsig-protocol_test.go +++ b/core/dkg-tsig-protocol_test.go @@ -178,6 +178,12 @@ func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() { s.Require().Len(recv.complaints, 0) } + for _, receiver := range receivers { + for _, complaint := range receiver.complaints { + gov.AddDKGComplaint(round, complaint) + } + } + for _, protocol := range protocols { s.Require().NoError(protocol.processNackComplaints( gov.DKGComplaints(round))) @@ -247,6 +253,136 @@ func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() { s.True(gpk.VerifySignature(msgHash, sig)) } +func (s *DKGTSIGProtocolTestSuite) TestErrMPKRegistered() { + k := 2 + n := 10 + round := uint64(1) + _, pubKeys, err := test.NewKeys(5) + s.Require().NoError(err) + gov, err := test.NewGovernance(test.NewState(DKGDelayRound, + pubKeys, 100, &common.NullLogger{}, true), ConfigRoundShift) + s.Require().NoError(err) + + receivers, protocols := s.newProtocols(k, n, round) + notRegisterID := s.nIDs[0] + errRegisterID := s.nIDs[1] + + for ID, receiver := range receivers { + if ID == notRegisterID { + continue + } + if ID == errRegisterID { + _, mpk := dkg.NewPrivateKeyShares(k) + receiver.ProposeDKGMasterPublicKey(&typesDKG.MasterPublicKey{ + Round: round, + DKGID: typesDKG.NewID(ID), + PublicKeyShares: *mpk, + }) + } + gov.AddDKGMasterPublicKey(round, receiver.mpk) + } + + for ID, protocol := range protocols { + err := protocol.processMasterPublicKeys(gov.DKGMasterPublicKeys(round)) + if ID == notRegisterID { + s.Require().Equal(ErrSelfMPKNotRegister, err) + } else if ID == errRegisterID { + s.Require().Equal(ErrSelfPrvShareMismatch, err) + } else { + s.Require().NoError(err) + } + } + + for ID, receiver := range receivers { + if ID == notRegisterID || ID == errRegisterID { + continue + } + s.Require().Len(receiver.prvShare, n-1) + for nID, prvShare := range receiver.prvShare { + s.Require().NoError(protocols[nID].processPrivateShare(prvShare)) + } + } + + for ID, protocol := range protocols { + if ID == notRegisterID { + continue + } + protocol.proposeNackComplaints() + } + + for ID, recv := range receivers { + if ID == notRegisterID || ID == errRegisterID { + continue + } + s.Require().Len(recv.complaints, 1) + for _, complaint := range recv.complaints { + s.Require().True(complaint.IsNack()) + s.Require().Equal(errRegisterID, complaint.PrivateShare.ProposerID) + } + } + + for _, receiver := range receivers { + for _, complaint := range receiver.complaints { + gov.AddDKGComplaint(round, complaint) + } + } + + s.Require().Len(gov.DKGComplaints(round), n-1) + + for ID, protocol := range protocols { + err := protocol.processNackComplaints(gov.DKGComplaints(round)) + if ID == notRegisterID { + s.Require().Equal(ErrSelfMPKNotRegister, err) + } else if ID == errRegisterID { + s.Require().Equal(ErrSelfPrvShareMismatch, err) + } else { + s.Require().NoError(err) + } + } + + for _, recv := range receivers { + s.Require().Len(recv.antiComplaints, 0) + } + + for _, protocol := range protocols { + protocol.enforceNackComplaints(gov.DKGComplaints(round)) + } + + for ID, recv := range receivers { + if ID == notRegisterID || ID == errRegisterID { + continue + } + s.Require().Len(recv.complaints, 1) + for _, complaint := range recv.complaints { + s.Require().True(complaint.IsNack()) + s.Require().Equal(errRegisterID, complaint.PrivateShare.ProposerID) + } + } + + // DKG is fininished. + gpk, err := NewDKGGroupPublicKey(round, + gov.DKGMasterPublicKeys(round), gov.DKGComplaints(round), + k, + ) + s.Require().NoError(err) + s.Require().Len(gpk.qualifyIDs, n-2) + qualifyIDs := make(map[dkg.ID]struct{}, len(gpk.qualifyIDs)) + for _, id := range gpk.qualifyIDs { + qualifyIDs[id] = struct{}{} + } + + for nID := range gpk.qualifyNodeIDs { + if nID == notRegisterID || nID == errRegisterID { + continue + } + id, exist := gpk.idMap[nID] + s.Require().True(exist) + _, exist = qualifyIDs[id] + s.Require().True(exist) + } + +} + func (s *DKGTSIGProtocolTestSuite) TestNackComplaint() { k := 3 n := 10 -- cgit v1.2.3