func (jv *JVSS) handleSecInit(m WSecInitMsg) error { msg := m.SecInitMsg log.Lvl4(jv.Name(), jv.Index(), "Received SecInit from", m.TreeNode.Name()) // Initialise shared secret if err := jv.initSecret(msg.SID); err != nil { return err } // Unmarshal received deal deal := new(poly.Deal).UnmarshalInit(jv.info.T, jv.info.R, jv.info.N, jv.keyPair.Suite) if err := deal.UnmarshalBinary(msg.Deal); err != nil { return err } // Buffer received deal for later secret, err := jv.secrets.secret(msg.SID) if err != nil { return err } secret.deals[msg.Src] = deal // Finalise shared secret if err := jv.finaliseSecret(msg.SID); err != nil { log.Error(jv.Index(), err) return err } log.Lvl4("Finished handleSecInit", jv.Name(), msg.SID) return nil }
// handleCommit receives commit messages and signal the end if it received // enough of it. func (p *Protocol) handleCommit(com *Commit) { if p.state != stateCommit { // log.Lvl3(p.Name(), "STORE handle commit packet") p.tempCommitMsg = append(p.tempCommitMsg, com) return } // finish after threshold of Commit msgs p.commitMsgCount++ log.Lvl4(p.Name(), "----------------\nWe got", p.commitMsgCount, "COMMIT msgs and threshold is", p.threshold) if p.IsRoot() { log.Lvl4("Leader got ", p.commitMsgCount) } if p.commitMsgCount >= p.threshold { p.state = stateFinished // reset counter p.commitMsgCount = 0 log.Lvl3(p.Name(), "Threshold reached: We are done... CONSENSUS") if p.IsRoot() && p.onDoneCB != nil { log.Lvl3(p.Name(), "We are root and threshold reached: return to the simulation.") p.onDoneCB() p.finish() } return } }
// addForwardLinks checks if we have a valid link connecting the two // SkipBlocks with each other. func (s *Service) addForwardLinks(newest *SkipBlock) ([]*SkipBlock, error) { height := len(newest.BackLinkIds) blocks := make([]*SkipBlock, height+1) blocks[0] = newest for h := range newest.BackLinkIds { log.Lvl4("Searching forward-link for", h) b, ok := s.getSkipBlockByID(newest.BackLinkIds[h]) if !ok { return nil, errors.New("Found unknwon backlink in block") } bc := b.Copy() log.Lvl4("Checking", b.Index, b, len(bc.ForwardLink)) if len(bc.ForwardLink) >= h+1 { return nil, errors.New("Backlinking to a block which has a forwardlink") } for len(bc.ForwardLink) < h+1 { fl := NewBlockLink() fl.Hash = newest.Hash bc.ForwardLink = append(bc.ForwardLink, fl) } log.Lvl4("Block has now height of", len(bc.ForwardLink)) blocks[h+1] = bc } return blocks, nil }
// Dispatch can handle timeouts func (p *Propagate) Dispatch() error { process := true log.Lvl4(p.ServerIdentity()) for process { p.Lock() timeout := time.Millisecond * time.Duration(p.sd.Msec) p.Unlock() select { case msg := <-p.ChannelSD: log.Lvl3(p.ServerIdentity(), "Got data from", msg.ServerIdentity, "and setting timeout to", msg.Msec) p.sd.Msec = msg.Msec if p.onData != nil { _, netMsg, err := network.UnmarshalRegistered(msg.Data) if err == nil { p.onData(netMsg) } } if !p.IsRoot() { log.Lvl3(p.ServerIdentity(), "Sending to parent") p.SendToParent(&PropagateReply{}) } if p.IsLeaf() { process = false } else { log.Lvl3(p.ServerIdentity(), "Sending to children") p.SendToChildren(&msg.PropagateSendData) } case <-p.ChannelReply: p.received++ log.Lvl4(p.ServerIdentity(), "received:", p.received, p.subtreeCount) if !p.IsRoot() { p.SendToParent(&PropagateReply{}) } if p.received == p.subtreeCount { process = false } case <-time.After(timeout): _, a, err := network.UnmarshalRegistered(p.sd.Data) log.Fatalf("Timeout of %s reached. %v %s", timeout, a, err) process = false } } if p.IsRoot() { if p.onDoneCb != nil { p.onDoneCb(p.received + 1) } } p.Done() return nil }
// signNewSkipBlock should start a BFT-signature on the newest block // which will propagate and update all forward-links of all blocks. // As a simple solution it verifies the validity of the block, // simulates a signature and propagates the latest and newest block. func (s *Service) signNewSkipBlock(latest, newest *SkipBlock) (*SkipBlock, *SkipBlock, error) { log.Lvl4("Signing new block", newest, "on block", latest) if newest != nil && newest.Roster == nil { log.Lvl3("Got a data-block") if newest.ParentBlockID.IsNull() { return nil, nil, onet.NewClientErrorCode(ErrorBlockNoParent, "Data skipblock without parent") } parent, ok := s.getSkipBlockByID(newest.ParentBlockID) if !ok { return nil, nil, onet.NewClientErrorCode(ErrorBlockNoParent, "Didn't find parent block") } newest.Roster = parent.Roster } // Now verify if it's a valid block if err := s.verifyNewSkipBlock(latest, newest); err != nil { return nil, nil, onet.NewClientErrorCode(ErrorVerification, "Verification of newest SkipBlock failed: "+err.Error()) } // Sign it err := s.startBFTSignature(newest) if err != nil { return nil, nil, err } if err := newest.VerifySignatures(); err != nil { log.Error("Couldn't verify signature: " + err.Error()) return nil, nil, err } newblocks := make([]*SkipBlock, 1) if latest == nil { // Genesis-block only newblocks[0] = newest } else { // Adjust forward-links if it's an additional block var err error newblocks, err = s.addForwardLinks(newest) if err != nil { return nil, nil, err } latest = newblocks[1] } // Store and propagate the new SkipBlocks log.Lvl4("Finished signing new block", newest) if err = s.startPropagation(newblocks); err != nil { return nil, nil, err } return latest, newblocks[0], nil }
// SendToGuard is the function that sends a request to the guard server from the client and receives the responses func (c *Client) SendToGuard(dst *network.ServerIdentity, UID []byte, epoch []byte, t abstract.Point) (*Response, onet.ClientError) { //send request an entity in the network log.Lvl4("Sending Request to ", dst) serviceReq := &Request{UID, epoch, t} reply := &Response{} cerr := c.SendProtobuf(dst, serviceReq, reply) if cerr != nil { return nil, cerr } return reply, nil }
func (jv *JVSS) handleSecConf(m WSecConfMsg) error { msg := m.SecConfMsg secret, err := jv.secrets.secret(msg.SID) if err != nil { log.Lvl2(jv.Index(), err, "for sid=", msg.SID) return nil } isShortTermSecret := strings.HasPrefix(string(msg.SID), string(STSS)) if isShortTermSecret { secret.nShortConfirmsMtx.Lock() defer secret.nShortConfirmsMtx.Unlock() secret.numShortConfs++ } else { secret.nLongConfirmsMtx.Lock() defer secret.nLongConfirmsMtx.Unlock() secret.numLongtermConfs++ } // Check if we are the initiator node and have enough confirmations to proceed if msg.SID.IsLTSS() && secret.numLongtermConfs == len(jv.List()) && jv.sidStore.exists(msg.SID) { log.Lvl4("Writing to longTermSecDone") jv.longTermSecDone <- true secret.numLongtermConfs = 0 } else if msg.SID.IsSTSS() && secret.numShortConfs == len(jv.List()) && jv.sidStore.exists(msg.SID) { log.Lvl4("Writing to shortTermSecDone") jv.shortTermSecDone <- true secret.numShortConfs = 0 } else { n := secret.numLongtermConfs if isShortTermSecret { n = secret.numShortConfs } log.Lvl4("Node %d: %s confirmations %d/%d", jv.Index(), msg.SID, n, len(jv.List())) } return nil }
// Verify function that returns true if the length of the data is 1. func verify(m []byte, d []byte) bool { c, err := strconv.Atoi(string(d)) log.ErrFatal(err) counter := counters.get(c) counter.Lock() counter.veriCount++ log.Lvl4("Verification called", counter.veriCount, "times") counter.Unlock() if len(d) == 0 { log.Error("Didn't receive correct data") return false } return true }
// verify takes a file and a group-definition, calls the signature // verification and prints the result. If sigFileName is empty it // assumes to find the standard signature in fileName.sig func verify(fileName, sigFileName, groupToml string) error { // if the file hash matches the one in the signature log.Lvl4("Reading file " + fileName) b, err := ioutil.ReadFile(fileName) if err != nil { return errors.New("Couldn't open msgFile: " + err.Error()) } // Read the JSON signature file log.Lvl4("Reading signature") var sigBytes []byte if sigFileName == "" { log.Print("[+] Reading signature from standard input ...") sigBytes, err = ioutil.ReadAll(os.Stdin) } else { sigBytes, err = ioutil.ReadFile(sigFileName) } if err != nil { return err } sig := &s.SignatureResponse{} log.Lvl4("Unmarshalling signature ") if err := json.Unmarshal(sigBytes, sig); err != nil { return err } fGroup, err := os.Open(groupToml) if err != nil { return err } log.Lvl4("Reading group definition") el, err := config.ReadGroupToml(fGroup) if err != nil { return err } log.Lvl4("Verfifying signature") err = verifySignatureHash(b, sig, el) return err }
// Verify-function that will refuse if the `called` bit is 0. func verifyRefuseBit(m []byte, d []byte) bool { c, err := strconv.Atoi(string(d)) log.ErrFatal(err) counter := counters.get(c) counter.Lock() defer counter.Unlock() log.Lvl4("Counter", c, counter.refuseCount, counter.veriCount) myBit := uint(counter.veriCount) counter.veriCount++ if counter.refuseCount&(1<<myBit) != 0 { log.Lvl2("Refusing for myBit ==", myBit) return false } log.Lvl3("Verification called", counter.veriCount, "times") return true }
// SignatureRequest sends a CoSi sign request to the Cothority defined by the given // Roster func (c *Client) SignatureRequest(r *onet.Roster, msg []byte) (*SignatureResponse, error) { serviceReq := &SignatureRequest{ Roster: r, Message: msg, } if len(r.List) == 0 { return nil, errors.New("Got an empty roster-list") } dst := r.List[0] log.Lvl4("Sending message to", dst) reply := &SignatureResponse{} cerr := c.SendProtobuf(dst, serviceReq, reply) if cerr != nil { return nil, cerr } return reply, nil }
// Start will contact everyone and make the connections func (p *Propagate) Start() error { log.Lvl4("going to contact", p.Root().ServerIdentity) p.SendTo(p.Root(), p.sd) return nil }
// ProposeSkipBlock takes a hash for the latest valid SkipBlock and a SkipBlock // that will be verified. If the verification returns true, the new SkipBlock // will be signed and added to the chain and returned. // If the the latest block given is nil it verify if we are actually creating // the first (genesis) block and creates it. If it is called with nil although // there already exist previous blocks, it will return an error. func (s *Service) ProposeSkipBlock(psbd *ProposeSkipBlock) (network.Body, onet.ClientError) { prop := psbd.Proposed var prev *SkipBlock if !psbd.LatestID.IsNull() { // We're appending a block to an existing chain var ok bool prev, ok = s.getSkipBlockByID(psbd.LatestID) if !ok { return nil, onet.NewClientErrorCode(ErrorBlockNotFound, "Didn't find latest block") } prop.MaximumHeight = prev.MaximumHeight prop.BaseHeight = prev.BaseHeight prop.ParentBlockID = prev.ParentBlockID prop.VerifierID = prev.VerifierID prop.Index = prev.Index + 1 index := prop.Index for prop.Height = 1; index%prop.BaseHeight == 0; prop.Height++ { index /= prop.BaseHeight if prop.Height >= prop.MaximumHeight { break } } log.Lvl4("Found height", prop.Height, "for index", prop.Index, "and maxHeight", prop.MaximumHeight, "and base", prop.BaseHeight) prop.BackLinkIds = make([]SkipBlockID, prop.Height) pointer := prev for h := range prop.BackLinkIds { for pointer.Height < h+1 { var ok bool pointer, ok = s.getSkipBlockByID(pointer.BackLinkIds[0]) if !ok { return nil, onet.NewClientErrorCode(ErrorBlockNotFound, "Didn't find convenient SkipBlock for height "+ strconv.Itoa(h)) } } prop.BackLinkIds[h] = pointer.Hash } } else { // A new chain is created, suppose all arguments in SkipBlock // are correctly set up prop.Index = 0 if prop.MaximumHeight == 0 { return nil, onet.NewClientErrorCode(ErrorParameterWrong, "Set a maximumHeight > 0") } if prop.BaseHeight == 0 { return nil, onet.NewClientErrorCode(ErrorParameterWrong, "Set a baseHeight > 0") } prop.Height = prop.MaximumHeight prop.ForwardLink = make([]*BlockLink, 0) // genesis block has a random back-link: bl := make([]byte, 32) rand.Read(bl) prop.BackLinkIds = []SkipBlockID{SkipBlockID(bl)} } if prop.Roster != nil { prop.Aggregate = prop.Roster.Aggregate } el, cerr := prop.GetResponsible(s) if cerr != nil { return nil, cerr } prop.AggregateResp = el.Aggregate prop.updateHash() var err error prev, prop, err = s.signNewSkipBlock(prev, prop) if err != nil { return nil, onet.NewClientErrorCode(ErrorVerification, "Verification error: "+err.Error()) } s.save() reply := &ProposedSkipBlockReply{ Previous: prev, Latest: prop, } return reply, nil }
// VerifyNoneFunc returns always true. func (s *Service) VerifyNoneFunc(msg []byte, sb *SkipBlock) bool { log.Lvl4("No verification - accepted") return true }