github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/merkletree2/tree_test.go (about)

     1  package merkletree2
     2  
     3  import (
     4  	"context"
     5  	"crypto/sha256"
     6  	"fmt"
     7  	"math/rand"
     8  	"testing"
     9  
    10  	"github.com/keybase/client/go/logger"
    11  	"github.com/keybase/client/go/msgpack"
    12  
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func TestEmptyTree(t *testing.T) {
    17  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
    18  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
    19  	defaultStep := 2
    20  
    21  	kvps1_1bit, kvps2_1bit, _ := getSampleKVPS1bit()
    22  	kvps1_3bits, kvps2_3bits, _ := getSampleKVPS3bits()
    23  
    24  	tests := []struct {
    25  		cfg   Config
    26  		kvps1 []KeyValuePair
    27  		kvps2 []KeyValuePair
    28  	}{
    29  		{config1bitU, kvps1_1bit, kvps2_1bit},
    30  		{config2bitsU, kvps1_1bit, kvps2_1bit},
    31  		{config3bitsU, kvps1_3bits, kvps2_3bits},
    32  		{config1bitB, kvps1_1bit, kvps2_1bit},
    33  		{config2bitsB, kvps1_1bit, kvps2_1bit},
    34  		{config3bitsB, kvps1_3bits, kvps2_3bits},
    35  	}
    36  
    37  	for _, test := range tests {
    38  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
    39  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
    40  			require.NoError(t, err)
    41  
    42  			seq, root, hash, err := tree.GetLatestRoot(NewLoggerContextTodoForTesting(t), nil)
    43  			require.Error(t, err)
    44  			require.IsType(t, NoLatestRootFoundError{}, err)
    45  			require.Equal(t, Seqno(0), seq, "Tree should have Seqno 0 as no insertions were made, got %v instead", seq)
    46  			require.Nil(t, root.BareRootHash, "Tree root should not have a bareRootHash as no insertions were made")
    47  			require.Nil(t, hash, "Tree root should not have a root hash as no insertions were made")
    48  
    49  			for _, kvp := range test.kvps1 {
    50  				_, err := tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
    51  				require.Error(t, err)
    52  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
    53  				_, err = tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
    54  				require.Error(t, err)
    55  				require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
    56  
    57  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
    58  				require.Error(t, err)
    59  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
    60  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
    61  				require.Error(t, err)
    62  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
    63  			}
    64  
    65  			// building a tree without keys should succeed.
    66  			s, _, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, nil, nil)
    67  			require.NoError(t, err)
    68  			require.EqualValues(t, 1, s)
    69  		})
    70  	}
    71  
    72  }
    73  
    74  func TestBuildTreeAndGetKeyValuePair(t *testing.T) {
    75  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
    76  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
    77  	defaultStep := 2
    78  	kvps1_1bit, kvps2_1bit, _ := getSampleKVPS1bit()
    79  	kvps1_3bits, kvps2_3bits, _ := getSampleKVPS3bits()
    80  
    81  	tests := []struct {
    82  		cfg   Config
    83  		kvps1 []KeyValuePair
    84  		kvps2 []KeyValuePair
    85  	}{
    86  		{config1bitU, kvps1_1bit, kvps2_1bit},
    87  		{config2bitsU, kvps1_1bit, kvps2_1bit},
    88  		{config3bitsU, kvps1_3bits, kvps2_3bits},
    89  		{config1bitB, kvps1_1bit, kvps2_1bit},
    90  		{config2bitsB, kvps1_1bit, kvps2_1bit},
    91  		{config3bitsB, kvps1_3bits, kvps2_3bits},
    92  	}
    93  
    94  	for _, test := range tests {
    95  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
    96  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
    97  			require.NoError(t, err)
    98  
    99  			// This kvp has a key which is not part of test.kvps1
   100  			kvpAddedAtSeqno2 := test.kvps2[len(test.kvps2)-2]
   101  
   102  			_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 0, kvpAddedAtSeqno2.Key)
   103  			require.Error(t, err)
   104  			require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   105  			_, err = tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 0, kvpAddedAtSeqno2.Key)
   106  			require.Error(t, err)
   107  			require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   108  
   109  			_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   110  			require.Error(t, err)
   111  			require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   112  			_, err = tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   113  			require.Error(t, err)
   114  			require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
   115  
   116  			_, _, err = tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps1, nil)
   117  			require.NoError(t, err)
   118  
   119  			for _, kvp := range test.kvps1 {
   120  				_, err := tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
   121  				require.Error(t, err)
   122  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   123  				kvpRet, err := tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   124  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   125  				require.Equal(t, kvp.Key, kvpRet.Key)
   126  				require.Equal(t, kvp.Value, kvpRet.Value)
   127  				kvpRet, err = tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
   128  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   129  				require.Equal(t, kvp.Key, kvpRet.Key)
   130  				require.Equal(t, kvp.Value, kvpRet.Value)
   131  
   132  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
   133  				require.Error(t, err)
   134  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   135  				kvpRet, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   136  				require.NoError(t, err)
   137  				require.Equal(t, kvp.Key, kvpRet.Key)
   138  				require.Equal(t, kvp.Value, kvpRet.Value)
   139  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
   140  				require.Error(t, err)
   141  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   142  			}
   143  
   144  			_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   145  			require.Error(t, err)
   146  			require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
   147  			_, err = tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   148  			require.Error(t, err)
   149  			require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
   150  
   151  			_, _, err = tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps2, nil)
   152  			require.NoError(t, err)
   153  
   154  			for _, kvp := range test.kvps1 {
   155  				kvpRet, err := tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   156  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   157  				require.Equal(t, kvp.Key, kvpRet.Key)
   158  				require.Equal(t, kvp.Value, kvpRet.Value)
   159  
   160  				kvpRet, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   161  				require.NoError(t, err)
   162  				require.Equal(t, kvp.Value, kvpRet.Value)
   163  			}
   164  
   165  			_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   166  			require.Error(t, err)
   167  			require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
   168  			_, err = tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   169  			require.Error(t, err)
   170  			require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
   171  
   172  			for _, kvp := range test.kvps2 {
   173  				_, err := tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
   174  				require.Error(t, err)
   175  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   176  				kvpRet, err := tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 2, kvp.Key)
   177  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   178  				require.Equal(t, kvp.Key, kvpRet.Key)
   179  				require.Equal(t, kvp.Value, kvpRet.Value)
   180  				kvpRet, err = tree.GetKeyValuePairUnsafe(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
   181  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   182  				require.Equal(t, kvp.Key, kvpRet.Key)
   183  				require.Equal(t, kvp.Value, kvpRet.Value)
   184  
   185  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
   186  				require.Error(t, err)
   187  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   188  				kvpRet, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 2, kvp.Key)
   189  				require.NoError(t, err)
   190  				require.Equal(t, kvp.Value, kvpRet.Value)
   191  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
   192  				require.Error(t, err)
   193  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   194  			}
   195  		})
   196  	}
   197  
   198  }
   199  
   200  func TestBuildTreeAndGetKeyValuePairWithProof(t *testing.T) {
   201  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
   202  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
   203  	defaultStep := 2
   204  	kvps1_1bit, kvps2_1bit, _ := getSampleKVPS1bit()
   205  	kvps1_3bits, kvps2_3bits, _ := getSampleKVPS3bits()
   206  
   207  	tests := []struct {
   208  		cfg   Config
   209  		kvps1 []KeyValuePair
   210  		kvps2 []KeyValuePair
   211  	}{
   212  		{config1bitU, kvps1_1bit, kvps2_1bit},
   213  		{config2bitsU, kvps1_1bit, kvps2_1bit},
   214  		{config3bitsU, kvps1_3bits, kvps2_3bits},
   215  		{config1bitB, kvps1_1bit, kvps2_1bit},
   216  		{config2bitsB, kvps1_1bit, kvps2_1bit},
   217  		{config3bitsB, kvps1_3bits, kvps2_3bits},
   218  	}
   219  
   220  	for _, test := range tests {
   221  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
   222  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
   223  			require.NoError(t, err)
   224  
   225  			// This kvp has a key which is not part of test.kvps1
   226  			kvpAddedAtSeqno2 := test.kvps2[len(test.kvps2)-2]
   227  
   228  			_, _, err = tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 0, kvpAddedAtSeqno2.Key)
   229  			require.Error(t, err)
   230  			require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   231  
   232  			_, _, err = tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   233  			require.Error(t, err)
   234  			require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   235  
   236  			_, _, err = tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps1, nil)
   237  			require.NoError(t, err)
   238  
   239  			for _, kvp := range test.kvps1 {
   240  				_, _, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
   241  				require.Error(t, err)
   242  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   243  				kvpRet, _, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   244  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   245  				require.Equal(t, kvp.Key, kvpRet.Key)
   246  				require.Equal(t, kvp.Value, kvpRet.Value)
   247  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
   248  				require.Error(t, err)
   249  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   250  			}
   251  
   252  			_, _, err = tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   253  			require.Error(t, err)
   254  			require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
   255  
   256  			_, _, err = tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps2, nil)
   257  			require.NoError(t, err)
   258  
   259  			for _, kvp := range test.kvps1 {
   260  				kvpRet, _, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   261  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   262  				require.Equal(t, kvp.Key, kvpRet.Key)
   263  				require.Equal(t, kvp.Value, kvpRet.Value)
   264  			}
   265  			_, _, err = tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvpAddedAtSeqno2.Key)
   266  			require.Error(t, err)
   267  			require.IsType(t, KeyNotFoundError{}, err, "Expected KeyNotFoundError, but got %v", err)
   268  
   269  			for _, kvp := range test.kvps2 {
   270  				_, _, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 0, kvp.Key)
   271  				require.Error(t, err)
   272  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   273  				kvpRet, _, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 2, kvp.Key)
   274  				require.NoError(t, err, "Unexpected error for key %v: %v", kvp.Key, err)
   275  				require.Equal(t, kvp.Key, kvpRet.Key)
   276  				require.Equal(t, kvp.Value, kvpRet.Value)
   277  				_, err = tree.GetKeyValuePair(NewLoggerContextTodoForTesting(t), nil, 7, kvp.Key)
   278  				require.Error(t, err)
   279  				require.IsType(t, InvalidSeqnoError{}, err, "Expected InvalidSeqnoError, but got %v", err)
   280  			}
   281  		})
   282  	}
   283  }
   284  
   285  func TestHonestMerkleProofsVerifySuccesfully(t *testing.T) {
   286  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
   287  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
   288  	defaultStep := 2
   289  	kvps1_1bit, kvps2_1bit, _ := getSampleKVPS1bit()
   290  	kvps1_3bits, kvps2_3bits, _ := getSampleKVPS3bits()
   291  
   292  	config3bits2valsPerLeafU, err := NewConfig(IdentityHasher{}, false, 3, 2, 3, ConstructStringValueContainer)
   293  	require.NoError(t, err)
   294  	config3bits2valsPerLeafB, err := NewConfig(IdentityHasherBlinded{}, true, 3, 2, 3, ConstructStringValueContainer)
   295  	require.NoError(t, err)
   296  
   297  	tests := []struct {
   298  		cfg   Config
   299  		kvps1 []KeyValuePair
   300  		kvps2 []KeyValuePair
   301  	}{
   302  		{config1bitU, kvps1_1bit, kvps2_1bit},
   303  		{config2bitsU, kvps1_1bit, kvps2_1bit},
   304  		{config3bitsU, kvps1_3bits, kvps2_3bits},
   305  		{config3bits2valsPerLeafU, kvps1_3bits, kvps2_3bits},
   306  		{config1bitB, kvps1_1bit, kvps2_1bit},
   307  		{config2bitsB, kvps1_1bit, kvps2_1bit},
   308  		{config3bitsB, kvps1_3bits, kvps2_3bits},
   309  		{config3bits2valsPerLeafB, kvps1_3bits, kvps2_3bits},
   310  	}
   311  
   312  	for _, test := range tests {
   313  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
   314  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
   315  			require.NoError(t, err)
   316  			verifier := MerkleProofVerifier{cfg: test.cfg}
   317  
   318  			s1, rootHash1, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps1[:len(test.kvps1)-1], nil)
   319  			require.NoError(t, err)
   320  			require.EqualValues(t, 1, s1)
   321  
   322  			for _, kvp := range test.kvps1[:len(test.kvps1)-1] {
   323  				kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   324  				require.NoError(t, err)
   325  				require.True(t, kvp.Key.Equal(kvpRet.Key))
   326  				require.Equal(t, kvp.Value, kvpRet.Value)
   327  				require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHash1))
   328  			}
   329  			// test absence proofs
   330  			kvp := test.kvps1[len(test.kvps1)-1]
   331  			eVal, proof, err := tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash1, kvp.Key)
   332  			require.NoError(t, err)
   333  			require.Nil(t, eVal)
   334  			require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), kvp.Key, &proof, rootHash1))
   335  
   336  			s2, rootHash2, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps2[:len(test.kvps2)-1], nil)
   337  			require.NoError(t, err)
   338  			require.EqualValues(t, 2, s2)
   339  
   340  			for _, kvp := range test.kvps2[:len(test.kvps2)-1] {
   341  				kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 2, kvp.Key)
   342  				require.NoError(t, err)
   343  				require.Equal(t, kvp.Key, kvpRet.Key)
   344  				require.Equal(t, kvp.Value, kvpRet.Value)
   345  				require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHash2))
   346  			}
   347  			// test absence proofs
   348  			kvp = test.kvps2[len(test.kvps2)-1]
   349  			eVal, proof, err = tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash2, kvp.Key)
   350  			require.NoError(t, err)
   351  			require.Nil(t, eVal)
   352  			require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), kvp.Key, &proof, rootHash2))
   353  
   354  			for _, kvp := range test.kvps1[:len(test.kvps1)-1] {
   355  				kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   356  				require.NoError(t, err)
   357  				require.True(t, kvp.Key.Equal(kvpRet.Key))
   358  				require.Equal(t, kvp.Value, kvpRet.Value)
   359  				require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHash1))
   360  			}
   361  			// test absence proofs
   362  			kvp = test.kvps1[len(test.kvps1)-1]
   363  			eVal, proof, err = tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash1, kvp.Key)
   364  			require.NoError(t, err)
   365  			require.Nil(t, eVal)
   366  			require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), kvp.Key, &proof, rootHash1))
   367  
   368  		})
   369  	}
   370  
   371  }
   372  
   373  func TestHonestMerkleProofsVerifySuccesfullyLargeTree(t *testing.T) {
   374  	blindedBinaryTreeConfig, err := NewConfig(NewBlindedSHA512_256v1Encoder(), true, 1, 1, 32, ConstructStringValueContainer)
   375  	require.NoError(t, err)
   376  
   377  	unblindedBinaryTreeConfig, err := NewConfig(SHA512_256Encoder{}, false, 1, 1, 32, ConstructStringValueContainer)
   378  	require.NoError(t, err)
   379  
   380  	blinded16aryTreeConfig, err := NewConfig(NewBlindedSHA512_256v1Encoder(), true, 4, 4, 32, ConstructStringValueContainer)
   381  	require.NoError(t, err)
   382  
   383  	blinded16aryShallowTreeConfig, err := NewConfig(NewBlindedSHA512_256v1Encoder(), true, 4, 4, 2, ConstructStringValueContainer)
   384  	require.NoError(t, err)
   385  
   386  	blindedBinaryShallowTreeConfig, err := NewConfig(NewBlindedSHA512_256v1Encoder(), true, 1, 1, 2, ConstructStringValueContainer)
   387  	require.NoError(t, err)
   388  
   389  	// Make test deterministic.
   390  	rand.Seed(1)
   391  
   392  	tests := []struct {
   393  		cfg         Config
   394  		step        int
   395  		numIncPairs int
   396  		numExcPairs int
   397  		rootVersion RootVersion
   398  	}{
   399  		{blindedBinaryTreeConfig, 63, 8000, 800, RootVersionV1},
   400  		{blindedBinaryTreeConfig, 1, 200, 200, RootVersionV1},
   401  		{blindedBinaryTreeConfig, 2, 200, 200, RootVersionV1},
   402  		{blindedBinaryTreeConfig, 80, 200, 200, RootVersionV1},
   403  		{unblindedBinaryTreeConfig, 16, 1000, 200, RootVersionV1},
   404  		{blinded16aryTreeConfig, 16, 1000, 200, RootVersionV1},
   405  		{blindedBinaryShallowTreeConfig, 16, 1000, 200, RootVersionV1},
   406  		{blinded16aryShallowTreeConfig, 16, 1000, 200, RootVersionV1},
   407  	}
   408  
   409  	for _, test := range tests {
   410  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
   411  			tree, err := NewTree(test.cfg, test.step, NewInMemoryStorageEngine(test.cfg), test.rootVersion)
   412  			require.NoError(t, err)
   413  			verifier := MerkleProofVerifier{cfg: test.cfg}
   414  
   415  			keys, keysNotInTree, err := makeRandomKeysForTesting(uint(test.cfg.KeysByteLength), test.numIncPairs, test.numExcPairs)
   416  			require.NoError(t, err)
   417  			kvp1, err := makeRandomKVPFromKeysForTesting(keys)
   418  			require.NoError(t, err)
   419  			kvp2, err := makeRandomKVPFromKeysForTesting(keys)
   420  			require.NoError(t, err)
   421  
   422  			s1, rootHash1, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvp1, nil)
   423  			require.NoError(t, err)
   424  			require.EqualValues(t, 1, s1)
   425  
   426  			for i, key := range keys {
   427  				kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, key)
   428  				require.NoError(t, err)
   429  				require.True(t, key.Equal(kvpRet.Key))
   430  				require.Equal(t, kvp1[i].Value, kvpRet.Value)
   431  				err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp1[i], &proof, rootHash1)
   432  				require.NoErrorf(t, err, "Error verifying proof for key %v: %v", key, err)
   433  			}
   434  			for _, key := range keysNotInTree {
   435  				eVal, proof, err := tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash1, key)
   436  				require.NoError(t, err)
   437  				require.Nil(t, eVal)
   438  				require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), key, &proof, rootHash1))
   439  			}
   440  
   441  			s2, rootHash2, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvp2, nil)
   442  			require.NoError(t, err)
   443  			require.EqualValues(t, 2, s2)
   444  
   445  			for i, key := range keys {
   446  				kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 2, key)
   447  				require.NoError(t, err)
   448  				require.True(t, key.Equal(kvpRet.Key))
   449  				require.Equal(t, kvp2[i].Value, kvpRet.Value)
   450  				require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp2[i], &proof, rootHash2))
   451  
   452  				kvpRet, proof, err = tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, key)
   453  				require.NoError(t, err)
   454  				require.True(t, key.Equal(kvpRet.Key))
   455  				require.Equal(t, kvp1[i].Value, kvpRet.Value)
   456  				require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp1[i], &proof, rootHash1))
   457  			}
   458  			for _, key := range keysNotInTree {
   459  				eVal, proof, err := tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash2, key)
   460  				require.NoError(t, err)
   461  				require.Nil(t, eVal)
   462  				require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), key, &proof, rootHash2))
   463  
   464  				eVal, proof, err = tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash2, key)
   465  				require.NoError(t, err)
   466  				require.Nil(t, eVal)
   467  				require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), key, &proof, rootHash2))
   468  			}
   469  		})
   470  	}
   471  
   472  }
   473  
   474  func TestSomeMaliciousInclusionProofsFail(t *testing.T) {
   475  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
   476  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
   477  	defaultStep := 2
   478  	kvps1_1bit, kvps2_1bit, _ := getSampleKVPS1bit()
   479  	kvps1_3bits, kvps2_3bits, _ := getSampleKVPS3bits()
   480  
   481  	config3bits2valsPerLeafU, err := NewConfig(IdentityHasher{}, false, 3, 2, 3, ConstructStringValueContainer)
   482  	require.NoError(t, err)
   483  	config3bits2valsPerLeafB, err := NewConfig(IdentityHasherBlinded{}, true, 3, 2, 3, ConstructStringValueContainer)
   484  	require.NoError(t, err)
   485  
   486  	tests := []struct {
   487  		cfg   Config
   488  		kvps1 []KeyValuePair
   489  		kvps2 []KeyValuePair
   490  	}{
   491  		{config1bitU, kvps1_1bit, kvps2_1bit},
   492  		{config2bitsU, kvps1_1bit, kvps2_1bit},
   493  		{config3bitsU, kvps1_3bits, kvps2_3bits},
   494  		{config3bits2valsPerLeafU, kvps1_3bits, kvps2_3bits},
   495  		{config1bitB, kvps1_1bit, kvps2_1bit},
   496  		{config2bitsB, kvps1_1bit, kvps2_1bit},
   497  		{config3bitsB, kvps1_3bits, kvps2_3bits},
   498  		{config3bits2valsPerLeafB, kvps1_3bits, kvps2_3bits},
   499  	}
   500  
   501  	for _, test := range tests {
   502  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
   503  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
   504  			require.NoError(t, err)
   505  			verifier := MerkleProofVerifier{cfg: test.cfg}
   506  
   507  			s1, rootHash1, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps1, nil)
   508  			require.NoError(t, err)
   509  			require.EqualValues(t, 1, s1)
   510  
   511  			for _, kvp := range test.kvps1 {
   512  				// First, sanity check that honest proofs pass
   513  				kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   514  				require.NoError(t, err)
   515  				require.Equal(t, kvp.Value, kvpRet.Value)
   516  				require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHash1))
   517  
   518  				// Change the value
   519  				kvpFakeVal := KeyValuePair{Key: kvp.Key, Value: "ALTERED_VALUE"}
   520  				err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvpFakeVal, &proof, rootHash1)
   521  				require.Error(t, err)
   522  				require.IsType(t, ProofVerificationFailedError{}, err)
   523  
   524  				// Change the key
   525  				keyFake := Key(append([]byte(nil), ([]byte(kvp.Key))...))
   526  				([]byte(keyFake))[0] = 1 + ([]byte(keyFake))[0]
   527  				kvpFakeKey := KeyValuePair{Key: keyFake, Value: kvp.Value}
   528  				err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvpFakeKey, &proof, rootHash1)
   529  				require.Error(t, err)
   530  				require.IsType(t, ProofVerificationFailedError{}, err)
   531  
   532  				// Change the root hash
   533  				rootHashFake := Hash(append([]byte(nil), ([]byte(rootHash1))...))
   534  				([]byte(rootHashFake))[0] = 1 + ([]byte(rootHashFake))[0]
   535  				err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHashFake)
   536  				require.Error(t, err)
   537  				require.IsType(t, ProofVerificationFailedError{}, err)
   538  
   539  				// nil root hash
   540  				err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, nil)
   541  				require.Error(t, err)
   542  				require.IsType(t, ProofVerificationFailedError{}, err)
   543  
   544  				// empty proof
   545  				err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &MerkleInclusionProof{}, rootHash1)
   546  				require.Error(t, err)
   547  				require.IsType(t, ProofVerificationFailedError{}, err)
   548  
   549  				// Change the blinding key-specific secret (where appropriate)
   550  				if tree.cfg.UseBlindedValueHashes {
   551  					require.NotNil(t, proof.KeySpecificSecret)
   552  					require.True(t, len(proof.KeySpecificSecret) > 0, "Kss: %X", proof.KeySpecificSecret)
   553  
   554  					fakeKSS := KeySpecificSecret(append([]byte(nil), ([]byte)(proof.KeySpecificSecret)...))
   555  					([]byte(fakeKSS))[0] = 1 + ([]byte(fakeKSS))[0]
   556  					fakeProof := proof
   557  					fakeProof.KeySpecificSecret = fakeKSS
   558  					err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeProof, rootHash1)
   559  					require.Error(t, err)
   560  					require.IsType(t, ProofVerificationFailedError{}, err)
   561  				}
   562  			}
   563  		})
   564  	}
   565  }
   566  
   567  func TestSomeMaliciousExclusionProofsFail(t *testing.T) {
   568  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
   569  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
   570  	defaultStep := 2
   571  	kvps1_1bit, _, _ := getSampleKVPS1bit()
   572  	kvps1_3bits, _, _ := getSampleKVPS3bits()
   573  
   574  	config3bits2valsPerLeafU, err := NewConfig(IdentityHasher{}, false, 3, 2, 3, ConstructStringValueContainer)
   575  	require.NoError(t, err)
   576  	config3bits2valsPerLeafB, err := NewConfig(IdentityHasherBlinded{}, true, 3, 2, 3, ConstructStringValueContainer)
   577  	require.NoError(t, err)
   578  
   579  	tests := []struct {
   580  		cfg      Config
   581  		kvps1    []KeyValuePair
   582  		extraKey Key
   583  	}{
   584  		{config1bitU, kvps1_1bit, []byte{0xaa}},
   585  		{config2bitsU, kvps1_1bit, []byte{0xaa}},
   586  		{config3bitsU, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   587  		{config3bits2valsPerLeafU, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   588  		{config1bitB, kvps1_1bit, []byte{0xaa}},
   589  		{config2bitsB, kvps1_1bit, []byte{0xaa}},
   590  		{config3bitsB, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   591  		{config3bits2valsPerLeafB, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   592  	}
   593  
   594  	for _, test := range tests {
   595  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
   596  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
   597  			require.NoError(t, err)
   598  			verifier := MerkleProofVerifier{cfg: test.cfg}
   599  
   600  			s1, rootHash1, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps1, nil)
   601  			require.NoError(t, err)
   602  			require.EqualValues(t, 1, s1)
   603  
   604  			// First, sanity check that honest proofs pass
   605  			eVal, proof, err := tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash1, test.extraKey)
   606  			require.NoError(t, err)
   607  			require.Nil(t, eVal)
   608  			require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), test.extraKey, &proof, rootHash1))
   609  
   610  			// This key is in the tree, so the exclusion proof should fail
   611  			keyFake := test.kvps1[0].Key
   612  			err = verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), keyFake, &proof, rootHash1)
   613  			require.Error(t, err)
   614  			require.IsType(t, ProofVerificationFailedError{}, err)
   615  			// Even an inclusion proof for the right key should fail when verified as an exclusion proof
   616  			eVal, incProof, err := tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash1, keyFake)
   617  			require.NoError(t, err)
   618  			require.NotNil(t, eVal)
   619  			err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), test.kvps1[0], &incProof, rootHash1)
   620  			require.NoError(t, err)
   621  			err = verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), test.kvps1[0].Key, &incProof, rootHash1)
   622  			require.Error(t, err)
   623  			require.IsType(t, ProofVerificationFailedError{}, err)
   624  
   625  			// Change the root hash
   626  			rootHashFake := Hash(append([]byte(nil), ([]byte(rootHash1))...))
   627  			([]byte(rootHashFake))[0] = 1 + ([]byte(rootHashFake))[0]
   628  			err = verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), test.extraKey, &proof, rootHashFake)
   629  			require.Error(t, err)
   630  			require.IsType(t, ProofVerificationFailedError{}, err)
   631  
   632  			// nil root hash
   633  			err = verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), test.extraKey, &proof, nil)
   634  			require.Error(t, err)
   635  			require.IsType(t, ProofVerificationFailedError{}, err)
   636  
   637  			// empty proof
   638  			err = verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), test.extraKey, &MerkleInclusionProof{}, rootHash1)
   639  			require.Error(t, err)
   640  			require.IsType(t, ProofVerificationFailedError{}, err)
   641  		})
   642  	}
   643  }
   644  
   645  func TestExclProofOnEmptyTree(t *testing.T) {
   646  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
   647  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
   648  	defaultStep := 2
   649  	kvps1_1bit, _, _ := getSampleKVPS1bit()
   650  	kvps1_3bits, _, _ := getSampleKVPS3bits()
   651  
   652  	config3bits2valsPerLeafU, err := NewConfig(IdentityHasher{}, false, 3, 2, 3, ConstructStringValueContainer)
   653  	require.NoError(t, err)
   654  	config3bits2valsPerLeafB, err := NewConfig(IdentityHasherBlinded{}, true, 3, 2, 3, ConstructStringValueContainer)
   655  	require.NoError(t, err)
   656  
   657  	tests := []struct {
   658  		cfg      Config
   659  		kvps1    []KeyValuePair
   660  		extraKey Key
   661  	}{
   662  		{config1bitU, kvps1_1bit, []byte{0xaa}},
   663  		{config2bitsU, kvps1_1bit, []byte{0xaa}},
   664  		{config3bitsU, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   665  		{config3bits2valsPerLeafU, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   666  		{config1bitB, kvps1_1bit, []byte{0xaa}},
   667  		{config2bitsB, kvps1_1bit, []byte{0xaa}},
   668  		{config3bitsB, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   669  		{config3bits2valsPerLeafB, kvps1_3bits, []byte{0xaa, 0xaa, 0xaa}},
   670  	}
   671  
   672  	for _, test := range tests {
   673  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
   674  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
   675  			require.NoError(t, err)
   676  			verifier := MerkleProofVerifier{cfg: test.cfg}
   677  
   678  			s1, rootHash1, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, nil, nil)
   679  			require.NoError(t, err)
   680  			require.EqualValues(t, 1, s1)
   681  
   682  			eVal, proof, err := tree.GetEncodedValueWithInclusionOrExclusionProofFromRootHash(NewLoggerContextTodoForTesting(t), nil, rootHash1, test.extraKey)
   683  			require.NoError(t, err)
   684  			require.Nil(t, eVal)
   685  			require.NoError(t, verifier.VerifyExclusionProof(NewLoggerContextTodoForTesting(t), test.extraKey, &proof, rootHash1))
   686  		})
   687  	}
   688  }
   689  
   690  func TestVerifyInclusionProofFailureBranches(t *testing.T) {
   691  
   692  	cfg, err := NewConfig(IdentityHasherBlinded{}, true, 2, 4, 2, ConstructStringValueContainer)
   693  	require.NoError(t, err)
   694  	defaultStep := 2
   695  
   696  	kvps := []KeyValuePair{
   697  		{Key: []byte{0x00, 0x00}, Value: "key0x0000Seqno1"},
   698  		{Key: []byte{0x00, 0x01}, Value: "key0x0001Seqno1"},
   699  		{Key: []byte{0x00, 0x02}, Value: "key0x0002Seqno1"},
   700  		{Key: []byte{0x01, 0x10}, Value: "key0x0100Seqno1"},
   701  		{Key: []byte{0x01, 0x11}, Value: "key0x0111Seqno1"},
   702  		{Key: []byte{0x01, 0x12}, Value: "key0x0112Seqno1"},
   703  	}
   704  
   705  	tree, err := NewTree(cfg, defaultStep, NewInMemoryStorageEngine(cfg), RootVersionV1)
   706  	require.NoError(t, err)
   707  	verifier := NewMerkleProofVerifier(cfg)
   708  
   709  	s1, rootHash1, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvps, nil)
   710  	require.NoError(t, err)
   711  	require.EqualValues(t, 1, s1)
   712  
   713  	// First, sanity check that honest proofs pass
   714  	kvp := kvps[1]
   715  	kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   716  	require.NoError(t, err)
   717  	require.Equal(t, kvp.Value, kvpRet.Value)
   718  	require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHash1))
   719  
   720  	// nil proof
   721  	err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, nil, rootHash1)
   722  	require.Error(t, err)
   723  	require.Contains(t, err.Error(), "nil proof")
   724  
   725  	// Wrong key length
   726  	fakeKvp := kvp
   727  	fakeKvp.Key = []byte{0x00}
   728  	err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), fakeKvp, &proof, rootHash1)
   729  	require.Error(t, err)
   730  	require.IsType(t, ProofVerificationFailedError{}, err)
   731  	require.Contains(t, err.Error(), "Key has wrong length")
   732  
   733  	// Proof has too many key hash pairs
   734  	fakeProof := proof
   735  	fakeProof.OtherPairsInLeaf = make([]KeyHashPair, cfg.MaxValuesPerLeaf)
   736  	err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeProof, rootHash1)
   737  	require.Error(t, err)
   738  	require.IsType(t, ProofVerificationFailedError{}, err)
   739  	require.Contains(t, err.Error(), "Too many keys in leaf")
   740  
   741  	// switch order in other pairs
   742  	fakeProof = proof
   743  	fakeProof.OtherPairsInLeaf = make([]KeyHashPair, len(proof.OtherPairsInLeaf))
   744  	copy(fakeProof.OtherPairsInLeaf, proof.OtherPairsInLeaf)
   745  	fakeProof.OtherPairsInLeaf[0], fakeProof.OtherPairsInLeaf[1] = fakeProof.OtherPairsInLeaf[1], fakeProof.OtherPairsInLeaf[0]
   746  	err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeProof, rootHash1)
   747  	require.Error(t, err)
   748  	require.IsType(t, ProofVerificationFailedError{}, err)
   749  	require.Contains(t, err.Error(), "Error in Leaf Key ordering or duplicated key")
   750  
   751  	// wrong number of siblings
   752  	fakeProof = proof
   753  	fakeProof.SiblingHashesOnPath = fakeProof.SiblingHashesOnPath[1:]
   754  	err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeProof, rootHash1)
   755  	require.Error(t, err)
   756  	require.IsType(t, ProofVerificationFailedError{}, err)
   757  	require.Contains(t, err.Error(), "Invalid number of SiblingHashes")
   758  
   759  	// Change the root hash
   760  	rootHashFake := Hash(append([]byte(nil), ([]byte(rootHash1))...))
   761  	([]byte(rootHashFake))[0] = 1 + ([]byte(rootHashFake))[0]
   762  	err = verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHashFake)
   763  	require.Error(t, err)
   764  	require.IsType(t, ProofVerificationFailedError{}, err)
   765  	require.Contains(t, err.Error(), "expected rootHash does not match the computed one")
   766  }
   767  
   768  func TestTreeWithoutInternalNodes(t *testing.T) {
   769  
   770  	tests := []struct {
   771  		step int
   772  	}{
   773  		{1},
   774  		{2},
   775  		{3},
   776  		{30},
   777  	}
   778  
   779  	for _, test := range tests {
   780  		t.Run(fmt.Sprintf("Empy tree with %v step", test.step), func(t *testing.T) {
   781  
   782  			cfg, err := NewConfig(IdentityHasherBlinded{}, true, 2, 4, 2, ConstructStringValueContainer)
   783  			require.NoError(t, err)
   784  			tree, err := NewTree(cfg, test.step, NewInMemoryStorageEngine(cfg), RootVersionV1)
   785  			require.NoError(t, err)
   786  			verifier := NewMerkleProofVerifier(cfg)
   787  
   788  			kvps1 := []KeyValuePair{
   789  				{Key: []byte{0x00, 0x00}, Value: "key0x0000Seqno1"},
   790  			}
   791  
   792  			s1, rootHash1, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvps1, nil)
   793  			require.NoError(t, err)
   794  			require.EqualValues(t, 1, s1)
   795  
   796  			kvp := kvps1[0]
   797  			kvpRet, proof, err := tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 1, kvp.Key)
   798  			require.NoError(t, err)
   799  			require.True(t, kvp.Key.Equal(kvpRet.Key))
   800  			require.Equal(t, kvp.Value, kvpRet.Value)
   801  			require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHash1))
   802  
   803  			kvps2 := []KeyValuePair{
   804  				{Key: []byte{0x00, 0x00}, Value: "key0x0000Seqno2"},
   805  				{Key: []byte{0x00, 0x01}, Value: "key0x0001Seqno2"},
   806  				{Key: []byte{0x00, 0x02}, Value: "key0x0002Seqno2"},
   807  			}
   808  
   809  			s2, rootHash2, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvps2, nil)
   810  			require.NoError(t, err)
   811  			require.EqualValues(t, 2, s2)
   812  
   813  			kvp = kvps2[1]
   814  			kvpRet, proof, err = tree.GetKeyValuePairWithProof(NewLoggerContextTodoForTesting(t), nil, 2, kvp.Key)
   815  			require.NoError(t, err)
   816  			require.True(t, kvp.Key.Equal(kvpRet.Key))
   817  			require.Equal(t, kvp.Value, kvpRet.Value)
   818  			require.NoError(t, verifier.VerifyInclusionProof(NewLoggerContextTodoForTesting(t), kvp, &proof, rootHash2))
   819  		})
   820  	}
   821  }
   822  
   823  func TestGetLatestRoot(t *testing.T) {
   824  	config1bitU, config2bitsU, config3bitsU := getTreeCfgsWith1_2_3BitsPerIndexUnblinded(t)
   825  	config1bitB, config2bitsB, config3bitsB := getTreeCfgsWith1_2_3BitsPerIndexBlinded(t)
   826  	defaultStep := 2
   827  	kvps1_1bit, kvps2_1bit, _ := getSampleKVPS1bit()
   828  	kvps1_3bits, kvps2_3bits, _ := getSampleKVPS3bits()
   829  
   830  	config3bits2valsPerLeafU, err := NewConfig(IdentityHasher{}, false, 3, 2, 3, ConstructStringValueContainer)
   831  	require.NoError(t, err)
   832  	config3bits2valsPerLeafB, err := NewConfig(IdentityHasherBlinded{}, true, 3, 2, 3, ConstructStringValueContainer)
   833  	require.NoError(t, err)
   834  
   835  	tests := []struct {
   836  		cfg   Config
   837  		kvps1 []KeyValuePair
   838  		kvps2 []KeyValuePair
   839  	}{
   840  		{config1bitU, kvps1_1bit, kvps2_1bit},
   841  		{config2bitsU, kvps1_1bit, kvps2_1bit},
   842  		{config3bitsU, kvps1_3bits, kvps2_3bits},
   843  		{config3bits2valsPerLeafU, kvps1_3bits, kvps2_3bits},
   844  		{config1bitB, kvps1_1bit, kvps2_1bit},
   845  		{config2bitsB, kvps1_1bit, kvps2_1bit},
   846  		{config3bitsB, kvps1_3bits, kvps2_3bits},
   847  		{config3bits2valsPerLeafB, kvps1_3bits, kvps2_3bits},
   848  	}
   849  
   850  	for _, test := range tests {
   851  		t.Run(fmt.Sprintf("%v bits %v values per leaf tree (blinded %v)", test.cfg.BitsPerIndex, test.cfg.MaxValuesPerLeaf, test.cfg.UseBlindedValueHashes), func(t *testing.T) {
   852  			tree, err := NewTree(test.cfg, defaultStep, NewInMemoryStorageEngine(test.cfg), RootVersionV1)
   853  			require.NoError(t, err)
   854  
   855  			s1, rootHash1Exp, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps1, nil)
   856  			require.NoError(t, err)
   857  			require.EqualValues(t, 1, s1)
   858  
   859  			_, _, rootHash1, err := tree.GetLatestRoot(NewLoggerContextTodoForTesting(t), nil)
   860  			require.NoError(t, err)
   861  			require.True(t, rootHash1Exp.Equal(rootHash1))
   862  
   863  			s2, rootHash2Exp, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, test.kvps2, nil)
   864  			require.NoError(t, err)
   865  			require.EqualValues(t, 2, s2)
   866  
   867  			_, _, rootHash2, err := tree.GetLatestRoot(NewLoggerContextTodoForTesting(t), nil)
   868  			require.NoError(t, err)
   869  			require.True(t, rootHash2Exp.Equal(rootHash2))
   870  
   871  			require.False(t, rootHash1.Equal(rootHash2))
   872  		})
   873  	}
   874  
   875  }
   876  
   877  func TestNodeEncodingBasic(t *testing.T) {
   878  	n := Node{}
   879  	enc, err := msgpack.EncodeCanonical(&n)
   880  	require.NoError(t, err)
   881  
   882  	var den Node
   883  	err = msgpack.Decode(&den, enc)
   884  	require.NoError(t, err)
   885  	require.Equal(t, n, den)
   886  	require.NotEqual(t, Node{LeafHashes: []KeyHashPair{}}, den)
   887  
   888  	n.INodes = make([]Hash, 2)
   889  	_, err = msgpack.EncodeCanonical(&n)
   890  	require.NoError(t, err)
   891  
   892  	n.LeafHashes = make([]KeyHashPair, 2)
   893  	_, err = msgpack.EncodeCanonical(&n)
   894  	require.Error(t, err)
   895  	require.Contains(t, err.Error(), "msgpack encode error")
   896  
   897  	n = Node{INodes: []Hash{Hash([]byte{0x01, 0x02}), Hash([]byte{0x03, 0x04})}}
   898  	enc, err = msgpack.EncodeCanonical(&n)
   899  	require.NoError(t, err)
   900  
   901  	t.Logf("enc : %X", enc)
   902  
   903  	var dn Node
   904  	err = msgpack.Decode(&dn, enc)
   905  	require.NoError(t, err)
   906  	require.Equal(t, n, dn)
   907  
   908  	n2 := Node{LeafHashes: []KeyHashPair{{Key: Key([]byte{0x01, 0x02}), Hash: Hash([]byte{0x03, 0x03})}}}
   909  	enc, err = msgpack.EncodeCanonical(&n2)
   910  	require.NoError(t, err)
   911  
   912  	var dn2 Node
   913  	err = msgpack.Decode(&dn2, enc)
   914  	require.NoError(t, err)
   915  	require.Equal(t, n2, dn2)
   916  	require.NotEqual(t, dn, dn2)
   917  }
   918  
   919  func TestInclusionExtensionProofsPass(t *testing.T) {
   920  	cfg, err := NewConfig(SHA512_256Encoder{}, false, 1, 1, 3, ConstructStringValueContainer)
   921  	require.NoError(t, err)
   922  
   923  	// make test deterministic
   924  	rand.Seed(1)
   925  
   926  	tree, err := NewTree(cfg, 2, NewInMemoryStorageEngine(cfg), RootVersionV1)
   927  	require.NoError(t, err)
   928  
   929  	keys, _, err := makeRandomKeysForTesting(uint(cfg.KeysByteLength), 5, 0)
   930  	require.NoError(t, err)
   931  
   932  	rootHashes := make(map[Seqno]Hash)
   933  
   934  	maxSeqno := Seqno(100)
   935  	// build a bunch of tree versions:
   936  	for j := Seqno(1); j < maxSeqno; j++ {
   937  		kvps, err := makeRandomKVPFromKeysForTesting(keys)
   938  		addOnsHash := Hash(nil)
   939  		// put a random AddOnsHash in half of the tree roots
   940  		if rand.Intn(2) == 1 {
   941  			buf := make([]byte, 32)
   942  			rand.Read(buf)
   943  			addOnsHash = Hash(buf)
   944  		}
   945  		require.NoError(t, err)
   946  		_, hash, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvps, addOnsHash)
   947  		rootHashes[j] = hash
   948  		require.NoError(t, err)
   949  	}
   950  
   951  	verifier := NewMerkleProofVerifier(cfg)
   952  
   953  	numTests := 50
   954  	for j := 0; j < numTests; j++ {
   955  		startSeqno := Seqno(rand.Intn(int(maxSeqno)-1) + 1)
   956  		endSeqno := Seqno(rand.Intn(int(maxSeqno)-1) + 1)
   957  		if startSeqno > endSeqno {
   958  			startSeqno, endSeqno = endSeqno, startSeqno
   959  		}
   960  
   961  		eProof, err := tree.GetExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno)
   962  		require.NoError(t, err)
   963  
   964  		err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
   965  		require.NoError(t, err)
   966  
   967  		k := keys[rand.Intn(len(keys))]
   968  
   969  		kvp, ieProof, err := tree.GetKeyValuePairWithInclusionExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno, k)
   970  		require.NoError(t, err)
   971  		require.Equal(t, k, kvp.Key)
   972  
   973  		err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
   974  		require.NoError(t, err)
   975  	}
   976  
   977  	// Test the special cases start == end and start == end - 1
   978  	startSeqno := Seqno(rand.Intn(int(maxSeqno)-1) + 1)
   979  	endSeqno := startSeqno
   980  
   981  	eProof, err := tree.GetExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno)
   982  	require.NoError(t, err)
   983  
   984  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
   985  	require.NoError(t, err)
   986  
   987  	k := keys[rand.Intn(len(keys))]
   988  
   989  	kvp, ieProof, err := tree.GetKeyValuePairWithInclusionExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno, k)
   990  	require.NoError(t, err)
   991  	require.Equal(t, k, kvp.Key)
   992  
   993  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
   994  	require.NoError(t, err)
   995  
   996  	endSeqno = startSeqno + 1
   997  
   998  	eProof, err = tree.GetExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno)
   999  	require.NoError(t, err)
  1000  
  1001  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1002  	require.NoError(t, err)
  1003  
  1004  	kvp, ieProof, err = tree.GetKeyValuePairWithInclusionExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno, k)
  1005  	require.NoError(t, err)
  1006  	require.Equal(t, k, kvp.Key)
  1007  
  1008  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1009  	require.NoError(t, err)
  1010  }
  1011  
  1012  func TestExtensionProofsFailureBranches(t *testing.T) {
  1013  	cfg, err := NewConfig(SHA512_256Encoder{}, false, 1, 1, 3, ConstructStringValueContainer)
  1014  	require.NoError(t, err)
  1015  
  1016  	// make test deterministic
  1017  	rand.Seed(1)
  1018  
  1019  	tree, err := NewTree(cfg, 2, NewInMemoryStorageEngine(cfg), RootVersionV1)
  1020  	require.NoError(t, err)
  1021  
  1022  	keys, _, err := makeRandomKeysForTesting(uint(cfg.KeysByteLength), 5, 0)
  1023  	require.NoError(t, err)
  1024  
  1025  	rootHashes := make(map[Seqno]Hash)
  1026  
  1027  	maxSeqno := Seqno(100)
  1028  	// build a bunch of tree versions:
  1029  	for j := Seqno(1); j < maxSeqno; j++ {
  1030  		kvps, err := makeRandomKVPFromKeysForTesting(keys)
  1031  		require.NoError(t, err)
  1032  		_, hash, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvps, nil)
  1033  		rootHashes[j] = hash
  1034  		require.NoError(t, err)
  1035  	}
  1036  
  1037  	verifier := NewMerkleProofVerifier(cfg)
  1038  
  1039  	startSeqno := Seqno(20)
  1040  	endSeqno := Seqno(39)
  1041  
  1042  	// real proof verifies successfully
  1043  	eProof, err := tree.GetExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno)
  1044  	require.NoError(t, err)
  1045  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1046  	require.NoError(t, err)
  1047  
  1048  	// nil proof
  1049  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1050  	require.Error(t, err)
  1051  	require.Contains(t, err.Error(), "nil proof")
  1052  
  1053  	// "good proofs" verified wrt the wrong parameters should fail
  1054  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, endSeqno, rootHashes[startSeqno], startSeqno, rootHashes[endSeqno])
  1055  	require.Error(t, err)
  1056  	require.Contains(t, err.Error(), "start > end")
  1057  
  1058  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno+1, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1059  	require.Error(t, err)
  1060  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1061  
  1062  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno+1, rootHashes[startSeqno], endSeqno+1, rootHashes[endSeqno])
  1063  	require.Error(t, err)
  1064  	require.Contains(t, err.Error(), "The proof does not have the expected number of root hashes")
  1065  
  1066  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno+1, rootHashes[startSeqno+1], endSeqno, rootHashes[endSeqno])
  1067  	require.Error(t, err)
  1068  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1069  
  1070  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &eProof, startSeqno+1, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno+1])
  1071  	require.Error(t, err)
  1072  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1073  
  1074  	// no previous roots
  1075  	fakeEProof := eProof
  1076  	fakeEProof.PreviousRootsNoSkips = nil
  1077  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &fakeEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1078  	require.Error(t, err)
  1079  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1080  
  1081  	// no root hashes
  1082  	fakeEProof = eProof
  1083  	fakeEProof.RootHashes = nil
  1084  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &fakeEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1085  	require.Error(t, err)
  1086  	require.Contains(t, err.Error(), "The proof does not have the expected number of root hashes")
  1087  
  1088  	// a root hash has been tampered with
  1089  	fakeEProof = eProof
  1090  	fakeEProof.RootHashes = make([]Hash, len(eProof.RootHashes))
  1091  	copy(fakeEProof.RootHashes, eProof.RootHashes)
  1092  	fakeHashB := sha256.Sum256([]byte("tampered hash!"))
  1093  	fakeHash := Hash(fakeHashB[:])
  1094  	fakeEProof.RootHashes[1] = fakeHash
  1095  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &fakeEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1096  	require.Error(t, err)
  1097  	require.Contains(t, err.Error(), "verifyExtensionProofFinal: hash mismatch")
  1098  
  1099  	// no PreviousRootsNoSkips
  1100  	fakeEProof = eProof
  1101  	fakeEProof.PreviousRootsNoSkips = nil
  1102  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &fakeEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1103  	require.Error(t, err)
  1104  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1105  
  1106  	// a root metadata has been tampered with
  1107  	fakeEProof = eProof
  1108  	fakeEProof.PreviousRootsNoSkips = make([]RootMetadata, len(eProof.PreviousRootsNoSkips))
  1109  	copy(fakeEProof.PreviousRootsNoSkips, eProof.PreviousRootsNoSkips)
  1110  	fakeRoot := RootMetadata{RootVersion: RootVersionV1, Seqno: Seqno(257), SkipPointersHash: fakeHash}
  1111  	fakeEProof.PreviousRootsNoSkips[1] = fakeRoot
  1112  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), &fakeEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1113  	require.Error(t, err)
  1114  	require.Contains(t, err.Error(), "verifyExtensionProofFinal: hash mismatch")
  1115  
  1116  	// failure when the proof is not necessary
  1117  	startSeqno = Seqno(20)
  1118  	endSeqno = startSeqno
  1119  
  1120  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1121  	require.NoError(t, err)
  1122  
  1123  	err = verifier.VerifyExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, rootHashes[startSeqno], endSeqno, fakeHash)
  1124  	require.Error(t, err)
  1125  	require.Contains(t, err.Error(), "Hash mismatch: initialSeqno == finalSeqno")
  1126  }
  1127  
  1128  func TestInclusionExtensionProofsFailureBranches(t *testing.T) {
  1129  	cfg, err := NewConfig(SHA512_256Encoder{}, false, 1, 1, 3, ConstructStringValueContainer)
  1130  	require.NoError(t, err)
  1131  
  1132  	// make test deterministic
  1133  	rand.Seed(1)
  1134  
  1135  	tree, err := NewTree(cfg, 2, NewInMemoryStorageEngine(cfg), RootVersionV1)
  1136  	require.NoError(t, err)
  1137  
  1138  	keys, _, err := makeRandomKeysForTesting(uint(cfg.KeysByteLength), 5, 0)
  1139  	require.NoError(t, err)
  1140  
  1141  	rootHashes := make(map[Seqno]Hash)
  1142  
  1143  	maxSeqno := Seqno(100)
  1144  	// build a bunch of tree versions:
  1145  	for j := Seqno(1); j < maxSeqno; j++ {
  1146  		kvps, err := makeRandomKVPFromKeysForTesting(keys)
  1147  		require.NoError(t, err)
  1148  		_, hash, err := tree.Build(NewLoggerContextTodoForTesting(t), nil, kvps, nil)
  1149  		rootHashes[j] = hash
  1150  		require.NoError(t, err)
  1151  	}
  1152  
  1153  	verifier := NewMerkleProofVerifier(cfg)
  1154  
  1155  	startSeqno := Seqno(20)
  1156  	endSeqno := Seqno(39)
  1157  
  1158  	k := keys[rand.Intn(len(keys))]
  1159  
  1160  	// real proof verifies successfully
  1161  	kvp, ieProof, err := tree.GetKeyValuePairWithInclusionExtensionProof(NewLoggerContextTodoForTesting(t), nil, startSeqno, endSeqno, k)
  1162  	require.NoError(t, err)
  1163  	require.Equal(t, k, kvp.Key)
  1164  
  1165  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1166  	require.NoError(t, err)
  1167  
  1168  	// nil proof
  1169  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, nil, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1170  	require.Error(t, err)
  1171  	require.Contains(t, err.Error(), "nil proof")
  1172  
  1173  	// "good proofs" verified wrt the wrong parameters should fail
  1174  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, endSeqno, rootHashes[startSeqno], startSeqno, rootHashes[endSeqno])
  1175  	require.Error(t, err)
  1176  	require.Contains(t, err.Error(), "start > end")
  1177  
  1178  	fakeKvp := KeyValuePair{Key: kvp.Key, Value: EncodedValue([]byte("fake value"))}
  1179  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), fakeKvp, &ieProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1180  	require.Error(t, err)
  1181  	require.Contains(t, err.Error(), "expected rootHash does not match the computed one")
  1182  
  1183  	fakeKvp = KeyValuePair{Key: Key([]byte{0x00, 0x01, 0x02}), Value: kvp.Value}
  1184  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), fakeKvp, &ieProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1185  	require.Error(t, err)
  1186  	require.Contains(t, err.Error(), "expected rootHash does not match the computed one")
  1187  
  1188  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno+1, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1189  	require.Error(t, err)
  1190  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1191  
  1192  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno+1, rootHashes[startSeqno], endSeqno+1, rootHashes[endSeqno])
  1193  	require.Error(t, err)
  1194  	require.Contains(t, err.Error(), "The proof does not have the expected number of root hashes")
  1195  
  1196  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno+1, rootHashes[startSeqno+1], endSeqno, rootHashes[endSeqno])
  1197  	require.Error(t, err)
  1198  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1199  
  1200  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &ieProof, startSeqno+1, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno+1])
  1201  	require.Error(t, err)
  1202  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1203  
  1204  	// no previous roots
  1205  	fakeIEProof := ieProof
  1206  	fakeIEProof.MerkleExtensionProof.PreviousRootsNoSkips = nil
  1207  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeIEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1208  	require.Error(t, err)
  1209  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1210  
  1211  	// no root hashes
  1212  	fakeIEProof = ieProof
  1213  	fakeIEProof.MerkleExtensionProof.RootHashes = nil
  1214  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeIEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1215  	require.Error(t, err)
  1216  	require.Contains(t, err.Error(), "The proof does not have the expected number of root hashes")
  1217  
  1218  	// a root hash has been tampered with
  1219  	fakeIEProof = ieProof
  1220  	fakeIEProof.MerkleExtensionProof.RootHashes = make([]Hash, len(ieProof.MerkleExtensionProof.RootHashes))
  1221  	copy(fakeIEProof.MerkleExtensionProof.RootHashes, ieProof.MerkleExtensionProof.RootHashes)
  1222  	fakeHashB := sha256.Sum256([]byte("tampered hash!"))
  1223  	fakeHash := Hash(fakeHashB[:])
  1224  	fakeIEProof.MerkleExtensionProof.RootHashes[1] = fakeHash
  1225  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeIEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1226  	require.Error(t, err)
  1227  	require.Contains(t, err.Error(), "expected rootHash does not match the computed one")
  1228  
  1229  	// no PreviousRootsNoSkips
  1230  	fakeIEProof = ieProof
  1231  	fakeIEProof.MerkleExtensionProof.PreviousRootsNoSkips = nil
  1232  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeIEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1233  	require.Error(t, err)
  1234  	require.Contains(t, err.Error(), "The proof does not have the expected number of roots")
  1235  
  1236  	// a root metadata has been tampered with
  1237  	fakeIEProof = ieProof
  1238  	fakeIEProof.MerkleExtensionProof.PreviousRootsNoSkips = make([]RootMetadata, len(ieProof.MerkleExtensionProof.PreviousRootsNoSkips))
  1239  	copy(fakeIEProof.MerkleExtensionProof.PreviousRootsNoSkips, ieProof.MerkleExtensionProof.PreviousRootsNoSkips)
  1240  	fakeRoot := RootMetadata{RootVersion: RootVersionV1, Seqno: Seqno(257), SkipPointersHash: fakeHash}
  1241  	fakeIEProof.MerkleExtensionProof.PreviousRootsNoSkips[1] = fakeRoot
  1242  	err = verifier.VerifyInclusionExtensionProof(NewLoggerContextTodoForTesting(t), kvp, &fakeIEProof, startSeqno, rootHashes[startSeqno], endSeqno, rootHashes[endSeqno])
  1243  	require.Error(t, err)
  1244  	require.Contains(t, err.Error(), "expected rootHash does not match the computed one")
  1245  
  1246  }
  1247  
  1248  func NewLoggerContextTodoForTesting(t *testing.T) logger.ContextInterface {
  1249  	return logger.NewContext(context.TODO(), logger.NewTestLogger(t))
  1250  }