Exemplo n.º 1
0
// The signer connects to the leader and then waits for a message to be
// signed
func GoSigner(conf *app.NaiveConfig) {
	// Wait for leader to be ready
	time.Sleep(2 * time.Second)
	host := net.NewTcpHost(app.RunFlags.Hostname)
	key := cliutils.KeyPair(suite)
	signer := NewPeer(host, ServRole, key.Secret, key.Public)
	dbg.Lvl3(signer.String(), "will contact leader", conf.Hosts[0])
	l := signer.Open(conf.Hosts[0])
	dbg.Lvl3(signer.String(), "is connected to leader", l.PeerName())

	// make the protocol for each round
	for round := 0; round < conf.Rounds; round++ {
		// Receive message
		m, err := l.Receive()
		dbg.Lvl3(signer.String(), "round", round, "received the message to be signed from the leader")
		if err != nil {
			dbg.Fatal(signer.String(), "round", round, "received error waiting msg")
		}
		if m.MsgType != net.MessageSigningType {
			dbg.Fatal(app.RunFlags.Hostname, "round", round, "wanted to receive a msg to sign but..",
				m.MsgType.String())
		}
		msg := m.Msg.(net.MessageSigning).Msg
		dbg.Lvl3(signer.String(), "round", round, "received msg:", msg[:])
		// Generate signature & send
		s := signer.Signature(msg[:])
		l.Send(*s)
		dbg.Lvl3(signer.String(), "round", round, "sent the signature to leader")
	}
	l.Close()
	dbg.Lvl3(app.RunFlags.Hostname, "Finished")
}
Exemplo 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")
}
Exemplo 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.")
}
Exemplo n.º 4
0
func RunPeer(conf *app.NTreeConfig) {

	host := net.NewTcpHost(app.RunFlags.Hostname)
	key := cliutils.KeyPair(suite)

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

	// Chan used to communicate the message from the parent to the children
	// Must do a Fan out to communicate this message to all children
	masterMsgChan := make(chan net.MessageSigning)
	childrenMsgChan := make([]chan net.MessageSigning, len(conf.Tree.Children))
	go func() {
		// init
		for i := range childrenMsgChan {
			childrenMsgChan[i] = make(chan net.MessageSigning)
		}
		// for each message
		for msg := range masterMsgChan {
			// broadcast to each channels
			for i, ch := range childrenMsgChan {
				dbg.Lvl4(peer.String(), "dispatching msg to children (", i+1, "/", len(conf.Tree.Children), ")...")
				ch <- msg
			}
		}
		// When finished, close all children channs
		for _, ch := range childrenMsgChan {
			close(ch)
		}
	}()

	// chan used to communicate the signature from the children to the parent
	// It is also used to specify the start of a new round (coming from the parent
	// connection)
	masterRoundChan := make(chan chan net.ListBasicSignature)
	// dispatch new round to each children
	childRoundChan := make([]chan chan net.ListBasicSignature, len(conf.Tree.Children))
	dbg.Lvl3(peer.String(), "created children Signal Channels (length =", len(childRoundChan), ")")
	go func() {
		// init
		for i := range childRoundChan {
			childRoundChan[i] = make(chan chan net.ListBasicSignature)
		}
		// For each new round started by the parent's connection
		for sigChan := range masterRoundChan {
			// if no children, no signature will come
			// so close immediatly so parent connection will continue
			if len(conf.Tree.Children) == 0 {
				dbg.Lvl3(peer.String(), "Has no children so closing childRoundChan")
				close(sigChan)
			} else {
				// otherwise, dispatch to children
				for i, _ := range childRoundChan {
					dbg.Lvl4(peer.String(), "Dispatching signature channel to children (", i+1, "/", len(conf.Tree.Children), ")...")
					childRoundChan[i] <- sigChan
				}
			}
		}
		dbg.Lvl3(peer.String(), "closing the children sig channels...")
		for _, ch := range childRoundChan {
			close(ch)
		}
	}()

	// chan used to tell the end of the protocols
	done := make(chan bool)
	// The parent protocol
	proto := func(c net.Conn) {
		dbg.Lvl3(peer.String(), "connected with parent", c.PeerName())
		// for each rounds
		for i := 1; i <= conf.Rounds; i++ {
			// Create the chan for this round
			sigChan := make(chan net.ListBasicSignature)
			// that wil be used for children to pass up their signatures
			masterRoundChan <- sigChan
			dbg.Lvl3(peer.String(), "starting round", i)
			// First, receive the message to be signed
			sig, err := c.Receive()
			if err != nil {
				dbg.Fatal(peer.String(), "error receiving message from parent", c.PeerName())
			}
			if sig.MsgType != net.MessageSigningType {
				dbg.Fatal(peer.String(), "received wrong packet type from parent:", sig.MsgType.String())
			}
			msg := sig.Msg.(net.MessageSigning)
			// Notify the chan so it will be broadcasted down
			masterMsgChan <- msg
			dbg.Lvl3(peer.String(), "round", i, ": received message from parent", msg.Msg)
			// issue our signature
			bs := peer.Signature(msg.Msg)
			// wait for children signatures
			sigs := make([]net.BasicSignature, 0)
			sigs = append(sigs, *bs)

			// for each ListBasicSignature
			n := 0
			dbg.Lvl3(peer.String(), "round", i, ": waiting on signatures from children ...")
			for lsig := range sigChan {
				dbg.Lvl3(peer.String(), "round", i, ": receievd a ListSignature !")
				// Add each independant signature
				for _, sig := range lsig.Sigs {
					sigs = append(sigs, sig)
				}
				n += 1
				//We got them all ;)
				if n == len(conf.Tree.Children) {
					close(sigChan)
					break
				}
			}

			dbg.Lvl3(peer.String(), "received", len(sigs), "signatures from children")
			// Then send to parent the signature
			lbs := net.ListBasicSignature{}
			lbs.Length = len(sigs)
			lbs.Sigs = sigs
			err = c.Send(lbs)
			if err != nil {
				dbg.Fatal(peer.String(), "Could not send list of signature to parents ><", err)
			}
			dbg.Lvl3(peer.String(), "round", i, ": sent the array of sigs to parent")
		}
		close(masterRoundChan)
		c.Close()
		done <- true
	}

	dbg.Lvl3(peer.String(), "listen for the parent connection...")
	go peer.Listen(conf.Name, proto)

	// Connect to the children
	// Relay the msg
	// Wait for signatures
	dbg.Lvl3(peer.String(), "will contact its siblings..")
	// To stop when every children has done all rounds
	// Connect to every children
	for i, c := range conf.Tree.Children {
		dbg.Lvl3(peer.String(), "is connecting to", c.Name, "(", i, ")")
		connPeer := peer.Open(c.Name)
		if connPeer == nil {
			dbg.Fatal(peer.String(), "Could not connect to", c.Name)
		}
		// Children protocol
		go func(child int, conn net.Conn) {
			dbg.Lvl3(peer.String(), "is connected to children", conn.PeerName(), "(", child, ")")

			// For each rounds new round
			for sigChan := range childRoundChan[child] {
				dbg.Lvl3(peer.String(), "starting new round with children", conn.PeerName(), "(", child, ")")
				// get & relay the message
				msg := <-childrenMsgChan[child]
				dbg.Lvl3(peer.String(), "will relay message to child", conn.PeerName(), "(", child, ")")
				err := conn.Send(msg)
				if err != nil {
					dbg.Fatal(peer.String(), "Could not relay message to children", conn.PeerName())
				}
				dbg.Lvl4(peer.String(), "sent to the message to children", conn.PeerName())
				// wait for signature bundle
				sig, err := conn.Receive()
				if err != nil {
					dbg.Fatal(peer.String(), "Could not receive the bundled children signature from", conn.PeerName())
				}
				if sig.MsgType != net.ListBasicSignatureType {
					dbg.Fatal(peer.String(), "received an different package from", conn.PeerName(), ":", sig.MsgType.String())
				}
				dbg.Lvl4(peer.String(), "received signature bundle from children", conn.PeerName())
				lbs := sig.Msg.(net.ListBasicSignature)
				// send to parent
				sigChan <- lbs
			}
			dbg.Lvl3(peer.String(), "finished with children", conn.PeerName())
			conn.Close()
		}(i, connPeer)
	}
	// Wait for the whole thing to be done (parent connection == master)
	<-done
	dbg.Lvl3(peer.String(), "leaving...")
}