@@ -168,12 +168,14 @@ pub fn node_hash(left: Hash, right: Hash) -> Hash {
168168 Hash ( result. into ( ) )
169169}
170170
171- /// Maps the tree coordinates `(level, n)` to a dense linear ordering that can be used for hash
172- /// storage. Hash storage implementations that store hashes in sequential storage can use this
173- /// function to compute where to read or write a given hash.
171+ /// Maps the tree coordinates `(level, n)` to a dense linear ordering that can
172+ /// be used for hash storage. Hash storage implementations that store hashes in
173+ /// sequential storage can use this function to compute where to read or write a
174+ /// given hash.
174175///
175- /// For information about the stored hash index ordering, see section 3.3 of Crosby and Wallach's
176- /// paper ["Efficient Data Structures for Tamper-Evident
176+ /// The stored hash index ordering is given by post-order (leaf, right, root)
177+ /// traversal of the nodes in the tree. For information, see section 3.3 of
178+ /// Crosby and Wallach's paper ["Efficient Data Structures for Tamper-Evident
177179/// Logging"](https://www.usenix.org/legacy/event/sec09/tech/full_papers/crosby.pdf).
178180pub fn stored_hash_index ( level : u8 , n : u64 ) -> u64 {
179181 // Level L's n'th hash is written right after level L+1's 2n+1'th hash.
@@ -206,7 +208,7 @@ pub fn split_stored_hash_index(index: u64) -> (u8, u64) {
206208 // so the n we want is in [index/2, index/2+log₂(index)].
207209 let mut n = index / 2 ;
208210 let mut index_n = stored_hash_index ( 0 , n) ;
209- assert ! ( index_n <= index, "bad math" ) ;
211+ debug_assert ! ( index_n <= index, "bad math" ) ;
210212 loop {
211213 // Each new record n adds 1 + trailingZeros(n) hashes.
212214 let x = index_n + 1 + u64:: from ( ( n + 1 ) . trailing_zeros ( ) ) ;
@@ -282,7 +284,7 @@ pub fn stored_hashes_for_record_hash<R: HashReader>(
282284
283285 // Fetch hashes.
284286 let old = r. read_hashes ( & indexes) ?;
285- assert_eq ! ( old. len( ) , indexes. len( ) , "bad read_hashes implementation" ) ;
287+ debug_assert_eq ! ( old. len( ) , indexes. len( ) , "bad read_hashes implementation" ) ;
286288
287289 // Build new hashes.
288290 let mut h = h;
@@ -366,13 +368,13 @@ pub fn subtree_hash_indexes(n: &Subtree) -> Vec<u64> {
366368pub fn subtree_hash < R : HashReader > ( n : & Subtree , r : & R ) -> Result < Hash , TlogError > {
367369 let indexes = n. hash_indexes ( ) ;
368370 let mut hashes = r. read_hashes ( & indexes) ?;
369- assert_eq ! (
371+ debug_assert_eq ! (
370372 hashes. len( ) ,
371373 indexes. len( ) ,
372374 "bad read_hashes implementation"
373375 ) ;
374376 let hash = n. hash ( & mut hashes) ;
375- assert ! ( hashes. is_empty( ) , "bad math in subtree_hash" ) ;
377+ debug_assert ! ( hashes. is_empty( ) , "bad math in subtree_hash" ) ;
376378 Ok ( hash)
377379}
378380
@@ -416,14 +418,14 @@ pub fn subtree_inclusion_proof<R: HashReader>(
416418 return Ok ( vec ! [ ] ) ;
417419 }
418420 let mut hashes = r. read_hashes ( & indexes) ?;
419- assert_eq ! (
421+ debug_assert_eq ! (
420422 hashes. len( ) ,
421423 indexes. len( ) ,
422424 "bad read_hashes implementation"
423425 ) ;
424426 // SUBTREE_PROOF(start, start + 1, D_n) = PATH(start, D_n)
425427 let proof = n. subproof ( m, & mut hashes, true ) ?;
426- assert ! (
428+ debug_assert ! (
427429 hashes. is_empty( ) ,
428430 "bad index math in prove_subtree_inclusion"
429431 ) ;
@@ -574,13 +576,13 @@ pub fn subtree_consistency_proof<R: HashReader>(
574576 return Ok ( vec ! [ ] ) ;
575577 }
576578 let mut hashes = r. read_hashes ( & indexes) ?;
577- assert_eq ! (
579+ debug_assert_eq ! (
578580 hashes. len( ) ,
579581 indexes. len( ) ,
580582 "bad read_hashes implementation"
581583 ) ;
582584 let proof = n. subproof ( m, & mut hashes, true ) ?;
583- assert ! (
585+ debug_assert ! (
584586 hashes. is_empty( ) ,
585587 "bad index math in subtree_consistency_proof"
586588 ) ;
@@ -759,9 +761,12 @@ fn lsb_set(i: u64) -> bool {
759761 ( i & 1 ) == 1
760762}
761763
762- /// A subtree of a Merkle Tree of size `n` is defined by two integers `lo` and `hi` such that:
764+ /// A subtree of a Merkle Tree of size `n` is defined by two integers `lo` and
765+ /// `hi` such that:
763766/// - 0 ≤ lo < hi ≤ n
764767/// - if `s` is the smallest power of two `≥ hi - lo`, `lo` is a multple of `s`
768+ ///
769+ /// <https://www.ietf.org/archive/id/draft-davidben-tls-merkle-tree-certs-06.html#section-4.1>
765770#[ derive( Debug , PartialEq , Eq ) ]
766771pub struct Subtree {
767772 lo : u64 ,
@@ -878,7 +883,7 @@ impl Subtree {
878883 let mut lo = self . lo ;
879884 while lo < self . hi {
880885 let ( k, level) = maxpow2 ( self . hi - lo + 1 ) ;
881- assert ! ( lo & ( k - 1 ) == 0 && lo < self . hi, "bad math in walk_hash" ) ;
886+ debug_assert ! ( lo & ( k - 1 ) == 0 && lo < self . hi, "bad math in walk_hash" ) ;
882887 f ( level, lo) ;
883888 lo += k;
884889 }
@@ -914,7 +919,7 @@ impl Subtree {
914919 } ;
915920 self . walk_hash ( & mut get_hash) ;
916921
917- assert ! (
922+ debug_assert ! (
918923 hashes. len( ) >= num_hashes,
919924 "not enough hashes for reconstruction"
920925 ) ;
@@ -997,7 +1002,7 @@ impl Subtree {
9971002 // `known` set to false as the right child of `m` was not one of
9981003 // the inputs to the algorithm.
9991004 let ( m_left, m_right) = m. children ( ) ;
1000- assert ! ( m_left == left, "expected left children to match" ) ;
1005+ debug_assert ! ( m_left == left, "expected left children to match" ) ;
10011006 right. walk_subproof ( & m_right, false , f, strategy) ?
10021007 } ;
10031008
0 commit comments