func loadHost(hostname string, m map[string]*sign.Node, testSuite abstract.Suite, testRand cipher.Stream, hc *HostConfig) *sign.Node { if h, ok := m[hostname]; ok { return h } host := coconet.NewGoHost(hostname, coconet.NewGoDirectory()) h := sign.NewNode(host, testSuite, testRand) hc.Hosts[hostname] = h m[hostname] = h return h }
// ConstructTree does a depth-first construction of the tree specified in the // config file. ConstructTree must be called AFTER populating the HostConfig with // ALL the possible hosts. func ConstructTree( n *Node, hc *HostConfig, parent string, suite abstract.Suite, rand cipher.Stream, hosts map[string]coconet.Host, nameToAddr map[string]string, opts ConfigOptions) (int, error) { // passes up its X_hat, and/or an error // get the name associated with this address name, ok := nameToAddr[n.Name] if !ok { fmt.Println("unknown name in address book:", n.Name) return 0, errors.New("unknown name in address book") } // generate indicates whether we should generate the signing // node for this hostname generate := opts.Host == "" || opts.Host == name // check to make sure the this hostname is in the tree // it can be backed by a nil pointer h, ok := hosts[name] if !ok { fmt.Println("unknown host in tree:", name) return 0, errors.New("unknown host in tree") } var prikey abstract.Secret var pubkey abstract.Point var sn *sign.Node // if the JSON holds the fields field is set load from there if len(n.PubKey) != 0 { // log.Println("decoding point") encoded, err := hex.DecodeString(string(n.PubKey)) if err != nil { log.Print("failed to decode hex from encoded") return 0, err } pubkey = suite.Point() err = pubkey.UnmarshalBinary(encoded) if err != nil { log.Print("failed to decode point from hex") return 0, err } // log.Println("decoding point") encoded, err = hex.DecodeString(string(n.PriKey)) if err != nil { log.Print("failed to decode hex from encoded") return 0, err } prikey = suite.Secret() err = prikey.UnmarshalBinary(encoded) if err != nil { log.Print("failed to decode point from hex") return 0, err } } if generate { if prikey != nil { // if we have been given a private key load that aux := sign.NewKeyedNode(h, suite, prikey) aux.GenSetPool() hc.SNodes = append(hc.SNodes, aux) h.SetPubKey(pubkey) } else { // otherwise generate a random new one sn := sign.NewNode(h, suite, rand) sn.GenSetPool() hc.SNodes = append(hc.SNodes, sn) h.SetPubKey(sn.PubKey) } sn = hc.SNodes[len(hc.SNodes)-1] hc.Hosts[name] = sn if prikey == nil { prikey = sn.PrivKey pubkey = sn.PubKey } // log.Println("pubkey:", sn.PubKey) // log.Println("given: ", pubkey) } // if the parent of this call is empty then this must be the root node if parent != "" && generate { h.AddParent(0, parent) } // log.Println("name: ", n.Name) // log.Println("prikey: ", prikey) // log.Println("pubkey: ", pubkey) height := 0 for _, c := range n.Children { // connect this node to its children cname, ok := nameToAddr[c.Name] if !ok { fmt.Println("unknown name in address book:", n.Name) return 0, errors.New("unknown name in address book") } if generate { h.AddChildren(0, cname) } // recursively construct the children // log.Print("ConstructTree:", h, suite, rand, hosts, nameToAddr, opts) h, err := ConstructTree(c, hc, name, suite, rand, hosts, nameToAddr, opts) if err != nil { return 0, err } height = max(h+1, height) // if generating all csn will be availible } if generate { sn.Height = height } // log.Println("name: ", n.Name) // log.Println("final x_hat: ", x_hat) // log.Println("final pubkey: ", pubkey) return height, nil }
func runStaticTest(signType sign.Type, RoundsPerView int, faultyNodes ...int) error { // Crypto setup suite := nist.NewAES128SHA256P256() rand := suite.Cipher([]byte("example")) // number of nodes for the test nNodes := 4 // create new directory for communication between peers dir := coconet.NewGoDirectory() // Create Hosts and Peers h := make([]coconet.Host, nNodes) for i := 0; i < nNodes; i++ { hostName := "host" + strconv.Itoa(i) if len(faultyNodes) > 0 { h[i] = &coconet.FaultyHost{} gohost := coconet.NewGoHost(hostName, dir) h[i] = coconet.NewFaultyHost(gohost) } else { h[i] = coconet.NewGoHost(hostName, dir) } } for _, fh := range faultyNodes { h[fh].(*coconet.FaultyHost).SetDeadFor("response", true) } // Create Signing Nodes out of the hosts nodes := make([]*sign.Node, nNodes) for i := 0; i < nNodes; i++ { nodes[i] = sign.NewNode(h[i], suite, rand) nodes[i].Type = signType nodes[i].GenSetPool() nodes[i].RoundsPerView = RoundsPerView defer nodes[i].Close() h[i].SetPubKey(nodes[i].PubKey) // To test the already keyed signing node, uncomment // PrivKey := suite.Secret().Pick(rand) // nodes[i] = NewKeyedNode(h[i], suite, PrivKey) } nodes[0].Height = 2 nodes[1].Height = 1 nodes[2].Height = 0 nodes[3].Height = 0 // Add edges to parents h[1].AddParent(DefaultView, h[0].Name()) h[2].AddParent(DefaultView, h[1].Name()) h[3].AddParent(DefaultView, h[1].Name()) // Add edges to children, listen to children h[0].AddChildren(DefaultView, h[1].Name()) h[1].AddChildren(DefaultView, h[2].Name(), h[3].Name()) for _, host := range h { host.Listen() host.Connect(0) } for i := 0; i < nNodes; i++ { if len(faultyNodes) > 0 { nodes[i].FailureRate = 1 } go func(i int) { // start listening for messages from within the tree nodes[i].Listen() }(i) } // Have root node initiate the signing protocol // via a simple annoucement nodes[0].LogTest = []byte("Hello World") // return nodes[0].Announce(DefaultView, &sign.AnnouncementMessage{LogTest: nodes[0].LogTest, Round: 1}) return nodes[0].StartAnnouncement(&sign.AnnouncementMessage{LogTest: nodes[0].LogTest, Round: 1}) }