aboutsummaryrefslogblamecommitdiffstats
path: root/core/types/dkg/dkg_test.go
blob: 4eb17ac792fa981cd13e76b2c815000fdcb2ba35 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                                    
  
                                                                        



                                                                               
                                                                         




                                                                           
                                                      

                                  
           

        
                   




                                           



                                                                               






                                               






                                                

                                                         









                                                    
                                              

                                                 

                                                                     
                               
                                








                                                   
                              








                                                                      


                                                                          
                                                      

                                            

                                                                       





                                                      


                                                          


                                                                    
                                     







                                         
                                                                       


                                               
                                                           








                                              
                                                                      


                                         
                                                   
                             


                                                                         
                                
                                                         




                                                      
                                 


                                      
                                                                      


                                             
                                                                      












                                              
                                                        





                                                          
                                                
                             

                                                                       
                              


                                                                                 
                                        
                                                                 








                                                              
                             


                                    
                                                                     



















                                                               






























                                                                       
                                               
                             

                                                                       





                                                      
                             


                                      
                                                                      













                                                                 




                                       
// Copyright 2018 The dexon-consensus Authors
// This file is part of the dexon-consensus library.
//
// The dexon-consensus library is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The dexon-consensus library is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.

package dkg

import (
    "math/rand"
    "reflect"
    "testing"

    "github.com/stretchr/testify/suite"

    "github.com/dexon-foundation/dexon-consensus/common"
    "github.com/dexon-foundation/dexon-consensus/core/crypto"
    cryptoDKG "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg"
    "github.com/dexon-foundation/dexon-consensus/core/types"
    "github.com/dexon-foundation/dexon/rlp"
)

type DKGTestSuite struct {
    suite.Suite
}

func (s *DKGTestSuite) genRandomBytes() []byte {
    randomness := make([]byte, 32)
    _, err := rand.Read(randomness)
    s.Require().NoError(err)
    return randomness
}

func (s *DKGTestSuite) genID() cryptoDKG.ID {
    dID, err := cryptoDKG.BytesID(s.genRandomBytes())
    s.Require().NoError(err)
    return dID
}

func (s *DKGTestSuite) clone(src, dst interface{}) {
    b, err := rlp.EncodeToBytes(src)
    s.Require().NoError(err)
    s.Require().NoError(rlp.DecodeBytes(b, dst))
}

func (s *DKGTestSuite) TestRLPEncodeDecode() {
    dID := s.genID()
    // Prepare master public key for testing.
    d := MasterPublicKey{
        ProposerID: types.NodeID{Hash: common.Hash{1, 2, 3}},
        Round:      10,
        DKGID:      dID,
        Signature: crypto.Signature{
            Type:      "123",
            Signature: []byte{4, 5, 6},
        },
    }

    b, err := rlp.EncodeToBytes(&d)
    s.Require().NoError(err)

    var dd MasterPublicKey
    err = rlp.DecodeBytes(b, &dd)
    s.Require().NoError(err)

    bb, err := rlp.EncodeToBytes(&dd)
    s.Require().NoError(err)
    s.Require().True(reflect.DeepEqual(b, bb))
    s.Require().True(d.ProposerID.Equal(dd.ProposerID))
    s.Require().True(d.Round == dd.Round)
    s.Require().True(reflect.DeepEqual(d.Signature, dd.Signature))
    s.Require().Equal(d.DKGID.GetHexString(), dd.DKGID.GetHexString())
}

func (s *DKGTestSuite) TestMasterPublicKeyEquality() {
    var req = s.Require()
    // Prepare source master public key.
    master1 := &MasterPublicKey{
        ProposerID: types.NodeID{Hash: common.NewRandomHash()},
        Round:      1234,
        DKGID:      s.genID(),
        Signature: crypto.Signature{
            Signature: s.genRandomBytes(),
        },
    }
    prvKey := cryptoDKG.NewPrivateKey()
    pubKey := prvKey.PublicKey().(cryptoDKG.PublicKey)
    _, pubShares := cryptoDKG.NewPrivateKeyShares(2)
    req.NoError(pubShares.AddShare(s.genID(), &pubKey))
    master1.PublicKeyShares = *pubShares
    // Prepare another master public key by copying every field.
    master2 := &MasterPublicKey{}
    s.clone(master1, master2)
    // They should be equal.
    req.True(master1.Equal(master2))
    // Change round.
    master2.Round = 2345
    req.False(master1.Equal(master2))
    master2.Round = 1234
    // Change proposerID.
    master2.ProposerID = types.NodeID{Hash: common.NewRandomHash()}
    req.False(master1.Equal(master2))
    master2.ProposerID = master1.ProposerID
    // Change DKGID.
    master2.DKGID = cryptoDKG.NewID(s.genRandomBytes())
    req.False(master1.Equal(master2))
    master2.DKGID = master1.DKGID
    // Change signature.
    master2.Signature = crypto.Signature{
        Signature: s.genRandomBytes(),
    }
    req.False(master1.Equal(master2))
    master2.Signature = master1.Signature
    // Change public key share.
    master2.PublicKeyShares = *cryptoDKG.NewEmptyPublicKeyShares()
    req.False(master1.Equal(master2))
}

func (s *DKGTestSuite) TestPrivateShareEquality() {
    var req = s.Require()
    share1 := &PrivateShare{
        ProposerID:   types.NodeID{Hash: common.NewRandomHash()},
        ReceiverID:   types.NodeID{Hash: common.NewRandomHash()},
        Round:        1,
        PrivateShare: *cryptoDKG.NewPrivateKey(),
        Signature: crypto.Signature{
            Signature: s.genRandomBytes(),
        },
    }
    // Make a copy.
    share2 := &PrivateShare{}
    s.clone(share1, share2)
    req.True(share1.Equal(share2))
    // Change proposer ID.
    share2.ProposerID = types.NodeID{Hash: common.NewRandomHash()}
    req.False(share1.Equal(share2))
    share2.ProposerID = share1.ProposerID
    // Change receiver ID.
    share2.ReceiverID = types.NodeID{Hash: common.NewRandomHash()}
    req.False(share1.Equal(share2))
    share2.ReceiverID = share1.ReceiverID
    // Change round.
    share2.Round = share1.Round + 1
    req.False(share1.Equal(share2))
    share2.Round = share1.Round
    // Change signature.
    share2.Signature = crypto.Signature{
        Signature: s.genRandomBytes(),
    }
    req.False(share1.Equal(share2))
    share2.Signature = share1.Signature
    // Change private share.
    share2.PrivateShare = *cryptoDKG.NewPrivateKey()
    req.False(share1.Equal(share2))
    share2.PrivateShare = share1.PrivateShare
    // They should be equal after chaning fields back.
    req.True(share1.Equal(share2))
}

func (s *DKGTestSuite) TestComplaintEquality() {
    var req = s.Require()
    comp1 := &Complaint{
        ProposerID: types.NodeID{Hash: common.NewRandomHash()},
        Round:      1,
        PrivateShare: PrivateShare{
            ProposerID:   types.NodeID{Hash: common.NewRandomHash()},
            ReceiverID:   types.NodeID{Hash: common.NewRandomHash()},
            Round:        2,
            PrivateShare: *cryptoDKG.NewPrivateKey(),
            Signature: crypto.Signature{
                Signature: s.genRandomBytes(),
            },
        },
        Signature: crypto.Signature{
            Signature: s.genRandomBytes(),
        },
    }
    // Make a copy.
    comp2 := &Complaint{}
    s.clone(comp1, comp2)
    req.True(comp1.Equal(comp2))
    // Change proposer ID.
    comp2.ProposerID = types.NodeID{Hash: common.NewRandomHash()}
    req.False(comp1.Equal(comp2))
    comp2.ProposerID = comp1.ProposerID
    // Change round.
    comp2.Round = comp1.Round + 1
    req.False(comp1.Equal(comp2))
    comp2.Round = comp1.Round
    // Change signature.
    comp2.Signature = crypto.Signature{
        Signature: s.genRandomBytes(),
    }
    req.False(comp1.Equal(comp2))
    comp2.Signature = comp1.Signature
    // Change share's round.
    comp2.PrivateShare.Round = comp1.PrivateShare.Round + 1
    req.False(comp1.Equal(comp2))
    comp2.PrivateShare.Round = comp1.PrivateShare.Round
    // After changing every field back, should be equal.
    req.True(comp1.Equal(comp2))
}

func (s *DKGTestSuite) TestMPKReadyEquality() {
    var req = s.Require()
    ready1 := &MPKReady{
        ProposerID: types.NodeID{Hash: common.NewRandomHash()},
        Round:      1,
        Signature: crypto.Signature{
            Signature: s.genRandomBytes(),
        },
    }
    // Make a copy
    ready2 := &MPKReady{}
    s.clone(ready1, ready2)
    req.True(ready1.Equal(ready2))
    // Change proposer ID.
    ready2.ProposerID = types.NodeID{Hash: common.NewRandomHash()}
    req.False(ready1.Equal(ready2))
    ready2.ProposerID = ready1.ProposerID
    // Change round.
    ready2.Round = ready1.Round + 1
    req.False(ready1.Equal(ready2))
    ready2.Round = ready1.Round
    // Change signature.
    ready2.Signature = crypto.Signature{
        Signature: s.genRandomBytes(),
    }
    req.False(ready1.Equal(ready2))
    ready2.Signature = ready1.Signature
    // After changing every field back, they should be equal.
    req.True(ready1.Equal(ready2))
}

func (s *DKGTestSuite) TestFinalizeEquality() {
    var req = s.Require()
    final1 := &Finalize{
        ProposerID: types.NodeID{Hash: common.NewRandomHash()},
        Round:      1,
        Signature: crypto.Signature{
            Signature: s.genRandomBytes(),
        },
    }
    // Make a copy
    final2 := &Finalize{}
    s.clone(final1, final2)
    req.True(final1.Equal(final2))
    // Change proposer ID.
    final2.ProposerID = types.NodeID{Hash: common.NewRandomHash()}
    req.False(final1.Equal(final2))
    final2.ProposerID = final1.ProposerID
    // Change round.
    final2.Round = final1.Round + 1
    req.False(final1.Equal(final2))
    final2.Round = final1.Round
    // Change signature.
    final2.Signature = crypto.Signature{
        Signature: s.genRandomBytes(),
    }
    req.False(final1.Equal(final2))
    final2.Signature = final1.Signature
    // After changing every field back, they should be equal.
    req.True(final1.Equal(final2))
}

func TestDKG(t *testing.T) {
    suite.Run(t, new(DKGTestSuite))
}