#include "extensions/browser/content_hash_tree.h"
#include <memory>
#include "base/check_op.h"
#include "base/strings/string_view_util.h"
#include "crypto/hash.h"
namespace extensions {
std::string ComputeTreeHashRoot(const std::vector<std::string>& leaf_hashes,
int branch_factor) {
if (leaf_hashes.empty() || branch_factor < 2) {
return std::string();
}
std::vector<std::string> current_nodes;
const std::vector<std::string>* current = &leaf_hashes;
std::vector<std::string> parent_nodes;
while (current->size() > 1) {
auto i = current->cbegin();
while (i != current->cend()) {
crypto::hash::Hasher hash(crypto::hash::kSha256);
for (int j = 0; j < branch_factor && i != current->end(); j++) {
DCHECK_EQ(i->size(), crypto::hash::kSha256Size);
hash.Update(*i);
++i;
}
std::string digest(crypto::hash::kSha256Size, '\0');
hash.Finish(base::as_writable_byte_span(digest));
parent_nodes.push_back(digest);
}
current_nodes.swap(parent_nodes);
parent_nodes.clear();
current = ¤t_nodes;
}
DCHECK_EQ(1u, current->size());
return (*current)[0];
}
}