and Szydlo (Szydlo, 04). The first key observation
on which our algorithm is based is that during the
computation of node (A, i) its children (A − 1, 2i),
(A − 1, 2i + 1) as well as all other descendants are
computed. Therefore by storing intermediate results
of evaluation some future computations can be saved.
Actually, for every computed node N on level ih all
its descendants on levels ih − 1, . . . , ih − h (i.e. a
complete subtree of height h rooted in N) will be re-
tained to be used in the future authentication paths.
Thus only nodes at height ih, i = 1, . . . , L will be
computed directly (see Fig 2).
Another key observation is that we can schedule
the computations of the nodes needed in the future in
such a way that at most H storage units are necessary
to store all tail values.
In section 6 a further constant improvement is de-
scribed. We show that in a subtree only nodes with
odd indices must be stored. We also show that the
next subtree can be computed as the nodes of the cur-
rent subtree are discarded so that the total number of
nodes used by subtrees on a level is 2
h
.
4 ALGORITHM DESCRIPTION
Our algorithm consists of three phases: root genera-
tion, output, and verification. During the first phase
the root of the Merkle tree is generated. Addition-
ally, the initial set of subtrees with roots at (0, 2
ih
),
i = 1, . . . , L is computed and stored. The verification
phase is identical to the traditional verification phase
(see, for instance, (Jakobsson et al., 03)). The output
phase consists of 2
H
rounds, and during round j an
image of the j-th leaf and its authentication path are
output. In the rest of this section we will describe an
algorithm for the output phase and prove its correct-
ness.
For convenience we will measure time in rounds.
During each round 2L computation units are spent on
computation of subtrees needed in the future authen-
tication paths. Thus our algorithm starts at time 0 and
ends at time 2
H
− 1, and the i-th round starts at time
i. In the first part of the algorithm description we will
ignore the costs of all operations, except of the com-
putations of hash functions. Later we will show that
the number of other operations performed during a
round is O(L).
During round j we store L already computed sub-
trees with roots at (sh, m
s
) where j ∈ [m
s
2
sh
, (m
s
+
1)2
sh
), s = 0, 1, . . . , L. During the same round we
also spend 2L computation units in order to compute
jobs (sh, m
s
+ 1) and construct the corresponding
subtrees. At round (m
s
+ 1)2
sh
the subtree (sh, m
s
)
will be discarded, However the subtree (sh, m
s
+ 1)
will be retained for the next 2
sh
rounds, while subtree
(sh, m
s
+ 2) is computed.
During each round there are at most L different
jobs competing for 2L computation units. These jobs
will be called active. Active jobs are scheduled ac-
cording to the following rules:
1. A job (ih, k) k = 1, . . . , H/2
ih
becomes active at
time (k −1)2
ih
, i.e. during the (k −1)2
ih
-th round.
2. All active jobs (s
′
, k
s
′
) with s
′
> s such that mini-
mal level of (s
′
, k
s
′
) does not exceed s have priority
over the job (s, k
s
) on level s.
3. In all other cases jobs with the lower level have pri-
ority over jobs with the higher level.
Consider job (sh, i) that becomes active at time
2
sh
(i − 1). Rule 2 guarantees us that all jobs with
levels s
′
h such that s
′
> s do not store any tail val-
ues on levels 1, 2, . . . , sh − 1 when the computation
of job (sh, i) starts. Therefore, when job (sh, i) is
computed, only one tail node on each of the levels
(s − 1)h, (s − 1)h + 1, . . . , sh − 1 will be stored.
Now consider a job (s
′′
h, is
′′
) on level s
′′
h, s
′′
=
1, . . . , s − 1. If job (sh, i) stores a tail node on level
˜s < s
′′
, then (s
′′
h, is
′′
) is either already completed
(rule 3), or did not start yet (rule 2).
This scheduling guarantees us that at any time only
one tail value for a level i = 1, 2, . . . , H will be stored
by all jobs (sh, i). Only 2L subtrees (one currently
used and one currently computed for each level ih)
must be stored at each round, and subtrees require
(2H/h)(2
h+1
−1) space. Hence the memory require-
ment of our algorithm is O((2H/h)2
h
) + O(H) =
O((H/h)2
h
).
These considerations allow us to formulate the fol-
lowing trade-off between time and space complexity.
Theorem 1 Merkle tree can be traversed in time
O(H/h) with O((H/h)2
h
) storage units for any h ≥
1.
Corollary 1 Merkle tree can be traversed in time
O(log n/ log
(3)
n) with
O(log n log log n/ log
(3)
n) storage units.
In the next subsections we will prove the algorithm
correctness by showing that all values are computed
on time, and we prove the time bound stated in the
theorem by analysis of the operations necessary for
the job scheduling.
4.1 Correctness Proof
In this section we show that job (sh, k) will be com-
pleted at time k2
sh
.
Lemma 1 Suppose that at time (k − 1)2
sh
for every
level i = h, 2h, . . . , (s−1)h, (s +1)h, . . . Lh there is
at most one unfinished job on level i. Then job (sh, k)
will be completed before k2
sh
.
OPTIMAL TRADE-OFF FOR MERKLE TREE TRAVERSAL
277