1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/content_hash_tree.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util.h"
9 #include "crypto/secure_hash.h"
10 #include "crypto/sha2.h"
12 namespace extensions
{
14 std::string
ComputeTreeHashRoot(const std::vector
<std::string
>& leaf_hashes
,
16 if (leaf_hashes
.empty() || branch_factor
< 2)
19 // The nodes of the tree we're currently operating on.
20 std::vector
<std::string
> current_nodes
;
22 // We avoid having to copy all of the input leaf nodes into |current_nodes|
23 // by using a pointer. So the first iteration of the loop this points at
24 // |leaf_hashes|, but thereafter it points at |current_nodes|.
25 const std::vector
<std::string
>* current
= &leaf_hashes
;
27 // Where we're inserting new hashes computed from the current level.
28 std::vector
<std::string
> parent_nodes
;
30 while (current
->size() > 1) {
31 // Iterate over the current level of hashes, computing the hash of up to
32 // |branch_factor| elements to form the hash of each parent node.
33 std::vector
<std::string
>::const_iterator i
= current
->begin();
34 while (i
!= current
->end()) {
35 scoped_ptr
<crypto::SecureHash
> hash(
36 crypto::SecureHash::Create(crypto::SecureHash::SHA256
));
37 for (int j
= 0; j
< branch_factor
&& i
!= current
->end(); j
++) {
38 DCHECK_EQ(i
->size(), crypto::kSHA256Length
);
39 hash
->Update(i
->data(), i
->size());
42 parent_nodes
.push_back(std::string(crypto::kSHA256Length
, 0));
43 std::string
* output
= &(parent_nodes
.back());
44 hash
->Finish(string_as_array(output
), output
->size());
46 current_nodes
.swap(parent_nodes
);
48 current
= ¤t_nodes
;
50 DCHECK_EQ(1u, current
->size());
54 } // namespace extensions