github.com/letsencrypt/trillian@v1.1.2-0.20180615153820-ae375a99d36a/merkle/hstar2_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  
    15  package merkle
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"math/big"
    21  	"testing"
    22  
    23  	"github.com/google/trillian/merkle/hashers"
    24  	"github.com/google/trillian/merkle/maphasher"
    25  	"github.com/google/trillian/storage"
    26  	"github.com/google/trillian/testonly"
    27  )
    28  
    29  const treeID = int64(0)
    30  
    31  var (
    32  	deB64 = testonly.MustDecodeBase64
    33  )
    34  
    35  // Some known answers for incrementally adding index/value pairs to a sparse tree.
    36  // rootB64 is the incremental root after adding the corresponding i/v pair, and
    37  // all i/v pairs which come before it.
    38  //
    39  // Values were calculated with the C++/Python sparse Merkle tree code in the
    40  // github.com/google/certificate-transparency repo.
    41  // TODO(alcutter): replace with hash-dependent computation. How is this computed?
    42  var simpleTestVector = []struct {
    43  	index, value, root []byte
    44  }{
    45  	{nil, nil, deB64("xmifEIEqCYCXbZUz2Dh1KCFmFZVn7DUVVxbBQTr1PWo=")}, // Empty tree.
    46  	{testonly.HashKey("a"), []byte("0"), deB64("nP1psZp1bu3jrY5Yv89rI+w5ywe9lLqI2qZi5ibTSF0=")},
    47  	{testonly.HashKey("b"), []byte("1"), deB64("EJ1Rw6DQT9bDn2Zbn7u+9/j799PSdqT9gfBymS9MBZY=")},
    48  	{testonly.HashKey("a"), []byte("2"), deB64("2rAZz4HJAMJqJ5c8ClS4wEzTP71GTdjMZMe1rKWPA5o=")},
    49  }
    50  
    51  // createHStar2Leaves returns a []HStar2LeafHash formed by the mapping of index, value ...
    52  // createHStar2Leaves panics if len(iv) is odd. Duplicate i/v pairs get over written.
    53  func createHStar2Leaves(treeID int64, hasher hashers.MapHasher, iv ...[]byte) ([]HStar2LeafHash, error) {
    54  	if len(iv)%2 != 0 {
    55  		panic(fmt.Sprintf("merkle: createHstar2Leaves got odd number of iv pairs: %v", len(iv)))
    56  	}
    57  	m := make(map[string]HStar2LeafHash)
    58  	var index []byte
    59  	for i, b := range iv {
    60  		if i%2 == 0 {
    61  			index = b
    62  			continue
    63  		}
    64  		leafHash, err := hasher.HashLeaf(treeID, index, b)
    65  		if err != nil {
    66  			return nil, err
    67  		}
    68  		m[fmt.Sprintf("%x", index)] = HStar2LeafHash{
    69  			Index:    new(big.Int).SetBytes(index),
    70  			LeafHash: leafHash,
    71  		}
    72  	}
    73  
    74  	r := make([]HStar2LeafHash, 0, len(m))
    75  	for _, v := range m {
    76  		r = append(r, v)
    77  	}
    78  	return r, nil
    79  }
    80  
    81  func TestHStar2SimpleDataSetKAT(t *testing.T) {
    82  	s := NewHStar2(treeID, maphasher.Default)
    83  
    84  	iv := [][]byte{}
    85  	for i, x := range simpleTestVector {
    86  		iv = append(iv, x.index, x.value)
    87  		values, err := createHStar2Leaves(treeID, maphasher.Default, iv...)
    88  		if err != nil {
    89  			t.Fatalf("createHStar2Leaves(): %v", err)
    90  		}
    91  		root, err := s.HStar2Root(s.hasher.BitLen(), values)
    92  		if err != nil {
    93  			t.Errorf("Failed to calculate root at iteration %d: %v", i, err)
    94  			continue
    95  		}
    96  		if got, want := root, x.root; !bytes.Equal(got, want) {
    97  			t.Errorf("Root: %x, want: %x", got, want)
    98  		}
    99  	}
   100  }
   101  
   102  // TestHStar2GetSet ensures that we get the same roots as above when we
   103  // incrementally calculate roots.
   104  func TestHStar2GetSet(t *testing.T) {
   105  	// Node cache is shared between tree builds and in effect plays the role of
   106  	// the TreeStorage layer.
   107  	cache := make(map[string][]byte)
   108  	hasher := maphasher.Default
   109  
   110  	for i, x := range simpleTestVector {
   111  		s := NewHStar2(treeID, hasher)
   112  		values, err := createHStar2Leaves(treeID, hasher, x.index, x.value)
   113  		if err != nil {
   114  			t.Fatalf("createHStar2Leaves(): %v", err)
   115  		}
   116  		// ensure we're going incrementally, one leaf at a time.
   117  		if len(values) != 1 {
   118  			t.Fatalf("Should only have 1 leaf per run, got %d", len(values))
   119  		}
   120  		root, err := s.HStar2Nodes(nil, s.hasher.BitLen(), values,
   121  			func(depth int, index *big.Int) ([]byte, error) {
   122  				return cache[fmt.Sprintf("%x/%d", index, depth)], nil
   123  			},
   124  			func(depth int, index *big.Int, hash []byte) error {
   125  				cache[fmt.Sprintf("%x/%d", index, depth)] = hash
   126  				return nil
   127  			})
   128  		if err != nil {
   129  			t.Errorf("Failed to calculate root at iteration %d: %v", i, err)
   130  			continue
   131  		}
   132  		if got, want := root, x.root; !bytes.Equal(got, want) {
   133  			t.Errorf("Root: %x, want: %x", got, want)
   134  		}
   135  	}
   136  }
   137  
   138  // Create intermediate "root" values for the passed in HStar2LeafHashes.
   139  // These "root" hashes are from (assumed distinct) subtrees of size
   140  // 256-prefixSize, and can be passed in as leaves to top-subtree calculation.
   141  func rootsForTrimmedKeys(t *testing.T, prefixSize int, lh []HStar2LeafHash) []HStar2LeafHash {
   142  	var ret []HStar2LeafHash
   143  	hasher := maphasher.Default
   144  	s := NewHStar2(treeID, hasher)
   145  	for i := range lh {
   146  		subtreeDepth := s.hasher.BitLen() - prefixSize
   147  		prefix := lh[i].Index.Bytes()
   148  		// Left pad prefix with zeros back out to 32 bytes.
   149  		for len(prefix) < 32 {
   150  			prefix = append([]byte{0}, prefix...)
   151  		}
   152  		prefix = prefix[:prefixSize/8] // We only want the first prefixSize bytes.
   153  		root, err := s.HStar2Nodes(prefix, subtreeDepth, []HStar2LeafHash{lh[i]}, nil, nil)
   154  		if err != nil {
   155  			t.Fatalf("Failed to calculate root %v", err)
   156  		}
   157  
   158  		ret = append(ret, HStar2LeafHash{
   159  			Index:    storage.NewNodeIDFromPrefixSuffix(prefix, storage.Suffix{}, hasher.BitLen()).BigInt(),
   160  			LeafHash: root,
   161  		})
   162  	}
   163  	return ret
   164  }
   165  
   166  // Checks that splitting the calculation of a 256-level tree into two phases
   167  // (single top subtree of size n, and multipl bottom subtrees of size 256-n)
   168  // still arrives at the same Known Answers for root hash.
   169  func TestHStar2OffsetRootKAT(t *testing.T) {
   170  	s := NewHStar2(treeID, maphasher.Default)
   171  	iv := [][]byte{}
   172  	for i, x := range simpleTestVector {
   173  		iv = append(iv, x.index, x.value)
   174  		// start at 24 so we can assume that key prefixes are probably unique by then
   175  		// TODO(al): improve rootsForTrimmedKeys to use a map and remove this
   176  		// requirement.
   177  		for size := 24; size < 256; size += 8 {
   178  			leaves, err := createHStar2Leaves(treeID, maphasher.Default, iv...)
   179  			if err != nil {
   180  				t.Fatalf("createHStar2Leaves(): %v", err)
   181  			}
   182  			intermediates := rootsForTrimmedKeys(t, size, leaves)
   183  
   184  			root, err := s.HStar2Nodes(nil, size, intermediates, nil, nil)
   185  			if err != nil {
   186  				t.Errorf("Failed to calculate root at iteration %d: %v", i, err)
   187  				continue
   188  			}
   189  			if got, want := root, x.root; !bytes.Equal(got, want) {
   190  				t.Errorf("HStar2Nodes(i: %v, size:%v): %x, want: %x", i, size, got, want)
   191  			}
   192  		}
   193  	}
   194  }
   195  
   196  func TestHStar2NegativeTreeLevelOffset(t *testing.T) {
   197  	s := NewHStar2(treeID, maphasher.Default)
   198  
   199  	_, err := s.HStar2Nodes(make([]byte, 31), 9, []HStar2LeafHash{}, nil, nil)
   200  	if got, want := err, ErrSubtreeOverrun; got != want {
   201  		t.Fatalf("Hstar2Nodes(): %v, want %v", got, want)
   202  	}
   203  }