aboutsummaryrefslogtreecommitdiffstats
path: root/core/utils/crypto_test.go
diff options
context:
space:
mode:
authorMission Liao <mission.liao@dexon.org>2018-12-22 12:54:03 +0800
committerGitHub <noreply@github.com>2018-12-22 12:54:03 +0800
commit6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6 (patch)
tree1895248f011a356fcd2a28c03dbda9d93fd46fd8 /core/utils/crypto_test.go
parent146ed32cf841151b826eafd7d6ade188c56865bf (diff)
downloadtangerine-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar.gz
tangerine-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar.zst
tangerine-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.zip
utils: move authenticator to utils package (#378)
Diffstat (limited to 'core/utils/crypto_test.go')
-rw-r--r--core/utils/crypto_test.go282
1 files changed, 282 insertions, 0 deletions
diff --git a/core/utils/crypto_test.go b/core/utils/crypto_test.go
new file mode 100644
index 0000000..f4280c2
--- /dev/null
+++ b/core/utils/crypto_test.go
@@ -0,0 +1,282 @@
+// 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 utils
+
+import (
+ "testing"
+ "time"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
+ "github.com/dexon-foundation/dexon-consensus/core/types"
+ typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
+ "github.com/stretchr/testify/suite"
+)
+
+type CryptoTestSuite struct {
+ suite.Suite
+}
+
+var myNID = types.NodeID{Hash: common.NewRandomHash()}
+
+func (s *CryptoTestSuite) prepareBlock(prevBlock *types.Block) *types.Block {
+ acks := common.Hashes{}
+ now := time.Now().UTC()
+ if prevBlock == nil {
+ return &types.Block{
+ Acks: common.NewSortedHashes(acks),
+ Timestamp: now,
+ Finalization: types.FinalizationResult{
+ Timestamp: time.Now(),
+ Height: 0,
+ },
+ }
+ }
+ s.Require().NotEqual(prevBlock.Hash, common.Hash{})
+ return &types.Block{
+ ParentHash: prevBlock.Hash,
+ Acks: common.NewSortedHashes(acks),
+ Timestamp: now,
+ Position: types.Position{
+ Height: prevBlock.Position.Height + 1,
+ },
+ Finalization: types.FinalizationResult{
+ Timestamp: time.Now(),
+ Height: prevBlock.Finalization.Height + 1,
+ },
+ }
+}
+
+func (s *CryptoTestSuite) newBlock(prevBlock *types.Block) *types.Block {
+ block := s.prepareBlock(prevBlock)
+ var err error
+ block.Hash, err = HashBlock(block)
+ s.Require().NoError(err)
+ return block
+}
+
+func (s *CryptoTestSuite) generateCompactionChain(
+ length int, prv crypto.PrivateKey) []*types.Block {
+ blocks := make([]*types.Block, length)
+ var prevBlock *types.Block
+ for idx := range blocks {
+ block := s.newBlock(prevBlock)
+ prevBlock = block
+ blocks[idx] = block
+ }
+ return blocks
+}
+
+func (s *CryptoTestSuite) generateBlockChain(
+ length int, signer *Signer) []*types.Block {
+ blocks := make([]*types.Block, length)
+ var prevBlock *types.Block
+ for idx := range blocks {
+ block := s.newBlock(prevBlock)
+ blocks[idx] = block
+ err := signer.SignBlock(block)
+ s.Require().NoError(err)
+ }
+ return blocks
+}
+
+func (s *CryptoTestSuite) TestBlockSignature() {
+ prv, err := ecdsa.NewPrivateKey()
+ s.Require().NoError(err)
+ blocks := s.generateBlockChain(10, NewSigner(prv))
+ blockMap := make(map[common.Hash]*types.Block)
+ for _, block := range blocks {
+ blockMap[block.Hash] = block
+ }
+ for _, block := range blocks {
+ if !block.IsGenesis() {
+ parentBlock, exist := blockMap[block.ParentHash]
+ s.Require().True(exist)
+ s.True(parentBlock.Position.Height == block.Position.Height-1)
+ hash, err := HashBlock(parentBlock)
+ s.Require().NoError(err)
+ s.Equal(hash, block.ParentHash)
+ }
+ s.NoError(VerifyBlockSignature(block))
+ }
+ // Modify Block.Acks and verify signature again.
+ for _, block := range blocks {
+ block.Acks = append(block.Acks, common.NewRandomHash())
+ s.Error(VerifyBlockSignature(block))
+ }
+}
+
+func (s *CryptoTestSuite) TestVoteSignature() {
+ prv, err := ecdsa.NewPrivateKey()
+ s.Require().NoError(err)
+ pub := prv.PublicKey()
+ nID := types.NewNodeID(pub)
+ vote := types.NewVote(types.VoteInit, common.NewRandomHash(), 1)
+ vote.ProposerID = nID
+ vote.Signature, err = prv.Sign(hashVote(vote))
+ s.Require().NoError(err)
+ ok, err := VerifyVoteSignature(vote)
+ s.Require().NoError(err)
+ s.True(ok)
+ vote.Type = types.VoteCom
+ ok, err = VerifyVoteSignature(vote)
+ s.Require().NoError(err)
+ s.False(ok)
+}
+
+func (s *CryptoTestSuite) TestCRSSignature() {
+ crs := common.NewRandomHash()
+ prv, err := ecdsa.NewPrivateKey()
+ s.Require().NoError(err)
+ pub := prv.PublicKey()
+ nID := types.NewNodeID(pub)
+ block := &types.Block{
+ ProposerID: nID,
+ }
+ block.CRSSignature, err = prv.Sign(hashCRS(block, crs))
+ s.Require().NoError(err)
+ ok, err := VerifyCRSSignature(block, crs)
+ s.Require().NoError(err)
+ s.True(ok)
+ block.Position.Height++
+ ok, err = VerifyCRSSignature(block, crs)
+ s.Require().NoError(err)
+ s.False(ok)
+}
+
+func (s *CryptoTestSuite) TestDKGSignature() {
+ prv, err := ecdsa.NewPrivateKey()
+ s.Require().NoError(err)
+ nID := types.NewNodeID(prv.PublicKey())
+ prvShare := &typesDKG.PrivateShare{
+ ProposerID: nID,
+ Round: 5,
+ PrivateShare: *dkg.NewPrivateKey(),
+ }
+ prvShare.Signature, err = prv.Sign(hashDKGPrivateShare(prvShare))
+ s.Require().NoError(err)
+ ok, err := VerifyDKGPrivateShareSignature(prvShare)
+ s.Require().NoError(err)
+ s.True(ok)
+ prvShare.Round++
+ ok, err = VerifyDKGPrivateShareSignature(prvShare)
+ s.Require().NoError(err)
+ s.False(ok)
+
+ id := dkg.NewID([]byte{13})
+ _, pkShare := dkg.NewPrivateKeyShares(1)
+ mpk := &typesDKG.MasterPublicKey{
+ ProposerID: nID,
+ Round: 5,
+ DKGID: id,
+ PublicKeyShares: *pkShare,
+ }
+ mpk.Signature, err = prv.Sign(hashDKGMasterPublicKey(mpk))
+ s.Require().NoError(err)
+ ok, err = VerifyDKGMasterPublicKeySignature(mpk)
+ s.Require().NoError(err)
+ s.True(ok)
+ mpk.Round++
+ ok, err = VerifyDKGMasterPublicKeySignature(mpk)
+ s.Require().NoError(err)
+ s.False(ok)
+
+ prvShare.Round = 5
+ prvShare.Signature, err = prv.Sign(hashDKGPrivateShare(prvShare))
+ s.Require().NoError(err)
+ complaint := &typesDKG.Complaint{
+ ProposerID: nID,
+ Round: 5,
+ PrivateShare: *prvShare,
+ }
+ complaint.Signature, err = prv.Sign(hashDKGComplaint(complaint))
+ s.Require().NoError(err)
+ ok, err = VerifyDKGComplaintSignature(complaint)
+ s.Require().NoError(err)
+ s.True(ok)
+ // Test incorrect complaint signature.
+ complaint.Round++
+ ok, err = VerifyDKGComplaintSignature(complaint)
+ s.Require().NoError(err)
+ s.False(ok)
+ // Test mismatch round.
+ complaint.Round--
+ complaint.PrivateShare.Round++
+ complaint.Signature, err = prv.Sign(hashDKGComplaint(complaint))
+ s.Require().NoError(err)
+ ok, err = VerifyDKGComplaintSignature(complaint)
+ s.Require().NoError(err)
+ s.False(ok)
+ // Test incorrect private share signature.
+ complaint.PrivateShare.Round--
+ complaint.PrivateShare.ReceiverID = types.NodeID{Hash: common.NewRandomHash()}
+ complaint.Signature, err = prv.Sign(hashDKGComplaint(complaint))
+ s.Require().NoError(err)
+ ok, err = VerifyDKGComplaintSignature(complaint)
+ s.Require().NoError(err)
+ s.False(ok)
+
+ sig := &typesDKG.PartialSignature{
+ ProposerID: nID,
+ Round: 5,
+ PartialSignature: dkg.PartialSignature{},
+ }
+ sig.Signature, err = prv.Sign(hashDKGPartialSignature(sig))
+ s.Require().NoError(err)
+ ok, err = VerifyDKGPartialSignatureSignature(sig)
+ s.Require().NoError(err)
+ s.True(ok)
+ sig.Round++
+ ok, err = VerifyDKGPartialSignatureSignature(sig)
+ s.Require().NoError(err)
+ s.False(ok)
+
+ ready := &typesDKG.MPKReady{
+ ProposerID: nID,
+ Round: 5,
+ }
+ ready.Signature, err = prv.Sign(hashDKGMPKReady(ready))
+ s.Require().NoError(err)
+ ok, err = VerifyDKGMPKReadySignature(ready)
+ s.Require().NoError(err)
+ s.True(ok)
+ ready.Round++
+ ok, err = VerifyDKGMPKReadySignature(ready)
+ s.Require().NoError(err)
+ s.False(ok)
+
+ final := &typesDKG.Finalize{
+ ProposerID: nID,
+ Round: 5,
+ }
+ final.Signature, err = prv.Sign(hashDKGFinalize(final))
+ s.Require().NoError(err)
+ ok, err = VerifyDKGFinalizeSignature(final)
+ s.Require().NoError(err)
+ s.True(ok)
+ final.Round++
+ ok, err = VerifyDKGFinalizeSignature(final)
+ s.Require().NoError(err)
+ s.False(ok)
+}
+
+func TestCrypto(t *testing.T) {
+ suite.Run(t, new(CryptoTestSuite))
+}