github.com/mre-fog/trillianxx@v1.1.2-0.20180615153820-ae375a99d36a/merkle/maphasher/maphasher_test.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package maphasher
    15  
    16  import (
    17  	"bytes"
    18  	"crypto"
    19  	"encoding/base64"
    20  	"testing"
    21  
    22  	"github.com/google/trillian/merkle/hashers"
    23  )
    24  
    25  const (
    26  	// Expected root hash of an empty sparse Merkle tree.
    27  	// This was taken from the C++ SparseMerkleTree tests in
    28  	// github.com/google/certificate-transparency.
    29  	emptyMapRootB64 = "xmifEIEqCYCXbZUz2Dh1KCFmFZVn7DUVVxbBQTr1PWo="
    30  	treeID          = int64(0)
    31  )
    32  
    33  func TestEmptyRoot(t *testing.T) {
    34  	emptyRoot, err := base64.StdEncoding.DecodeString(emptyMapRootB64)
    35  	if err != nil {
    36  		t.Fatalf("couldn't decode empty root base64 constant.")
    37  	}
    38  	mh := New(crypto.SHA256)
    39  	if got, want := mh.HashEmpty(treeID, nil, mh.BitLen()), emptyRoot; !bytes.Equal(got, want) {
    40  		t.Fatalf("HashEmpty(0): %x, want %x", got, want)
    41  	}
    42  }
    43  
    44  // Compares the old HStar2 empty branch algorithm to the new.
    45  func TestHStar2Equivalence(t *testing.T) {
    46  	m := New(crypto.SHA256)
    47  	leafHash, err := m.HashLeaf(treeID, nil, []byte(""))
    48  	if err != nil {
    49  		t.Fatalf("HashLeaf(): %v", err)
    50  	}
    51  	star := hstar{
    52  		hasher:          m,
    53  		hStarEmptyCache: [][]byte{leafHash},
    54  	}
    55  	fullDepth := m.Size() * 8
    56  	for i := 0; i < fullDepth; i++ {
    57  		if got, want := m.HashEmpty(treeID, nil, i), star.hStarEmpty(i); !bytes.Equal(got, want) {
    58  			t.Errorf("HashEmpty(%v): \n%x, want: \n%x", i, got, want)
    59  		}
    60  	}
    61  }
    62  
    63  // Old hstar2 empty cache algorithm.
    64  type hstar struct {
    65  	hasher          hashers.MapHasher
    66  	hStarEmptyCache [][]byte
    67  }
    68  
    69  // hStarEmpty calculates (and caches) the "null-hash" for the requested tree level.
    70  // Note: here level 0 is the leaf and level 255 is the root.
    71  func (s *hstar) hStarEmpty(n int) []byte {
    72  	if len(s.hStarEmptyCache) <= n {
    73  		emptyRoot := s.hStarEmpty(n - 1)
    74  		h := s.hasher.HashChildren(emptyRoot, emptyRoot)
    75  		s.hStarEmptyCache = append(s.hStarEmptyCache, h)
    76  	}
    77  	return s.hStarEmptyCache[n]
    78  }