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 }