예제 #1
0
func (round *RoundMeasure) Announcement(viewNbr, roundNbr int, in *sign.SigningMessage, out []*sign.SigningMessage) error {
	if round.IsRoot {
		round.measure = monitor.NewMeasure("round")
	}
	return round.RoundCosi.Announcement(viewNbr, roundNbr, in, out)
}
예제 #2
0
파일: server.go 프로젝트: mlncn/cothority
// This is the leader who waits for all connections and then sends the
// message to be signed
func GoLeader(conf *app.NaiveConfig) {

	host := net.NewTcpHost(app.RunFlags.Hostname)
	key := cliutils.KeyPair(suite)
	leader := NewPeer(host, LeadRole, key.Secret, key.Public)

	// Setting up the connections
	// notably to the monitoring process
	if app.RunFlags.Logger != "" {
		monitor.ConnectSink(app.RunFlags.Logger)
	} else {
		monitor.EnableMeasure(false)
	}
	msg := []byte("Hello World\n")
	// Listen for connections
	dbg.Lvl3(leader.String(), "making connections ...")
	// each conn will create its own channel to be used to handle rounds
	roundChans := make(chan chan chan *net.BasicSignature)
	// Send the message to be signed
	proto := func(c net.Conn) {
		// make the chan that will receive a new chan
		// for each round where to send the signature
		roundChan := make(chan chan *net.BasicSignature)
		roundChans <- roundChan
		n := 0
		// wait for the next round
		for sigChan := range roundChan {
			dbg.Lvl3(leader.String(), "Round", n, "sending message", msg, "to signer", c.PeerName())
			leader.SendMessage(msg, c)
			dbg.Lvl3(leader.String(), "Round", n, "receivng signature from signer", c.PeerName())
			sig := leader.ReceiveBasicSignature(c)
			sigChan <- sig
			n += 1
		}
		c.Close()
		dbg.Lvl3(leader.String(), "closed connection with signer", c.PeerName())
	}

	// Connecting to the signer
	setup := monitor.NewMeasure("setup")
	go leader.Listen(app.RunFlags.Hostname, proto)
	dbg.Lvl3(leader.String(), "Listening for channels creation..")
	// listen for round chans + signatures for each round
	masterRoundChan := make(chan chan *net.BasicSignature)
	roundChanns := make([]chan chan *net.BasicSignature, 0)
	numberHosts := len(conf.Hosts)
	//  Make the "setup" of channels
	for {
		ch := <-roundChans
		roundChanns = append(roundChanns, ch)
		//Received round channels from every connections-
		if len(roundChanns) == numberHosts-1 {
			// make the Fanout => master will send to all
			go func() {
				// send the new SignatureChannel to every conn
				for newSigChan := range masterRoundChan {
					for i, _ := range roundChanns {
						go func(j int) { roundChanns[j] <- newSigChan }(i)
					}
				}
				//close when finished
				for _, c := range roundChanns {
					close(c)
				}
			}()
			break
		}
	}
	setup.Measure()
	dbg.Lvl3(leader.String(), "got all channels ready => starting the", conf.Rounds, "rounds")

	// Starting to run the simulation for conf.Rounds rounds

	roundM := monitor.NewMeasure("round")
	for round := 0; round < conf.Rounds; round++ {
		// Measure calculation time
		calc := monitor.NewMeasure("calc")
		dbg.Lvl1("Server starting round", round+1)
		n := 0
		faulty := 0
		// launch a new round
		connChan := make(chan *net.BasicSignature)
		masterRoundChan <- connChan

		// Wait each signatures
		sigs := make([]*net.BasicSignature, 0)
		for n < numberHosts-1 {
			bs := <-connChan
			sigs = append(sigs, bs)
			n += 1
		}
		// All sigs reeived <=> all calcs are done
		calc.Measure()

		// verify each signatures
		if conf.SkipChecks {
			dbg.Lvl3("Skipping check for round", round)
		} else {
			// Measure verificationt time
			verify := monitor.NewMeasure("verify")
			for _, sig := range sigs {
				if err := SchnorrVerify(suite, msg, *sig); err != nil {
					faulty += 1
					dbg.Lvl1(leader.String(), "Round", round, "received a faulty signature!")
				} else {
					dbg.Lvl3(leader.String(), "Round", round, "received Good signature")
				}
			}
			verify.Measure()
		}
		roundM.Measure()
		dbg.Lvl3(leader.String(), "Round", round, "received", len(conf.Hosts)-1, "signatures (",
			faulty, "faulty sign)")
	}

	// Close down all connections
	close(masterRoundChan)
	dbg.Lvl3(leader.String(), "has done all rounds")
}
예제 #3
0
파일: server.go 프로젝트: mlncn/cothority
func RunServer(conf *app.ConfigShamir) {
	flags := app.RunFlags
	s := edwards.NewAES128SHA256Ed25519(false)
	n := len(conf.Hosts)

	info := poly.Threshold{
		N: n,
		R: n,
		T: n,
	}
	indexPeer := -1
	for i, h := range conf.Hosts {
		if h == flags.Hostname {
			indexPeer = i
			break
		}
	}
	if indexPeer == -1 {
		log.Fatal("Peer", flags.Hostname, "(", flags.PhysAddr, ") did not find any match for its name.Abort")
	}

	dbg.Lvl3("Creating new peer", flags.Hostname, "(", flags.PhysAddr, ") ...")
	// indexPeer == 0 <==> peer is root
	p := NewPeer(indexPeer, flags.Hostname, s, info, indexPeer == 0)

	// make it listen
	setup := monitor.NewMeasure("setup")
	dbg.Lvl3("Peer", flags.Hostname, "is now listening for incoming connections")
	go p.Listen()

	// then connect it to its successor in the list
	for _, h := range conf.Hosts[indexPeer+1:] {
		dbg.Lvl3("Peer", flags.Hostname, "will connect to", h)
		// will connect and SYN with the remote peer
		p.ConnectTo(h)
	}
	// Wait until this peer is connected / SYN'd with each other peer
	p.WaitSYNs()

	// Setup the schnorr system amongst peers
	p.SetupDistributedSchnorr()
	p.SendACKs()
	p.WaitACKs()
	dbg.Lvl3(p.String(), "completed Schnorr setup")

	// send setup time if we're root
	if p.IsRoot() {
		setup.Measure()
	}

	roundm := monitor.NewMeasure("round")
	for round := 1; round <= conf.Rounds; round++ {
		calc := monitor.NewMeasure("calc")
		// Then issue a signature !
		//sys, usr := app.GetRTime()
		msg := "hello world"

		// Only root calculates if it's OK and sends a log-message
		if p.IsRoot() {
			dbg.Lvl1("Starting round", round)
			sig := p.SchnorrSigRoot([]byte(msg))
			calc.Measure()
			verify := monitor.NewMeasure("verify")
			err := p.VerifySchnorrSig(sig, []byte(msg))
			if err != nil {
				dbg.Fatal(p.String(), "could not verify schnorr signature:/", err)
			}
			verify.Measure()
			roundm.Measure()
			dbg.Lvl3(p.String(), "verified the schnorr sig !")
		} else {
			// Compute the partial sig and send it to the root
			p.SchnorrSigPeer([]byte(msg))
		}
	}

	p.WaitFins()
	dbg.Lvl3(p.String(), "is leaving ...")

	if p.IsRoot() {
		monitor.End()
	}
}
예제 #4
0
func main() {
	conf := &app.ConfigColl{}
	app.ReadConfig(conf)

	// we must know who we are
	if app.RunFlags.Hostname == "" {
		dbg.Fatal("Hostname empty: Abort")
	}

	// Do some common setup
	if app.RunFlags.Mode == "client" {
		app.RunFlags.Hostname = app.RunFlags.Name
	}
	hostname := app.RunFlags.Hostname
	if hostname == conf.Hosts[0] {
		dbg.Lvlf3("Tree is %+v", conf.Tree)
	}
	dbg.Lvl3(hostname, "Starting to run")

	app.RunFlags.StartedUp(len(conf.Hosts))
	peer := conode.NewPeer(hostname, conf.ConfigConode)

	Releases = make(map[string]CommitEntry)
	//ReleaseInformation()
	ReadRelease(PolicyFile, SignaturesFile, CommitIdFile)

	if app.RunFlags.AmRoot {
		err := peer.WaitRoundSetup(len(conf.Hosts), 5, 2)
		if err != nil {
			dbg.Fatal(err)
		}
		dbg.Lvl1("Starting the rounds")
	}

	if app.RunFlags.AmRoot {
		for round := 0; round < conf.Rounds; round++ {
			dbg.Lvl1("Doing round", round, "of", conf.Rounds)
			wallTime := monitor.NewMeasure("round")
			hashToSign, _ := CommitScanner(CommitIdFile) // retrieve commitid/hash that the root is willing to get signed

			entry := Releases[hashToSign]
			if entry.policy != "" && entry.signatures != "" {
				rootpgpTime := monitor.NewMeasure("rootpgp")
				decision, err := ApprovalCheck(entry.policy, entry.signatures, hashToSign)
				rootpgpTime.Measure()

				if decision && err == nil {
					round := NewRoundSwsign(peer.Node)
					round.Hash = []byte(hashToSign) // passing hash of the file that we want to produce a signature for
					peer.StartAnnouncement(round)

					wallTime.Measure()
					Signature := <-round.Signature
					dbg.Lvlf1("Received signature %+v", Signature)
				} else {
					dbg.Fatal("Developers related to the root haven't approved the release so the root didn't start signing process")
				}
			} else {
				dbg.Error("There is no input with such commitid", hashToSign)
			}
		}
		peer.SendCloseAll()
	} else {
		peer.LoopRounds(RoundSwsignType, conf.Rounds)
	}

	dbg.Lvlf3("Done - flags are %+v", app.RunFlags)
	monitor.End()
}
예제 #5
0
파일: sign.go 프로젝트: mlncn/cothority
func RunRoot(conf *app.NTreeConfig) {
	host := net.NewTcpHost(app.RunFlags.Hostname)
	key := cliutils.KeyPair(suite)

	peer := NewPeer(host, LeadRole, key.Secret, key.Public)
	dbg.Lvl3(peer.String(), "Up and will make connections...")

	// monitor
	if app.RunFlags.Logger == "" {
		monitor.EnableMeasure(false)
	} else {
		if err := monitor.ConnectSink(app.RunFlags.Logger); err != nil {
			dbg.Fatal(peer.String(), "could not connect to the monitor:", err)
		}
	}

	// msg to be sent + signed
	msg := []byte("Hello World")

	// make setup measurement
	setup := monitor.NewMeasure("setup")

	// masterRoundChan is used to tell that everyone is ready
	masterRoundChan := make(chan chan chan *net.ListBasicSignature)
	// Open connection for each children
	for _, c := range conf.Tree.Children {
		dbg.Lvl3(peer.String(), "will connect to children", c.Name)

		connPeer := peer.Open(c.Name)
		if connPeer == nil {
			dbg.Fatal(peer.String(), "Could not open connection to child", c.Name)
		}
		// then start Root protocol
		go func(conn net.Conn) {
			dbg.Lvl3(peer.String(), "connected to children", conn.PeerName())
			roundSigChan := make(chan chan *net.ListBasicSignature)
			// notify we are ready to begin
			masterRoundChan <- roundSigChan
			// each rounds...
			for lsigChan := range roundSigChan {
				dbg.Lvl4(peer.String(), "starting new round with", conn.PeerName())
				m := net.MessageSigning{
					Length: len(msg),
					Msg:    msg,
				}
				// send msg to children
				err := conn.Send(m)
				if err != nil {
					dbg.Fatal(peer.String(), "could not send message to children", conn.PeerName(), ":", err)
				}
				dbg.Lvl3(peer.String(), "sent message to children", conn.PeerName())
				// Receive bundled signatures
				sig, err := conn.Receive()
				if err != nil {
					dbg.Fatal(peer.String(), "could not received bundled signature from", conn.PeerName(), ":", err)
				}
				if sig.MsgType != net.ListBasicSignatureType {
					dbg.Fatal(peer.String(), "received a wrong packet type from", conn.PeerName(), ":", sig.MsgType.String())
				}
				// Then pass them on
				sigs := sig.Msg.(net.ListBasicSignature)
				lsigChan <- &sigs
				dbg.Lvl3(peer.String(), "Received list of signatures from child", conn.PeerName())
			}
		}(connPeer)
	}
	// First collect every "ready-connections"
	children := make([]chan chan *net.ListBasicSignature, 0)
	for round := range masterRoundChan {
		children = append(children, round)
		if len(children) == len(conf.Tree.Children) {
			dbg.Lvl3(peer.String(), "collected each children channels")
			break
		}
	}
	close(masterRoundChan)
	setup.Measure()

	// Then for each rounds tell them to start the protocol
	round := monitor.NewMeasure("round")
	for i := 1; i <= conf.Rounds; i++ {
		dbg.Lvl1(peer.String(), "will start a new round", i)
		calc := monitor.NewMeasure("calc")
		// the signature channel used for this round
		lsigChan := make(chan *net.ListBasicSignature)
		// notify each connections
		for _, ch := range children {
			ch <- lsigChan
		}

		childrenSigs := make([]*net.ListBasicSignature, 0)
		// Wait for listsignatures coming
		dbg.Lvl3(peer.String(), "Waiting on signatures for round", i, "...")

		for sigs := range lsigChan {
			dbg.Lvl3(peer.String(), "will analyze one ListBasicSignature...")
			childrenSigs = append(childrenSigs, sigs)
			// we have received all bundled signatures so time it
			if len(childrenSigs) == len(conf.Tree.Children) {
				close(lsigChan) // we have finished for this round
			}
		}
		dbg.Lvl3(peer.String(), "Received all signatures ... ")
		calc.Measure()

		var verifyWg sync.WaitGroup
		var faulty uint64 = 0
		var total uint64 = 0
		// start timing verification
		verify := monitor.NewMeasure("verify")
		for _, sigs := range childrenSigs {
			// Here it launches one go routine to verify a bundle
			verifyWg.Add(1)
			go func(s *net.ListBasicSignature) {
				defer verifyWg.Done()
				if conf.SkipChecks {
					return
				}
				// verify each independant signatures
				for _, sig := range s.Sigs {
					if err := SchnorrVerify(suite, msg, sig); err != nil {
						dbg.Lvl2(peer.String(), "received incorrect signature ><", err)
						atomic.AddUint64(&faulty, 1)
					}
					atomic.AddUint64(&total, 1)
				}
			}(sigs)
		}
		// wait for all verifications
		verifyWg.Wait()
		// finished verifying => time it !
		verify.Measure()
		round.Measure()
		dbg.Lvl3(peer.String(), "Round", i, "/", conf.Rounds, "has verified all signatures:", total-faulty, "/", total, "good signatures")
	}

	// cLosing each channels
	for _, ch := range children {
		close(ch)
	}

	dbg.Lvl2(peer.String(), "Finished all rounds successfully.")
}