예제 #1
0
파일: handlers.go 프로젝트: dedis/cothority
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
}
예제 #2
0
파일: pbft.go 프로젝트: dedis/cothority
// 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
	}
}
예제 #3
0
// 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
}
예제 #4
0
// 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
}
예제 #5
0
// 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
}
예제 #6
0
파일: api.go 프로젝트: dedis/cothority
// 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
}
예제 #7
0
파일: handlers.go 프로젝트: dedis/cothority
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
}
예제 #8
0
// 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
}
예제 #9
0
파일: client.go 프로젝트: dedis/cothority
// 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
}
예제 #10
0
// 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
}
예제 #11
0
파일: api.go 프로젝트: dedis/cothority
// 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
}
예제 #12
0
// 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
}
예제 #13
0
// 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
}
예제 #14
0
// VerifyNoneFunc returns always true.
func (s *Service) VerifyNoneFunc(msg []byte, sb *SkipBlock) bool {
	log.Lvl4("No verification - accepted")
	return true
}