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 |