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 }