func (p *Protocol) verifySignatureReply(sig *SignatureReply) string { if sig.Index >= len(p.Roster().List) { log.Error("Index in signature reply out of range") return "FAIL" } entity := p.Roster().List[sig.Index] var s string if err := crypto.VerifySchnorr(p.Suite(), entity.Public, p.Message, sig.Sig); err != nil { s = "FAIL" } else { s = "SUCCESS" } return s }
func verifySchnorr(suite abstract.Suite, key abstract.Point, m interface{}) error { // Make a copy of the signature x := reflect.ValueOf(m).Elem().FieldByName("Sig") sig := reflect.New(x.Type()).Elem() sig.Set(x) // Reset signature field reflect.ValueOf(m).Elem().FieldByName("Sig").Set(reflect.ValueOf(crypto.SchnorrSig{})) // XXX: hack // Marshal message mb, err := network.MarshalRegisteredType(m) if err != nil { return err } // Copy back original signature reflect.ValueOf(m).Elem().FieldByName("Sig").Set(sig) // XXX: hack return crypto.VerifySchnorr(suite, key, mb, sig.Interface().(crypto.SchnorrSig)) }
// Go routine that will do the verification of the signature request in // parrallele func (nt *Ntree) verifySignatureRequest(msg *RoundSignatureRequest) { // verification if we have too much exceptions threshold := int(math.Ceil(float64(len(nt.Tree().List())) / 3.0)) if len(msg.Exceptions) > threshold { nt.verifySignatureRequestChan <- false } // verification of all the signatures var goodSig int marshalled, _ := json.Marshal(nt.block) for _, sig := range msg.Sigs { if err := crypto.VerifySchnorr(nt.Suite(), nt.Public(), marshalled, sig); err == nil { goodSig++ } } log.Lvl3(nt.Name(), "Verification of signatures =>", goodSig, "/", len(msg.Sigs), ")") // enough good signatures ? if goodSig <= 2*threshold { nt.verifySignatureRequestChan <- false } nt.verifySignatureRequestChan <- true }
// ProposeVote takes int account a vote for the proposed config. It also verifies // that the voter is in the latest config. // An empty signature signifies that the vote has been rejected. func (s *Service) ProposeVote(v *ProposeVote) (network.Body, onet.ClientError) { log.Lvl2(s, "Voting on proposal") // First verify if the signature is legitimate sid := s.getIdentityStorage(v.ID) if sid == nil { return nil, onet.NewClientErrorCode(ErrorBlockMissing, "Didn't find identity") } // Putting this in a function because of the lock which needs to be held // over all calls that might return an error. cerr := func() onet.ClientError { sid.Lock() defer sid.Unlock() log.Lvl3("Voting on", sid.Proposed.Device) owner, ok := sid.Latest.Device[v.Signer] if !ok { return onet.NewClientErrorCode(ErrorAccountMissing, "Didn't find signer") } if sid.Proposed == nil { return onet.NewClientErrorCode(ErrorConfigMissing, "No proposed block") } hash, err := sid.Proposed.Hash() if err != nil { return onet.NewClientErrorCode(ErrorOnet, "Couldn't get hash") } if _, exists := sid.Votes[v.Signer]; exists { return onet.NewClientErrorCode(ErrorVoteDouble, "Already voted for that block") } log.Lvl3(v.Signer, "voted", v.Signature) if v.Signature != nil { err = crypto.VerifySchnorr(network.Suite, owner.Point, hash, *v.Signature) if err != nil { return onet.NewClientErrorCode(ErrorVoteSignature, "Wrong signature: "+err.Error()) } } return nil }() if cerr != nil { return nil, cerr } // Propagate the vote _, err := s.propagateConfig(sid.Root.Roster, v, propagateTimeout) if err != nil { return nil, onet.NewClientErrorCode(ErrorOnet, cerr.Error()) } if len(sid.Votes) >= sid.Latest.Threshold || len(sid.Votes) == len(sid.Latest.Device) { // If we have enough signatures, make a new data-skipblock and // propagate it log.Lvl3("Having majority or all votes") // Making a new data-skipblock log.Lvl3("Sending data-block with", sid.Proposed.Device) reply, cerr := s.skipchain.ProposeData(sid.Root, sid.Data, sid.Proposed) if cerr != nil { return nil, cerr } _, msg, _ := network.UnmarshalRegistered(reply.Latest.Data) log.Lvl3("SB signed is", msg.(*Config).Device) usb := &UpdateSkipBlock{ ID: v.ID, Latest: reply.Latest, } _, err = s.propagateSkipBlock(sid.Root.Roster, usb, propagateTimeout) if err != nil { return nil, onet.NewClientErrorCode(ErrorOnet, cerr.Error()) } s.save() return &ProposeVoteReply{sid.Data}, nil } return nil, nil }