// 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") }
// 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") }
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.") }
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...") }