notary/internal/tlog: fix bit shifting bug when determining if an index is in a tree

The TileHashReader implementation of ReadHashes was splitting the requested
index into level and n, then bit shifting to decide whether or not the index
existing in the tree of size N. This doesn't work if the index n is 0, and
would then cause infinite looping looking for a parent tile that it knows about.

Note that this bug may exist in other parts of the code as well, but this is
the one that I noticed and was impacting me.

Change-Id: I46e27be0a0fba6d07cbabc6c9ac52cd7b24f2bc0
Reviewed-on: https://go-review.googlesource.com/c/exp/+/170817
Run-TryBot: Katie Hockman <katie@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/notary/internal/tlog/tile.go b/notary/internal/tlog/tile.go
index 7c6ec23..855cb1e 100644
--- a/notary/internal/tlog/tile.go
+++ b/notary/internal/tlog/tile.go
@@ -299,8 +299,7 @@
 	// the parents are being fetched anyway.
 	indexTileOrder := make([]int, len(indexes))
 	for i, x := range indexes {
-		level, n := SplitStoredHashIndex(x)
-		if n<<uint(level) >= r.tree.N {
+		if x >= StoredHashIndex(0, r.tree.N) {
 			return nil, fmt.Errorf("indexes not in tree")
 		}
 
diff --git a/notary/internal/tlog/tlog_test.go b/notary/internal/tlog/tlog_test.go
index a225a0f..cfc1233 100644
--- a/notary/internal/tlog/tlog_test.go
+++ b/notary/internal/tlog/tlog_test.go
@@ -166,6 +166,11 @@
 			}
 		}
 
+		// Check that ReadHashes will give an error if the index is not in the tree.
+		if _, err := thr.ReadHashes([]int64{(i + 1) * 2}); err == nil {
+			t.Fatalf("TileHashReader(%d).ReadHashes(%d) for index not in tree <nil>, want err", i, i+1)
+		}
+
 		// Check that tree proofs work, for all trees so far, using TileReader.
 		// To prove a tree that way, all you have to do is compute and verify its hash.
 		for j := int64(0); j <= i; j++ {