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