// Copyright 2025 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "merkle_tree.h"

#include <cassert>
#include <cstdint>
#include <limits>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

BSSL_NAMESPACE_BEGIN

namespace {

// Returns a subtree consistency proof for `subtree` in the first `n` elements
// of `tree`. This is currently implemented recursively, matching the
// specification. If we ever need to expose it, we can implement it more
// efficiently.
std::vector<uint8_t> SubtreeConsistencyProof(const MerkleTree &mt,
                                             Subtree subtree,
                                             const Subtree &tree,
                                             bool known_hash = true) {
  BSSL_CHECK(subtree.IsValid());
  BSSL_CHECK(tree.IsValid());
  BSSL_CHECK(tree.Contains(subtree));

  if (subtree == tree) {
    if (known_hash) {
      return {};
    }
    TreeHash h = mt.SubtreeHash(subtree);
    return std::vector(h.begin(), h.end());
  }

  uint64_t k = tree.Split();
  Subtree subproof_tree, mth_tree;
  if (subtree.end <= k) {
    subproof_tree = tree.Left();
    mth_tree = tree.Right();
  } else if (subtree.start >= k) {
    mth_tree = tree.Left();
    subproof_tree = tree.Right();
  } else {
    subtree.start = k;
    mth_tree = tree.Left();
    subproof_tree = tree.Right();
    known_hash = false;
  }
  std::vector<uint8_t> subproof =
      SubtreeConsistencyProof(mt, subtree, subproof_tree, known_hash);
  TreeHash mth = mt.SubtreeHash(mth_tree);
  subproof.insert(subproof.end(), mth.begin(), mth.end());
  return subproof;
}

std::vector<std::vector<uint8_t>> MakeTestEntries(std::string_view label,
                                                  size_t n) {
  std::vector<std::vector<uint8_t>> entries;
  entries.reserve(n);
  for (size_t i = 0; i < n; i++) {
    std::vector<uint8_t> entry(label.begin(), label.end());
    for (size_t j = 0; j < 8; j++) {
      entry.push_back(static_cast<uint8_t>(i >> (j * 8)));
    }
    entries.push_back(std::move(entry));
  }
  return entries;
}

std::vector<uint8_t> ConcatProof(const std::vector<TreeHash> &proof) {
  std::vector<uint8_t> out;
  for (const auto &p : proof) {
    out.insert(out.end(), p.begin(), p.end());
  }
  return out;
}

TEST(MerkleTreeTest, SubtreeIsValid) {
  // An empty subtree is invalid.
  EXPECT_FALSE((Subtree{0, 0}.IsValid()));
  // But if the end is before start, it's invalid.
  EXPECT_FALSE((Subtree{1, 0}.IsValid()));
  // A subtree of the maximum expressible size is valid.
  EXPECT_TRUE((Subtree{0, std::numeric_limits<uint64_t>::max()}.IsValid()));

  // Subtrees don't have to start at 0.
  EXPECT_TRUE((Subtree{4, 8}.IsValid()));
  // But if they don't start at 0, there's a limit to how big they can be.
  EXPECT_FALSE((Subtree{4, 9}.IsValid()));
  // Subtrees can have a ragged right edge.
  EXPECT_TRUE((Subtree{4, 6}.IsValid()));
  EXPECT_TRUE((Subtree{0, 6}.IsValid()));
}

TEST(MerkleTreeTest, SubtreeSplit) {
  // Empty subtree.
  EXPECT_EQ((Subtree{24601, 24601}).Split(), 24601ul);
  // Single-item subtree.
  EXPECT_EQ((Subtree{1336, 1337}).Split(), 1337ul);
  // Two items in subtree.
  EXPECT_EQ((Subtree{42, 44}).Split(), 43ul);
  // Subtree size is 1 less than a power of 2.
  EXPECT_EQ((Subtree{0, 31}).Split(), 16ul);
  // Subtree size is a power of 2.
  EXPECT_EQ((Subtree{64, 128}).Split(), 96ul);
  /// Subtree size is 1 more than a power of 2.
  EXPECT_EQ((Subtree{0, 257}).Split(), 256ul);

  static const uint64_t u64_max = std::numeric_limits<uint64_t>::max();
  // Maximum size tree.
  EXPECT_EQ((Subtree{0, u64_max}).Split(), 1ull << 63);
  // Small tree, with end at maximum value.
  EXPECT_EQ((Subtree{u64_max - 3, u64_max}).Split(), u64_max - 1);
}

TEST(MerkleTreeTest, VerifySubtreeInclusionProof) {
  auto entries = MakeTestEntries("label", 847);
  MerkleTreeInMemory tree(entries);

  uint64_t index = 0;
  auto node_hash = tree.SubtreeHash({index, index + 1});
  Subtree subtree{0, 16};
  auto proof = tree.SubtreeInclusionProof(index, subtree);
  auto root_hash = EvaluateMerkleSubtreeConsistencyProof(
      subtree.end, {index, index + 1}, proof, node_hash);
  ASSERT_TRUE(root_hash.has_value());
  EXPECT_EQ(root_hash, tree.SubtreeHash(subtree));
  // Check again with EvaluateMerkleSubtreeInclusionProof
  root_hash =
      EvaluateMerkleSubtreeInclusionProof(proof, index, node_hash, subtree);
  ASSERT_TRUE(root_hash.has_value());
  EXPECT_EQ(root_hash, tree.SubtreeHash(subtree));

  // Build and verify a proof from a subtree with start != 0
  index = 845;
  node_hash = tree.SubtreeHash({index, index + 1});
  subtree = {840, 847};
  proof = tree.SubtreeInclusionProof(index, subtree);
  root_hash = EvaluateMerkleSubtreeConsistencyProof(
      subtree.Size(), {index - subtree.start, index - subtree.start + 1}, proof,
      node_hash);
  ASSERT_TRUE(root_hash.has_value());
  EXPECT_EQ(root_hash, tree.SubtreeHash(subtree));
  // Check again with EvaluateMerkleSubtreeInclusionProof
  root_hash =
      EvaluateMerkleSubtreeInclusionProof(proof, index, node_hash, subtree);
  ASSERT_TRUE(root_hash.has_value());
  EXPECT_EQ(root_hash, tree.SubtreeHash(subtree));
}

TEST(MerkleTreeTest, SubtreeInclusionProofInvalidArgs) {
  auto entries = MakeTestEntries("label", 847);
  MerkleTreeInMemory tree(entries);

  uint64_t index = 845;
  auto node_hash = tree.SubtreeHash({index, index + 1});
  Subtree subtree = {840, 847};
  auto proof = tree.SubtreeInclusionProof(index, subtree);

  // If the wrong node hash is passed in, the function will still compute a
  // root hash, but it won't match the expected value.
  auto wrong_node_hash = tree.SubtreeHash({index + 1, index + 2});
  auto root_hash = EvaluateMerkleSubtreeInclusionProof(
      proof, index, wrong_node_hash, subtree);
  ASSERT_TRUE(root_hash.has_value());
  EXPECT_NE(root_hash, tree.SubtreeHash(subtree));

  // If the subtree isn't valid, the function will fail.
  ASSERT_FALSE(
      EvaluateMerkleSubtreeInclusionProof(proof, index, node_hash, {840, 849}));

  // If the index isn't contained within the subtree, the function will fail.
  ASSERT_FALSE(
      EvaluateMerkleSubtreeInclusionProof(proof, 848, node_hash, {840, 847}));
}

// Test that the computed consistency proofs match the examples given in RFC
// 9162 section 2.1.5.
TEST(MerkleTreeTest, SubtreeConsistencyProofRFC9162) {
  auto entries = MakeTestEntries("label", 7);
  MerkleTreeInMemory tree(entries);

  // The example from section 2.1.5 has a final tree with 7 leaves.
  Subtree final_tree{0, 7};

  // The examples refer to letters representing the hashes of various subtrees
  // within that tree. a and e aren't used in any of the examples.
  auto b = tree.SubtreeHash({1, 2});
  auto c = tree.SubtreeHash({2, 3});
  auto d = tree.SubtreeHash({3, 4});
  auto f = tree.SubtreeHash({5, 6});
  auto g = tree.SubtreeHash({0, 2});
  auto h = tree.SubtreeHash({2, 4});
  auto i = tree.SubtreeHash({4, 6});
  auto j = tree.SubtreeHash({6, 7});
  auto k = tree.SubtreeHash({0, 4});
  auto l = tree.SubtreeHash({4, 7});

  // Inclusion proofs:

  // Section 2.1.5: "The inclusion proof for `d0` is `[b, h, l]`."
  auto d0_proof = tree.SubtreeInclusionProof(0, final_tree);
  EXPECT_EQ(d0_proof, ConcatProof({b, h, l}));

  // Section 2.1.5: "The inclusion proof for `d3` is `[c, g, l]`."
  auto d3_proof = tree.SubtreeInclusionProof(3, final_tree);
  EXPECT_EQ(d3_proof, ConcatProof({c, g, l}));

  // Section 2.1.5: "The inclusion proof for `d4` is `[f, j, k]`."
  auto d4_proof = tree.SubtreeInclusionProof(4, final_tree);
  EXPECT_EQ(d4_proof, ConcatProof({f, j, k}));

  // Section 2.1.5: "The inclusion proof for `d6` is `[i, k]`."
  auto d6_proof = tree.SubtreeInclusionProof(6, final_tree);
  EXPECT_EQ(d6_proof, ConcatProof({i, k}));

  // Consistency proofs:

  // The consistency proofs refer to the lettered hashes above, as well as some
  // hashes of the tree as it was incrementally built.
  Subtree hash0_subtree = {0, 3};
  Subtree hash1_subtree = {0, 4};
  auto hash1 = tree.SubtreeHash(hash1_subtree);
  ASSERT_EQ(hash1, k);
  Subtree hash2_subtree = {0, 6};

  // "The consistency proof between hash0 and hash is [c, d, g, l]."
  auto hash0_proof = SubtreeConsistencyProof(tree, hash0_subtree, final_tree);
  EXPECT_EQ(hash0_proof, ConcatProof({c, d, g, l}));

  // "The consistency proof beween hash1 and hash is [l]."
  auto hash1_proof = SubtreeConsistencyProof(tree, hash1_subtree, final_tree);
  EXPECT_EQ(hash1_proof, ConcatProof({l}));

  // "The consistency proof between hash2 and hash is [i, j, k]."
  auto hash2_proof = SubtreeConsistencyProof(tree, hash2_subtree, final_tree);
  EXPECT_EQ(hash2_proof, ConcatProof({i, j, k}));
}

TEST(MerkleTreeTest, ValidProofsTest) {
  uint64_t n = 4, start = 0, end = 3;
  Subtree full_tree{0, n};
  auto entries = MakeTestEntries("label", n);
  MerkleTreeInMemory tree(entries);

  auto tree_hash = tree.SubtreeHash(full_tree);
  Subtree subtree{start, end};
  ASSERT_TRUE(subtree.IsValid());
  auto subtree_hash = tree.SubtreeHash(subtree);

  auto proof = SubtreeConsistencyProof(tree, subtree, full_tree);
  auto computed_hash =
      EvaluateMerkleSubtreeConsistencyProof(n, subtree, proof, subtree_hash);
  EXPECT_EQ(computed_hash, tree_hash);
}

TEST(MerkleTreeTest, ValidProofs) {
  // As of the time of writing this test, a run was performed with limit=257 and
  // the test passed. This value is set to 129 to balance how much of the space
  // to explore with test execution time. In particular, in an unoptimized
  // build, limit=257 takes about 4 seconds.
  for (bool incremental : {false, true}) {
    SCOPED_TRACE(incremental);

    uint64_t limit = 129;
    auto entries = MakeTestEntries("label", limit);
    MerkleTreeInMemory tree;
    if (incremental) {
      for (const auto &entry : entries) {
        tree.Append(entry);
      }
    } else {
      tree = MerkleTreeInMemory(entries);
    }

    // Exhaustively test subtree consistency proofs.
    for (uint64_t n = 1; n < limit; n++) {
      Subtree full_tree{0, n};
      auto tree_hash = tree.SubtreeHash(full_tree);
      for (uint64_t end = 0; end <= n; end++) {
        for (uint64_t start = 0; start < end; start++) {
          Subtree subtree{start, end};
          if (!subtree.IsValid()) {
            continue;
          }
          SCOPED_TRACE(testing::Message() << "Tree n=" << n << ", start: "
                                          << start << ", end: " << end);
          auto subtree_hash = tree.SubtreeHash(subtree);
          auto proof = SubtreeConsistencyProof(tree, subtree, full_tree);
          auto computed_hash = EvaluateMerkleSubtreeConsistencyProof(
              n, subtree, proof, subtree_hash);
          EXPECT_EQ(computed_hash, tree_hash);
        }
      }
    }

    // Exhaustively test subtree inclusion proofs.
    for (uint64_t end = 0; end <= limit; end++) {
      for (uint64_t start = 0; start < end; start++) {
        Subtree subtree{start, end};
        if (!subtree.IsValid()) {
          continue;
        }
        for (uint64_t index = start; index < end; index++) {
          SCOPED_TRACE(testing::Message() << "index: " << index << ", start: "
                                          << start << ", end: " << end);
          auto subtree_hash = tree.SubtreeHash(subtree);
          auto entry_hash = tree.SubtreeHash({index, index + 1});
          auto proof = tree.SubtreeInclusionProof(index, subtree);
          auto computed_hash = EvaluateMerkleSubtreeInclusionProof(
              proof, index, entry_hash, subtree);
          EXPECT_EQ(computed_hash, subtree_hash);

          // A subtree inclusion proof is a special case of a consistency proof.
          auto proof2 =
              SubtreeConsistencyProof(tree, {index, index + 1}, subtree);
          EXPECT_EQ(proof, proof2);
        }
      }
    }
  }
}

class MerkleTreeLarge : public MerkleTree {
 public:
  // Constructs a Merkle Tree over 2^64 - 1 copies of `entry`.
  explicit MerkleTreeLarge(Span<const uint8_t> entry) {
    HashLeaf(entry, levels_[0]);
    for (size_t i = 1; i < levels_.size(); i++) {
      HashNode(levels_[i - 1], levels_[i - 1], levels_[i]);
    }
  }

  uint64_t Size() const override {
    return std::numeric_limits<uint64_t>::max();
  }

  TreeHash GetNode(size_t level, uint64_t index) const override {
    BSSL_CHECK(level < 64);
    return levels_[level];
  }

 private:
  std::array<TreeHash, 64> levels_;
};

TEST(MerkleTreeTest, VeryLargeProofs) {
  MerkleTreeLarge tree(StringAsBytes("entry"));

  Subtree fullest_tree = {0, std::numeric_limits<uint64_t>::max()};
  auto root_hash = tree.SubtreeHash(fullest_tree);

  Subtree test_subtrees[] = {
      fullest_tree,
      {0, 1},
      {0, 1ull << 63},
      {1ull << 63, std::numeric_limits<uint64_t>::max()},
      {std::numeric_limits<uint64_t>::max() - 1,
       std::numeric_limits<uint64_t>::max()},
  };
  for (auto subtree : test_subtrees) {
    SCOPED_TRACE(testing::Message() << "Subtree start: " << subtree.start
                                    << ", end: " << subtree.end);

    auto proof = SubtreeConsistencyProof(tree, subtree, fullest_tree);
    auto computed_root_hash = EvaluateMerkleSubtreeConsistencyProof(
        fullest_tree.end, subtree, proof, tree.SubtreeHash(subtree));
    EXPECT_EQ(computed_root_hash, root_hash);
  }
}

}  // namespace

BSSL_NAMESPACE_END
