Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert/ct_log_verifier.h" | 5 #include "net/cert/ct_log_verifier.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <map> | |
| 9 #include <memory> | 10 #include <memory> |
| 10 #include <string> | 11 #include <string> |
| 12 #include <utility> | |
| 11 | 13 |
| 12 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 14 #include "crypto/secure_hash.h" | 16 #include "crypto/secure_hash.h" |
| 15 #include "net/base/hash_value.h" | 17 #include "net/base/hash_value.h" |
| 16 #include "net/cert/ct_log_verifier_util.h" | 18 #include "net/cert/ct_log_verifier_util.h" |
| 17 #include "net/cert/merkle_consistency_proof.h" | 19 #include "net/cert/merkle_consistency_proof.h" |
| 18 #include "net/cert/signed_certificate_timestamp.h" | 20 #include "net/cert/signed_certificate_timestamp.h" |
| 19 #include "net/cert/signed_tree_head.h" | 21 #include "net/cert/signed_tree_head.h" |
| 20 #include "net/test/ct_test_util.h" | 22 #include "net/test/ct_test_util.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 24 |
| 23 namespace net { | 25 namespace net { |
| 24 | 26 |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 29 // Enables the node hash cache used to accelerate some of the tests. | |
| 30 // The cache reduces the duration of some tests by at least 50%, in exchange for | |
| 31 // significantly higher memory usage. | |
|
Eran Messeri
2016/07/26 15:45:37
Can you say how much or point to a calculation lat
| |
| 32 const bool kIsHashCacheEnabled = true; | |
| 33 | |
| 27 // Calculate the power of two nearest to, but less than, |n|. | 34 // Calculate the power of two nearest to, but less than, |n|. |
| 28 // |n| must be at least 2. | 35 // |n| must be at least 2. |
| 29 uint64_t CalculateNearestPowerOfTwo(uint64_t n) { | 36 uint64_t CalculateNearestPowerOfTwo(uint64_t n) { |
| 30 DCHECK_GT(n, 1u); | 37 DCHECK_GT(n, 1u); |
| 31 | 38 |
| 32 uint64_t ret = UINT64_C(1) << 63; | 39 uint64_t ret = UINT64_C(1) << 63; |
| 33 while (ret >= n) | 40 while (ret >= n) |
| 34 ret >>= 1; | 41 ret >>= 1; |
| 35 | 42 |
| 36 return ret; | 43 return ret; |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 | 426 |
| 420 return std::string(reinterpret_cast<const char*>(sha256.data), | 427 return std::string(reinterpret_cast<const char*>(sha256.data), |
| 421 sizeof(sha256.data)); | 428 sizeof(sha256.data)); |
| 422 } | 429 } |
| 423 }; | 430 }; |
| 424 | 431 |
| 425 // Reference implementation of Merkle hash, for cross-checking. | 432 // Reference implementation of Merkle hash, for cross-checking. |
| 426 // Recursively calculates the hash of the root given the leaf data | 433 // Recursively calculates the hash of the root given the leaf data |
| 427 // specified in |inputs|. | 434 // specified in |inputs|. |
| 428 std::string ReferenceMerkleTreeHash(std::string* inputs, uint64_t input_size) { | 435 std::string ReferenceMerkleTreeHash(std::string* inputs, uint64_t input_size) { |
| 429 if (!input_size) | 436 // Memoize function - this requires 34 bytes of memory per unique pair of |
| 430 return TreeHasher::HashEmpty(); | 437 // |inputs| and |input_size|, plus std::map and std::string overhead. |
| 431 if (input_size == 1) | 438 // This results in a ~50% reduction in time required to run the |
| 432 return TreeHasher::HashLeaf(inputs[0]); | 439 // *FromReferenceGenerator tests. |
| 440 static std::map<std::pair<std::string*, uint64_t>, std::string> cache; | |
|
Eran Messeri
2016/07/26 15:45:37
As discussed offline, there are two issues with us
| |
| 441 if (kIsHashCacheEnabled) { | |
| 442 auto iter = cache.find(std::make_pair(inputs, input_size)); | |
| 443 if (iter != cache.end()) | |
| 444 return iter->second; | |
| 445 } | |
| 433 | 446 |
| 434 const uint64_t split = CalculateNearestPowerOfTwo(input_size); | 447 std::string hash; |
| 448 if (input_size == 0) { | |
| 449 hash = TreeHasher::HashEmpty(); | |
| 450 } else if (input_size == 1) { | |
| 451 hash = TreeHasher::HashLeaf(inputs[0]); | |
| 452 } else { | |
| 453 const uint64_t split = CalculateNearestPowerOfTwo(input_size); | |
| 435 | 454 |
| 436 return ct::internal::HashNodes( | 455 hash = ct::internal::HashNodes( |
| 437 ReferenceMerkleTreeHash(&inputs[0], split), | 456 ReferenceMerkleTreeHash(&inputs[0], split), |
| 438 ReferenceMerkleTreeHash(&inputs[split], input_size - split)); | 457 ReferenceMerkleTreeHash(&inputs[split], input_size - split)); |
| 458 } | |
| 459 | |
| 460 if (kIsHashCacheEnabled) | |
| 461 cache[std::make_pair(inputs, input_size)] = hash; | |
| 462 | |
| 463 return hash; | |
| 439 } | 464 } |
| 440 | 465 |
| 441 // Reference implementation of snapshot consistency. Returns a | 466 // Reference implementation of snapshot consistency. Returns a |
| 442 // consistency proof between two snapshots of the tree designated | 467 // consistency proof between two snapshots of the tree designated |
| 443 // by |inputs|. | 468 // by |inputs|. |
| 444 // Call with have_root1 = true. | 469 // Call with have_root1 = true. |
| 445 std::vector<std::string> ReferenceSnapshotConsistency(std::string* inputs, | 470 std::vector<std::string> ReferenceSnapshotConsistency(std::string* inputs, |
| 446 uint64_t snapshot2, | 471 uint64_t snapshot2, |
| 447 uint64_t snapshot1, | 472 uint64_t snapshot1, |
| 448 bool have_root1) { | 473 bool have_root1) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 ReferenceSnapshotConsistency(data.data(), tree_size, snapshot, true); | 535 ReferenceSnapshotConsistency(data.data(), tree_size, snapshot, true); |
| 511 root1 = ReferenceMerkleTreeHash(data.data(), snapshot); | 536 root1 = ReferenceMerkleTreeHash(data.data(), snapshot); |
| 512 VerifierConsistencyCheck(snapshot, tree_size, root1, root2, proof); | 537 VerifierConsistencyCheck(snapshot, tree_size, root1, root2, proof); |
| 513 } | 538 } |
| 514 } | 539 } |
| 515 } | 540 } |
| 516 | 541 |
| 517 } // namespace | 542 } // namespace |
| 518 | 543 |
| 519 } // namespace net | 544 } // namespace net |
| OLD | NEW |