# How does a “Tiger Tree Hash” handle data whose size isn't a power of two?

Constructing a hash tree is simple enough if the data fits into a number of blocks that is a power of two.

root = H(H(A+B)+H(C+D))
/            \
H(A+B)             H(C+D)
/    \              /   \
A      B            C     D


In other cases, there is some flexibility. The missing blocks could be replaced with zeroes...

root = H(H(A+B)+H(C+0))
/            \
H(A+B)             H(C+0)
/    \              /   \
A      B            C     0


...passed up the tree...

root = H(H(A+B)+C)
/      |
H(A+B)       |
/    \       |
A      B      C


...hashed up the tree...

root = H(H(A+B)+H(C))
/       |
H(A+B)       H(C)
/     \       |
A       B      C


...or something different...

root = H(H(A)+H(B+C))
/       |
H(A)     H(B+C)
/        /    \
A        B      C


...and I'm just assuming that they do anything else like padding incomplete blocks before hashing.

The term "Tiger Tree Hash" seems to be used to refer to the root of a specific type of Tiger-based hash tree, but I haven't been able to find the details documented anywhere. How are such hashes constructed?

-
You might want to rephrase that question, because a tree hash can be implemented any way you like. –  Henrick Hellström Mar 15 '12 at 17:50
@HenrickHellström Edited a bit to clarify my meaning; I'm asking about the implementation called "Tiger Tree Hash"/TTH in peer-to-peer protocols, not about Tiger-based hash trees in general. –  Jeremy Banks Mar 15 '12 at 17:59

The Tree Hash EXchange format (THEX) spec (which seems to have dropped off the web, but is still available on archive.org) says, in section 2:

### 2.1 Hash Functions

The strength of the hash tree construct is only as strong as the underlying hash algorithm. Thus, it is RECOMMENDED that a secure hash algorithm such as SHA-1 be used as the basis of the hash tree.

In order to protect against collisions between leaf hashes and internal hashes, different hash constructs are used to hash the leaf nodes and the internal nodes. The same hash algorithm is used as the basis of each construct, but a single '1' byte in network byte order, or 0x01 is prepended to the input of the internal node hashes, and a single '0' byte, or 0x00 is prepended to the input of the leaf node hashes.

Let H() be the secure hash algorithm, for example SHA-1.

internal hash function = IH(X) = H(0x01, X)

leaf hash function = LH(X) = H(0x00, X)


### 2.2 Unbalanced Trees

For trees that are unbalanced -- that is, they have a number of leaves which is not a power of 2 -- interim hash values which do not have a sibling value to which they may be concatenated are promoted, unchanged, up the tree until a sibling is found.

For example, consider a file made up of 5 segments, S1, S2, S3, S4, and S5.

                     ROOT=IH(H+E)
/        \
/          \
H=IH(F+G)          E
/       \           \
/         \           \
F=IH(A+B)       G=IH(C+D)     E
/     \           /     \      \
/       \         /       \      \
A=LH(S1)  B=LH(S2) C=LH(S3)  D=LH(S4) E=LH(S5)


In the above example, E does not have any immediate siblings with which to be combined to calculate the next generation. So, E is promoted up the tree, without being rehashed, until it can be paired with value H. The values H and E are then concatenated, and hashed, to produce the ROOT hash.

-
I just want to emphasize that the difference between inner and leaf hashing is very important. for security. –  CodesInChaos Mar 17 '12 at 12:49
I have inquired further about this point here: What is the purpose of using different hash functions for the leaves and internals of a hash tree? –  Jeremy Banks Mar 17 '12 at 15:14