Beispiel #1
0
// handleCommitChallenge will verify the signature + check if no more than 1/3
// of participants refused to sign.
func (bft *ProtocolBFTCoSi) handleChallengeCommit(ch *ChallengeCommit) error {
	ch.Challenge = bft.commit.Challenge(ch.Challenge)
	hash := bft.Suite().Hash()
	hash.Write(bft.Msg)
	h := hash.Sum(nil)

	// verify if the signature is correct
	if err := cosi.VerifyCosiSignatureWithException(bft.suite,
		bft.AggregatedPublic, h, ch.Signature,
		ch.Exceptions); err != nil {
		log.Error(bft.Name(), "Verification of the signature failed:", err)
		bft.signRefusal = true
	}

	// Check if we have no more than 1/3 failed nodes
	if len(ch.Exceptions) > int(bft.threshold) {
		log.Errorf("More than 1/3 (%d/%d) refused to sign ! ABORT",
			len(ch.Exceptions), len(bft.Roster().List))
		bft.signRefusal = true
	}

	// store the exceptions for later usage
	bft.tempExceptions = ch.Exceptions
	log.Lvl4("BFTCoSi handle Challenge COMMIT")
	if bft.IsLeaf() {
		return bft.startResponseCommit()
	}

	if err := bft.SendToChildrenInParallel(ch); err != nil {
		log.Error(err)
	}
	return nil
}
Beispiel #2
0
func TestBftCoSi(t *testing.T) {
	defer log.AfterTest(t)
	log.TestOutput(testing.Verbose(), 4)

	// Register test protocol using BFTCoSi
	sda.ProtocolRegisterName(TestProtocolName, func(n *sda.TreeNodeInstance) (sda.ProtocolInstance, error) {
		return NewBFTCoSiProtocol(n, verify)
	})

	for _, nbrHosts := range []int{3, 13} {
		countMut.Lock()
		veriCount = 0
		countMut.Unlock()
		log.Lvl2("Running BFTCoSi with", nbrHosts, "hosts")
		local := sda.NewLocalTest()
		_, _, tree := local.GenBigTree(nbrHosts, nbrHosts, 3, true, true)

		done := make(chan bool)
		// create the message we want to sign for this round
		msg := []byte("Hello BFTCoSi")

		// Start the protocol
		node, err := local.CreateProtocol(tree, TestProtocolName)
		if err != nil {
			t.Fatal("Couldn't create new node:", err)
		}

		// Register the function generating the protocol instance
		var root *ProtocolBFTCoSi
		root = node.(*ProtocolBFTCoSi)
		root.Msg = msg
		// function that will be called when protocol is finished by the root
		root.RegisterOnDone(func() {
			done <- true
		})
		go node.Start()
		// are we done yet?
		wait := time.Second * 3
		select {
		case <-done:
			countMut.Lock()
			assert.Equal(t, veriCount, nbrHosts,
				"Each host should have called verification.")
			// if assert fails we don't care for unlocking (t.Fail)
			countMut.Unlock()
			sig := root.Signature()
			if err := cosi.VerifyCosiSignatureWithException(root.Suite(),
				root.AggregatedPublic, msg, sig.Sig,
				sig.Exceptions); err != nil {

				t.Fatal(fmt.Sprintf("%s Verification of the signature failed: %s", root.Name(), err.Error()))
			}
		case <-time.After(wait):
			t.Fatal("Waited", wait, "sec for BFTCoSi to finish ...")
		}
		local.CloseAll()
	}
}
Beispiel #3
0
// Verify returns whether the verification of the signature succeeds or not.
func (bs *BFTSignature) Verify(s abstract.Suite, agg abstract.Point, msg []byte) error {
	return cosi.VerifyCosiSignatureWithException(s, agg, msg, bs.Sig, bs.Exceptions)
}