gopkg.in/dedis/onet.v2@v2.0.0-20181115163211-c8f3724038a7/tree.go (about)

     1  package onet
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/hex"
     6  	"errors"
     7  	"fmt"
     8  	"math/rand"
     9  
    10  	"gopkg.in/dedis/kyber.v2"
    11  	"gopkg.in/dedis/onet.v2/log"
    12  	"gopkg.in/dedis/onet.v2/network"
    13  	"gopkg.in/satori/go.uuid.v1"
    14  )
    15  
    16  // In this file we define the main structures used for a running protocol
    17  // instance. First there is the ServerIdentity struct: it represents the ServerIdentity of
    18  // someone, a server over the internet, mainly tied by its public key.
    19  // The tree contains the peerId which is the ID given to a an ServerIdentity / server
    20  // during one protocol instance. A server can have many peerId in one tree.
    21  //
    22  // ProtocolInstance needs to know:
    23  //   - which Roster we are using ( a selection of proper servers )
    24  //   - which Tree we are using
    25  //   - The overlay network: a mapping from PeerId
    26  //
    27  // It contains the PeerId of the parent and the sub tree of the children.
    28  
    29  func init() {
    30  	network.RegisterMessage(Tree{})
    31  	network.RegisterMessage(tbmStruct{})
    32  }
    33  
    34  // Tree is a topology to be used by any network layer/host layer.
    35  // It contains the peer list we use, and the tree we use
    36  type Tree struct {
    37  	ID     TreeID
    38  	Roster *Roster
    39  	Root   *TreeNode
    40  }
    41  
    42  // TreeID uniquely identifies a Tree struct in the onet framework.
    43  type TreeID uuid.UUID
    44  
    45  // Equal returns true if and only if tID2 equals this TreeID.
    46  func (tId TreeID) Equal(tID2 TreeID) bool {
    47  	return uuid.Equal(uuid.UUID(tId), uuid.UUID(tID2))
    48  }
    49  
    50  // Equals will be removed!
    51  func (tId TreeID) Equals(tID2 TreeID) bool {
    52  	log.Warn("Deprecated: TreeID.Equals will be removed in onet.v2")
    53  	return tId.Equal(tID2)
    54  }
    55  
    56  // String returns a canonical representation of the TreeID.
    57  func (tId TreeID) String() string {
    58  	return uuid.UUID(tId).String()
    59  }
    60  
    61  // IsNil returns true iff the TreeID is Nil
    62  func (tId TreeID) IsNil() bool {
    63  	return tId.Equal(TreeID(uuid.Nil))
    64  }
    65  
    66  // NewTree creates a new tree using the given roster and root. It
    67  // also generates the id.
    68  func NewTree(roster *Roster, root *TreeNode) *Tree {
    69  	// walk the tree with DFS to build a unique hash
    70  	h := sha256.New()
    71  	root.Visit(0, func(d int, tn *TreeNode) {
    72  		_, err := tn.ServerIdentity.Public.MarshalTo(h)
    73  		if err != nil {
    74  			log.Error(err)
    75  		}
    76  		if tn.IsLeaf() {
    77  			// to prevent generating the same hash for tree with
    78  			// the same nodes but with a different structure
    79  			_, err = h.Write([]byte{1})
    80  			if err != nil {
    81  				log.Error(err)
    82  			}
    83  		}
    84  	})
    85  
    86  	url := network.NamespaceURL + "tree/" + roster.ID.String() + hex.EncodeToString(h.Sum(nil))
    87  	t := &Tree{
    88  		Roster: roster,
    89  		Root:   root,
    90  		ID:     TreeID(uuid.NewV5(uuid.NamespaceURL, url)),
    91  	}
    92  	t.computeSubtreeAggregate(root)
    93  	return t
    94  }
    95  
    96  // NewTreeFromMarshal takes a slice of bytes and an Roster to re-create
    97  // the original tree
    98  func NewTreeFromMarshal(s network.Suite, buf []byte, el *Roster) (*Tree, error) {
    99  	tp, pm, err := network.Unmarshal(buf, s)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  	if !tp.Equal(TreeMarshalTypeID) {
   104  		return nil, errors.New("Didn't receive TreeMarshal-struct")
   105  	}
   106  	t, err := pm.(*TreeMarshal).MakeTree(el)
   107  	t.computeSubtreeAggregate(t.Root)
   108  	return t, err
   109  }
   110  
   111  // MakeTreeMarshal creates a replacement-tree that is safe to send: no
   112  // parent (creates loops), only sends ids (not send the roster again)
   113  func (t *Tree) MakeTreeMarshal() *TreeMarshal {
   114  	if t.Roster == nil {
   115  		return &TreeMarshal{}
   116  	}
   117  	treeM := &TreeMarshal{
   118  		TreeID:   t.ID,
   119  		RosterID: t.Roster.ID,
   120  	}
   121  	treeM.Children = append(treeM.Children, TreeMarshalCopyTree(t.Root))
   122  	return treeM
   123  }
   124  
   125  // Marshal creates a simple binary-representation of the tree containing only
   126  // the ids of the elements. Use NewTreeFromMarshal to get back the original
   127  // tree
   128  func (t *Tree) Marshal() ([]byte, error) {
   129  	buf, err := network.Marshal(t.MakeTreeMarshal())
   130  	return buf, err
   131  }
   132  
   133  type tbmStruct struct {
   134  	T  []byte
   135  	Ro *Roster
   136  }
   137  
   138  // BinaryMarshaler does the same as Marshal
   139  func (t *Tree) BinaryMarshaler() ([]byte, error) {
   140  	bt, err := t.Marshal()
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  	tbm := &tbmStruct{
   145  		T:  bt,
   146  		Ro: t.Roster,
   147  	}
   148  	b, err := network.Marshal(tbm)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	return b, nil
   153  }
   154  
   155  // BinaryUnmarshaler takes a TreeMarshal and stores it in the tree
   156  func (t *Tree) BinaryUnmarshaler(s network.Suite, b []byte) error {
   157  	_, m, err := network.Unmarshal(b, s)
   158  	tbm, ok := m.(*tbmStruct)
   159  	if !ok {
   160  		return errors.New("Didn't find TBMstruct")
   161  	}
   162  	tree, err := NewTreeFromMarshal(s, tbm.T, tbm.Ro)
   163  	if err != nil {
   164  		return err
   165  	}
   166  	t.Roster = tbm.Ro
   167  	t.ID = tree.ID
   168  	t.Root = tree.Root
   169  	return nil
   170  }
   171  
   172  // Equal verifies if the given tree is equal
   173  func (t *Tree) Equal(t2 *Tree) bool {
   174  	if !t.ID.Equal(t2.ID) || !t.Roster.ID.Equal(t2.Roster.ID) {
   175  		log.Lvl4("Ids of trees don't match")
   176  		return false
   177  	}
   178  	return t.Root.Equal(t2.Root)
   179  }
   180  
   181  // String writes the definition of the tree
   182  func (t *Tree) String() string {
   183  	return fmt.Sprintf("TreeId:%s - RosterId:%s - RootId:%s",
   184  		t.ID, t.Roster.ID, t.Root.ID)
   185  }
   186  
   187  // Dump returns string about the tree
   188  func (t *Tree) Dump() string {
   189  	ret := "Tree " + t.ID.String() + " is:"
   190  	t.Root.Visit(0, func(d int, tn *TreeNode) {
   191  		if tn.Parent != nil {
   192  			ret += fmt.Sprintf("\n%d - %s/%s has parent %s/%s", d,
   193  				tn.ServerIdentity.Public, tn.ServerIdentity.Address,
   194  				tn.Parent.ServerIdentity.Public, tn.Parent.ServerIdentity.Address)
   195  		} else {
   196  			ret += fmt.Sprintf("\n%s/%s is root", tn.ServerIdentity.Public, tn.ServerIdentity.Address)
   197  		}
   198  	})
   199  	return ret
   200  }
   201  
   202  // Search searches the Tree for the given TreeNodeID and returns the corresponding TreeNode
   203  func (t *Tree) Search(tn TreeNodeID) (ret *TreeNode) {
   204  	found := func(d int, tns *TreeNode) {
   205  		if tns.ID.Equal(tn) {
   206  			ret = tns
   207  		}
   208  	}
   209  	t.Root.Visit(0, found)
   210  	return ret
   211  }
   212  
   213  // List returns a list of TreeNodes generated by DFS-iterating the Tree
   214  func (t *Tree) List() (ret []*TreeNode) {
   215  	ret = make([]*TreeNode, 0)
   216  	add := func(d int, tns *TreeNode) {
   217  		ret = append(ret, tns)
   218  	}
   219  	t.Root.Visit(0, add)
   220  	return ret
   221  }
   222  
   223  // IsBinary returns true if every node has two or no children
   224  func (t *Tree) IsBinary(root *TreeNode) bool {
   225  	return t.IsNary(root, 2)
   226  }
   227  
   228  // IsNary returns true if every node has two or no children
   229  func (t *Tree) IsNary(root *TreeNode, N int) bool {
   230  	nChild := len(root.Children)
   231  	if nChild != N && nChild != 0 {
   232  		log.Lvl3("Only", nChild, "children for", root.ID)
   233  		return false
   234  	}
   235  	for _, c := range root.Children {
   236  		if !t.IsNary(c, N) {
   237  			return false
   238  		}
   239  	}
   240  	return true
   241  }
   242  
   243  // Size returns the number of all TreeNodes
   244  func (t *Tree) Size() int {
   245  	size := 0
   246  	t.Root.Visit(0, func(d int, tn *TreeNode) {
   247  		size++
   248  	})
   249  	return size
   250  }
   251  
   252  // UsesList returns true if all ServerIdentities of the list are used at least once
   253  // in the tree
   254  func (t *Tree) UsesList() bool {
   255  	nodes := t.List()
   256  	for _, p := range t.Roster.List {
   257  		found := false
   258  		for _, n := range nodes {
   259  			if n.ServerIdentity.ID.Equal(p.ID) {
   260  				found = true
   261  				break
   262  			}
   263  		}
   264  		if !found {
   265  			return false
   266  		}
   267  	}
   268  	return true
   269  }
   270  
   271  // computeSubtreeAggregate will compute the aggregate subtree public key for
   272  // each node of the tree.
   273  // root is the root of the subtree we want to compute the aggregate for
   274  // recursive function so it will go down to the leaves then go up to the root
   275  // Return the aggregate sub tree public key for this root (and compute each sub
   276  // aggregate public key for each of the children).
   277  func (t *Tree) computeSubtreeAggregate(root *TreeNode) kyber.Point {
   278  	// Cloning the root public key does two things for us. First, it
   279  	// gets agg set to the right kind of kyber.Group for this tree.
   280  	// Second, it is the first component of the aggregate. The rest
   281  	// of the subtree aggregates are added via the DFS.
   282  	agg := root.ServerIdentity.Public.Clone()
   283  
   284  	// DFS search
   285  	for _, ch := range root.Children {
   286  		agg = agg.Add(agg, t.computeSubtreeAggregate(ch))
   287  	}
   288  	root.PublicAggregateSubTree = agg
   289  	return agg
   290  }
   291  
   292  // TreeMarshal is used to send and receive a tree-structure without having
   293  // to copy the whole nodelist
   294  type TreeMarshal struct {
   295  	// This is the UUID of the corresponding TreeNode
   296  	TreeNodeID TreeNodeID
   297  	// TreeId identifies the Tree for the top-node
   298  	TreeID TreeID
   299  	// This is the UUID of the ServerIdentity, except
   300  	ServerIdentityID network.ServerIdentityID
   301  	// for the top-node this contains the Roster's ID
   302  	RosterID RosterID
   303  	// All children from this tree. The top-node only has one child, which is
   304  	// the root
   305  	Children []*TreeMarshal
   306  }
   307  
   308  func (tm *TreeMarshal) String() string {
   309  	s := fmt.Sprintf("%v", tm.ServerIdentityID)
   310  	s += "\n"
   311  	for i := range tm.Children {
   312  		s += tm.Children[i].String()
   313  	}
   314  	return s
   315  }
   316  
   317  // TreeMarshalTypeID of TreeMarshal message as registered in network
   318  var TreeMarshalTypeID = network.RegisterMessage(TreeMarshal{})
   319  
   320  // TreeMarshalCopyTree takes a TreeNode and returns a corresponding
   321  // TreeMarshal
   322  func TreeMarshalCopyTree(tr *TreeNode) *TreeMarshal {
   323  	tm := &TreeMarshal{
   324  		TreeNodeID:       tr.ID,
   325  		ServerIdentityID: tr.ServerIdentity.ID,
   326  	}
   327  	for i := range tr.Children {
   328  		tm.Children = append(tm.Children,
   329  			TreeMarshalCopyTree(tr.Children[i]))
   330  	}
   331  	return tm
   332  }
   333  
   334  // MakeTree creates a tree given an Roster
   335  func (tm TreeMarshal) MakeTree(ro *Roster) (*Tree, error) {
   336  	if !ro.ID.Equal(tm.RosterID) {
   337  		return nil, errors.New("Not correct Roster-Id")
   338  	}
   339  	tree := &Tree{
   340  		ID:     tm.TreeID,
   341  		Roster: ro,
   342  	}
   343  	tree.Root = tm.Children[0].MakeTreeFromList(nil, ro)
   344  	tree.computeSubtreeAggregate(tree.Root)
   345  	return tree, nil
   346  }
   347  
   348  // MakeTreeFromList creates a sub-tree given an Roster
   349  func (tm *TreeMarshal) MakeTreeFromList(parent *TreeNode, ro *Roster) *TreeNode {
   350  	idx, ent := ro.Search(tm.ServerIdentityID)
   351  	tn := &TreeNode{
   352  
   353  		Parent:         parent,
   354  		ID:             tm.TreeNodeID,
   355  		ServerIdentity: ent,
   356  		RosterIndex:    idx,
   357  	}
   358  	for _, c := range tm.Children {
   359  		tn.Children = append(tn.Children, c.MakeTreeFromList(tn, ro))
   360  	}
   361  	return tn
   362  }
   363  
   364  // A Roster is a list of ServerIdentity we choose to run some tree on it ( and
   365  // therefor some protocols). Access is not safe from multiple goroutines.
   366  type Roster struct {
   367  	ID RosterID
   368  	// List is the list of actual entities.
   369  	List      []*network.ServerIdentity
   370  	Aggregate kyber.Point
   371  }
   372  
   373  // RosterID uniquely identifies an Roster
   374  type RosterID uuid.UUID
   375  
   376  // String returns the default representation of the ID (wrapper around
   377  // uuid.UUID.String()
   378  func (roID RosterID) String() string {
   379  	return uuid.UUID(roID).String()
   380  }
   381  
   382  // Equal returns true if and only if roID2 equals this RosterID.
   383  func (roID RosterID) Equal(roID2 RosterID) bool {
   384  	return uuid.Equal(uuid.UUID(roID), uuid.UUID(roID2))
   385  }
   386  
   387  // IsNil returns true iff the RosterID is Nil
   388  func (roID RosterID) IsNil() bool {
   389  	return roID.Equal(RosterID(uuid.Nil))
   390  }
   391  
   392  // RosterTypeID of Roster message as registered in network
   393  var RosterTypeID = network.RegisterMessage(Roster{})
   394  
   395  // NewRoster creates a new roster from a list of entities. It also
   396  // adds a UUID which is randomly chosen.
   397  func NewRoster(ids []*network.ServerIdentity) *Roster {
   398  	// Don't allow a crash if things are not as expected.
   399  	if len(ids) < 1 || ids[0].Public == nil {
   400  		return nil
   401  	}
   402  
   403  	h := sha256.New()
   404  	for _, id := range ids {
   405  		_, err := id.Public.MarshalTo(h)
   406  		if err != nil {
   407  			log.Error(err)
   408  		}
   409  	}
   410  
   411  	r := &Roster{
   412  		ID: RosterID(uuid.NewV5(uuid.NamespaceURL, hex.EncodeToString(h.Sum(nil)))),
   413  	}
   414  
   415  	// Take a copy of ids, in case the caller tries to change it later.
   416  	r.List = append(r.List, ids...)
   417  
   418  	if len(ids) != 0 {
   419  		// compute the aggregate key, using the first server's
   420  		// public key to discover which kyber.Group we should be
   421  		// using.
   422  		agg := ids[0].Public.Clone()
   423  		agg.Null()
   424  		for _, e := range ids {
   425  			if e.Public != nil {
   426  				agg = agg.Add(agg, e.Public)
   427  			}
   428  		}
   429  		r.Aggregate = agg
   430  	}
   431  	return r
   432  }
   433  
   434  // Search searches the Roster for the given ServerIdentityID and returns the
   435  // corresponding ServerIdentity.
   436  func (ro *Roster) Search(eID network.ServerIdentityID) (int, *network.ServerIdentity) {
   437  	for i, e := range ro.List {
   438  		if e.ID.Equal(eID) {
   439  			return i, e
   440  		}
   441  	}
   442  	return -1, nil
   443  }
   444  
   445  // Get simply returns the entity that is stored at that index in the entitylist
   446  // returns nil if index error
   447  func (ro *Roster) Get(idx int) *network.ServerIdentity {
   448  	if idx < 0 || idx > len(ro.List) {
   449  		return nil
   450  	}
   451  	return ro.List[idx]
   452  }
   453  
   454  // Publics returns the public-keys of the underlying Roster. It won't modify
   455  // the underlying list.
   456  func (ro *Roster) Publics() []kyber.Point {
   457  	res := make([]kyber.Point, len(ro.List))
   458  	for i, p := range ro.List {
   459  		res[i] = p.Public
   460  	}
   461  	return res
   462  }
   463  
   464  // GenerateBigNaryTree creates a tree where each node has N children.
   465  // It will make a tree with exactly 'nodes' elements, regardless of the
   466  // size of the Roster. If 'nodes' is bigger than the number of elements
   467  // in the Roster, it will add some or all elements in the Roster
   468  // more than once.
   469  // If the length of the Roster is equal to 'nodes', it is guaranteed that
   470  // all ServerIdentities from the Roster will be used in the tree.
   471  // However, for some configurations it is impossible to use all ServerIdentities from
   472  // the Roster and still avoid having a parent and a child from the same
   473  // host. In this case use-all has preference over not-the-same-host.
   474  func (ro *Roster) GenerateBigNaryTree(N, nodes int) *Tree {
   475  	if len(ro.List) == 0 {
   476  		panic("empty roster")
   477  	}
   478  
   479  	// list of which hosts are already used
   480  	used := make([]bool, len(ro.List))
   481  	ilLen := len(ro.List)
   482  	// only use all ServerIdentities if we have the same number of nodes and hosts
   483  	useAll := ilLen == nodes
   484  	root := NewTreeNode(0, ro.List[0])
   485  	used[0] = true
   486  	levelNodes := []*TreeNode{root}
   487  	totalNodes := 1
   488  	roIndex := 1 % ilLen
   489  	for totalNodes < nodes {
   490  		newLevelNodes := make([]*TreeNode, len(levelNodes)*N)
   491  		newLevelNodesCounter := 0
   492  		for i, parent := range levelNodes {
   493  			children := (nodes - totalNodes) * (i + 1) / len(levelNodes)
   494  			if children > N {
   495  				children = N
   496  			}
   497  			parent.Children = make([]*TreeNode, children)
   498  			parentHost := parent.ServerIdentity.Address.Host()
   499  			for n := 0; n < children; n++ {
   500  				// Check on host-address, so that no child is
   501  				// on the same host as the parent.
   502  				childHost := ro.List[roIndex].Address.Host()
   503  				roIndexFirst := roIndex
   504  				notSameHost := true
   505  				for (notSameHost && childHost == parentHost && ilLen > 1) ||
   506  					(useAll && used[roIndex]) {
   507  					roIndex = (roIndex + 1) % ilLen
   508  					if useAll && used[roIndex] {
   509  						// In case we searched all ServerIdentities,
   510  						// give up on finding another host, but
   511  						// keep using all ServerIdentities
   512  						if roIndex == roIndexFirst {
   513  							notSameHost = false
   514  						}
   515  						continue
   516  					}
   517  					// If we tried all hosts, it means we're using
   518  					// just one hostname, as we didn't find any
   519  					// other name
   520  					if roIndex == roIndexFirst {
   521  						break
   522  					}
   523  					childHost = ro.List[roIndex].Address.Host()
   524  				}
   525  				child := NewTreeNode(roIndex, ro.List[roIndex])
   526  				used[roIndex] = true
   527  				roIndex = (roIndex + 1) % ilLen
   528  				totalNodes++
   529  				parent.Children[n] = child
   530  				child.Parent = parent
   531  				newLevelNodes[newLevelNodesCounter] = child
   532  				newLevelNodesCounter++
   533  			}
   534  		}
   535  		levelNodes = newLevelNodes[:newLevelNodesCounter]
   536  	}
   537  	return NewTree(ro, root)
   538  }
   539  
   540  // NewRosterWithRoot returns a copy of the roster but with the given ServerIdentity
   541  // at the first entry in the roster.
   542  func (ro *Roster) NewRosterWithRoot(root *network.ServerIdentity) *Roster {
   543  	list := make([]*network.ServerIdentity, len(ro.List))
   544  	copy(list, ro.List)
   545  	rootIndex, _ := ro.Search(root.ID)
   546  	if rootIndex < 0 {
   547  		return nil
   548  	}
   549  	list[0], list[rootIndex] = list[rootIndex], list[0]
   550  	return NewRoster(list)
   551  }
   552  
   553  // GenerateNaryTreeWithRoot creates a tree where each node has N children.
   554  // The root is given as an ServerIdentity. If root doesn't exist in the
   555  // roster, `nil` will be returned.
   556  // The generation of the tree is done in a simple for-loop, so that the
   557  // original roster can be used for tree creation, even if the root is not
   558  // at position 0.
   559  // If root == nil, the first element of the roster will be taken as root.
   560  //
   561  // If you need the root node to be at the first position of the roster, then
   562  // you need to create a new roster using roster.NewRosterWithRoot. Else this method
   563  // does not change the underlying roster or create a new one.
   564  func (ro *Roster) GenerateNaryTreeWithRoot(N int, root *network.ServerIdentity) *Tree {
   565  	// Fetch the root node, set to the first element of the roster if
   566  	// root == nil.
   567  	rootIndex := 0
   568  	if root != nil {
   569  		rootIndex, _ = ro.Search(root.ID)
   570  		if rootIndex < 0 {
   571  			log.Lvl2("Asked for non-existing root:", root, ro.List)
   572  			return nil
   573  		}
   574  	} else {
   575  		root = ro.List[0]
   576  	}
   577  	rootNode := NewTreeNode(rootIndex, root)
   578  	parents := []*TreeNode{rootNode}
   579  	children := []*TreeNode{}
   580  	for i := 1; i < len(ro.List); i++ {
   581  		index := (i + rootIndex) % len(ro.List)
   582  		// If a parent is full, remove it from the list.
   583  		if parents[0].SubtreeCount() == N {
   584  			parents = parents[1:]
   585  		}
   586  		// If there are no parents, pass all children to the parents, and
   587  		// continue
   588  		if len(parents) == 0 {
   589  			parents = children
   590  			children = []*TreeNode{}
   591  		}
   592  		// Create the new child and add it to the parent node.
   593  		newChild := NewTreeNode(index, ro.List[index])
   594  		children = append(children, newChild)
   595  		parents[0].AddChild(newChild)
   596  	}
   597  	return NewTree(ro, rootNode)
   598  }
   599  
   600  // GenerateNaryTree creates a tree where each node has N children.
   601  // The first element of the Roster will be the root element.
   602  func (ro *Roster) GenerateNaryTree(N int) *Tree {
   603  	return ro.GenerateNaryTreeWithRoot(N, nil)
   604  }
   605  
   606  // GenerateBinaryTree creates a binary tree out of the Roster
   607  // out of it. The first element of the Roster will be the root element.
   608  func (ro *Roster) GenerateBinaryTree() *Tree {
   609  	return ro.GenerateNaryTree(2)
   610  }
   611  
   612  // GenerateStar creates a star topology with the first element
   613  // of Roster as root, and all other elements as children of the root.
   614  func (ro *Roster) GenerateStar() *Tree {
   615  	return ro.GenerateNaryTree(len(ro.List) - 1)
   616  }
   617  
   618  // RandomServerIdentity returns a random element of the Roster.
   619  func (ro *Roster) RandomServerIdentity() *network.ServerIdentity {
   620  	if ro.List == nil || len(ro.List) == 0 {
   621  		return nil
   622  	}
   623  	return ro.List[rand.Int()%len(ro.List)]
   624  }
   625  
   626  // RandomSubset returns a new Roster which starts with root and is
   627  // followed by a random subset of n elements of ro, not including root.
   628  func (ro *Roster) RandomSubset(root *network.ServerIdentity, n int) *Roster {
   629  	if n > len(ro.List) {
   630  		n = len(ro.List)
   631  	}
   632  	out := make([]*network.ServerIdentity, 1, n+1)
   633  	out[0] = root
   634  
   635  	perm := rand.Perm(len(ro.List))
   636  	for _, p := range perm {
   637  		if !ro.List[p].ID.Equal(root.ID) {
   638  			out = append(out, ro.List[p])
   639  			if len(out) == n+1 {
   640  				break
   641  			}
   642  		}
   643  	}
   644  	return NewRoster(out)
   645  }
   646  
   647  // IsRotation returns true if the target is a rotated (the same roster but with
   648  // shifted server identities) version of the receiver.
   649  func (ro Roster) IsRotation(target *Roster) bool {
   650  	if target == nil {
   651  		return false
   652  	}
   653  	n := len(ro.List)
   654  	if n < 2 {
   655  		return false
   656  	}
   657  	if n != len(target.List) {
   658  		return false
   659  	}
   660  
   661  	// find the first element of ro in target
   662  	var offset int
   663  	for _, sid := range target.List {
   664  		if sid.Equal(ro.List[0]) {
   665  			break
   666  		}
   667  		offset++
   668  	}
   669  	if offset == 0 || offset >= n {
   670  		return false
   671  	}
   672  
   673  	// check that the identities are the same, starting at the offset
   674  	for i, sid := range ro.List {
   675  		if !sid.Equal(target.List[(i+offset)%n]) {
   676  			return false
   677  		}
   678  	}
   679  	return true
   680  }
   681  
   682  // Contains checks if the roster contains the given array of public keys
   683  // and no more
   684  func (ro *Roster) Contains(pubs []kyber.Point) bool {
   685  	if len(ro.List) != len(pubs) {
   686  		return false
   687  	}
   688  
   689  	table := make(map[string]bool)
   690  	for _, p := range pubs {
   691  		table[p.String()] = true
   692  	}
   693  
   694  	for _, p := range ro.Publics() {
   695  		_, ok := table[p.String()]
   696  		if !ok {
   697  			return false
   698  		}
   699  	}
   700  
   701  	return true
   702  }
   703  
   704  // Concat makes a new roster using an existing one and a list
   705  // of server identities while preserving the order of the
   706  // roster by appending at the end
   707  func (ro *Roster) Concat(sis ...*network.ServerIdentity) *Roster {
   708  	tmpRoster := NewRoster(ro.List)
   709  	for _, si := range sis {
   710  		if i, _ := tmpRoster.Search(si.ID); i < 0 {
   711  			tmpRoster.List = append(tmpRoster.List, si)
   712  		}
   713  	}
   714  
   715  	return NewRoster(tmpRoster.List)
   716  }
   717  
   718  // addNary is a recursive function to create the binary tree.
   719  func (ro *Roster) addNary(parent *TreeNode, N, start, end int) *TreeNode {
   720  	if !(start <= end && end < len(ro.List)) {
   721  		return nil
   722  	}
   723  	node := NewTreeNode(start, ro.List[start])
   724  	if parent != nil {
   725  		node.Parent = parent
   726  		parent.Children = append(parent.Children, node)
   727  	}
   728  	diff := end - start
   729  	for n := 0; n < N; n++ {
   730  		s := diff * n / N
   731  		e := diff * (n + 1) / N
   732  		ro.addNary(node, N, start+s+1, start+e)
   733  	}
   734  	return node
   735  }
   736  
   737  // TreeNode is one node in the tree
   738  type TreeNode struct {
   739  	// The Id represents that node of the tree
   740  	ID TreeNodeID
   741  	// The ServerIdentity points to the corresponding host. One given host
   742  	// can be used more than once in a tree.
   743  	ServerIdentity *network.ServerIdentity
   744  	// RosterIndex is the index in the Roster where the `ServerIdentity` is located
   745  	RosterIndex int
   746  	// Parent link
   747  	Parent *TreeNode
   748  	// Children links
   749  	Children []*TreeNode
   750  	// Aggregate public key for *this* subtree,i.e. this node's public key + the
   751  	// aggregate of all its children's aggregate public key
   752  	PublicAggregateSubTree kyber.Point
   753  }
   754  
   755  // TreeNodeID identifies a given TreeNode struct in the onet framework.
   756  type TreeNodeID uuid.UUID
   757  
   758  // String returns a canonical representation of the TreeNodeID.
   759  func (tId TreeNodeID) String() string {
   760  	return uuid.UUID(tId).String()
   761  }
   762  
   763  // Equal returns true if and only if the given TreeNodeID equals tId.
   764  func (tId TreeNodeID) Equal(tID2 TreeNodeID) bool {
   765  	return uuid.Equal(uuid.UUID(tId), uuid.UUID(tID2))
   766  }
   767  
   768  // IsNil returns true iff the TreeNodID is Nil
   769  func (tId TreeNodeID) IsNil() bool {
   770  	return tId.Equal(TreeNodeID(uuid.Nil))
   771  }
   772  
   773  // Name returns a human readable representation of the TreeNode (IP address).
   774  func (t *TreeNode) Name() string {
   775  	return t.ServerIdentity.Address.String()
   776  }
   777  
   778  var _ = network.RegisterMessage(TreeNode{})
   779  
   780  // NewTreeNode creates a new TreeNode with the proper Id
   781  func NewTreeNode(entityIdx int, ni *network.ServerIdentity) *TreeNode {
   782  	tn := &TreeNode{
   783  		ServerIdentity: ni,
   784  		RosterIndex:    entityIdx,
   785  		Parent:         nil,
   786  		Children:       make([]*TreeNode, 0),
   787  		ID:             TreeNodeID(uuid.NewV5(uuid.NamespaceURL, ni.Public.String())),
   788  	}
   789  	return tn
   790  }
   791  
   792  // IsConnectedTo checks if the TreeNode can communicate with its parent or
   793  // children.
   794  func (t *TreeNode) IsConnectedTo(si *network.ServerIdentity) bool {
   795  	if t.Parent != nil && t.Parent.ServerIdentity.Equal(si) {
   796  		return true
   797  	}
   798  
   799  	for i := range t.Children {
   800  		if t.Children[i].ServerIdentity.Equal(si) {
   801  			return true
   802  		}
   803  	}
   804  	return false
   805  }
   806  
   807  // IsLeaf returns true for a node without children
   808  func (t *TreeNode) IsLeaf() bool {
   809  	return len(t.Children) == 0
   810  }
   811  
   812  // IsRoot returns true for a node without a parent
   813  func (t *TreeNode) IsRoot() bool {
   814  	return t.Parent == nil
   815  }
   816  
   817  // IsInTree - verifies if the TreeNode is in the given Tree
   818  func (t *TreeNode) IsInTree(tree *Tree) bool {
   819  	root := *t
   820  	for root.Parent != nil {
   821  		root = *root.Parent
   822  	}
   823  	return tree.Root.ID.Equal(root.ID)
   824  }
   825  
   826  // AddChild adds a child to this tree-node.
   827  func (t *TreeNode) AddChild(c *TreeNode) {
   828  	t.Children = append(t.Children, c)
   829  	c.Parent = t
   830  }
   831  
   832  // Equal tests if that node is equal to the given node
   833  func (t *TreeNode) Equal(t2 *TreeNode) bool {
   834  	if !t.ID.Equal(t2.ID) || !t.ServerIdentity.ID.Equal(t2.ServerIdentity.ID) {
   835  		log.Lvl4("TreeNode: ids are not equal")
   836  		return false
   837  	}
   838  	if len(t.Children) != len(t2.Children) {
   839  		log.Lvl4("TreeNode: number of children are not equal")
   840  		return false
   841  	}
   842  	for i, c := range t.Children {
   843  		if !c.Equal(t2.Children[i]) {
   844  			log.Lvl4("TreeNode: children are not equal")
   845  			return false
   846  		}
   847  	}
   848  	return true
   849  }
   850  
   851  // String returns the current treenode's Id as a string.
   852  func (t *TreeNode) String() string {
   853  	return string(t.ID.String())
   854  }
   855  
   856  // Visit is a recursive function that allows for depth-first calling on all
   857  // nodes
   858  func (t *TreeNode) Visit(firstDepth int, fn func(depth int, n *TreeNode)) {
   859  	fn(firstDepth, t)
   860  	for _, c := range t.Children {
   861  		c.Visit(firstDepth+1, fn)
   862  	}
   863  }
   864  
   865  // SubtreeCount returns how many children are attached to that
   866  // TreeNode.
   867  func (t *TreeNode) SubtreeCount() int {
   868  	ret := -1
   869  	t.Visit(0, func(int, *TreeNode) { ret++ })
   870  	return ret
   871  }
   872  
   873  // AggregatePublic will return the aggregate public key of the TreeNode
   874  // and all it's children
   875  func (t *TreeNode) AggregatePublic(s network.Suite) kyber.Point {
   876  	agg := s.Point().Null()
   877  	t.Visit(0, func(i int, tn *TreeNode) {
   878  		agg.Add(agg, tn.ServerIdentity.Public)
   879  	})
   880  	return agg
   881  }
   882  
   883  // RosterToml is the struct can can embedded ServerIdentityToml to be written in a
   884  // toml file
   885  type RosterToml struct {
   886  	ID   RosterID
   887  	List []*network.ServerIdentityToml
   888  }
   889  
   890  // Toml returns the toml-writable version of this roster.
   891  func (ro *Roster) Toml(suite network.Suite) *RosterToml {
   892  	ids := make([]*network.ServerIdentityToml, len(ro.List))
   893  	for i := range ro.List {
   894  		ids[i] = ro.List[i].Toml(suite)
   895  	}
   896  	return &RosterToml{
   897  		ID:   ro.ID,
   898  		List: ids,
   899  	}
   900  }
   901  
   902  // Roster returns the Id list from this toml read struct
   903  func (rot *RosterToml) Roster(suite network.Suite) *Roster {
   904  	ids := make([]*network.ServerIdentity, len(rot.List))
   905  	for i := range rot.List {
   906  		ids[i] = rot.List[i].ServerIdentity(suite)
   907  	}
   908  	return &Roster{
   909  		ID:   rot.ID,
   910  		List: ids,
   911  	}
   912  }