Ejemplo n.º 1
0
/*
 * Reads in the config for the application -
 * also parses the init-flags and connects to
 * the monitor.
 */
func ReadConfig(conf interface{}, dir ...string) {
	var err error
	err = ReadTomlConfig(conf, "app.toml", dir...)
	if err != nil {
		log.Fatal("Couldn't load app-config-file in exec")
	}
	debug := reflect.ValueOf(conf).Elem().FieldByName("Debug")
	if debug.IsValid() {
		dbg.DebugVisible = debug.Interface().(int)
	}
	FlagInit()
	flag.Parse()
	dbg.Lvlf3("Flags are %+v", RunFlags)

	if RunFlags.AmRoot {
		if err := monitor.ConnectSink(RunFlags.Logger); err != nil {
			dbg.Fatal("Couldn't connect to monitor", err)
		}
	}

	dbg.Lvl3("Running", RunFlags.Hostname, "with logger at", RunFlags.Logger)
}
Ejemplo n.º 2
0
// 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")
}
Ejemplo n.º 3
0
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.")
}
Ejemplo n.º 4
0
func main() {
	// First, let's read our config
	// You should create your own config in lib/app.
	// TOML is a pretty simple and readable format
	// Whatever information needed, supply it in the simulation/.toml file that
	// will be parsed into your ConfigSkeleton struct.
	conf := &app.ConfigSkeleton{}
	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
	// i.e. we are root
	if hostname == conf.Hosts[0] {
		dbg.Lvlf3("Tree is %+v", conf.Tree)
	}
	dbg.Lvl3(hostname, "Starting to run")

	// Connect to the monitor process. This monitor process is run on your
	// machine and accepts connections from any node, usually you only connect
	// with the root for readability and performance reasons (don't connect to
	// your machine from 8000 nodes .. !)
	if app.RunFlags.Logger != "" {
		monitor.ConnectSink(app.RunFlags.Logger)
	} else {
		dbg.Fatal("No logger specified")
	}

	// Here you create a "Peer",that's the struct that will create a new round
	// each seconds and handle other subtleties for you
	peer := conode.NewPeer(hostname, conf.ConfigConode)

	// The root waits everyone's to be up
	if app.RunFlags.AmRoot {
		for {
			time.Sleep(time.Second)
			setupRound := sign.NewRoundSetup(peer.Node)
			peer.StartAnnouncementWithWait(setupRound, 5*time.Second)
			counted := <-setupRound.Counted
			dbg.Lvl1("Number of peers counted:", counted)
			if counted == len(conf.Hosts) {
				dbg.Lvl1("All hosts replied")
				break
			}
		}
	}

	// You register by giving the type, and a function that takes a sign.Node in
	// input (basically the underlying protocol) and returns a Round.
	sign.RegisterRoundFactory(RoundSkeletonType,
		func(node *sign.Node) sign.Round {
			return NewRoundSkeleton(node)
		})

	// Here it will create a new round each seconds automatically.
	// If you need more fined grained control, you must implement yourself the
	// conode.Peer struct (it's quite easy).
	peer.LoopRounds(RoundSkeletonType, conf.Rounds)
	// Notify the monitor that we finished so that the simulation can be stopped
	monitor.End()
}