// 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 <algorithm>
#include <optional>

#include <openssl/mem.h>
#include <openssl/span.h>
#include <openssl/sha2.h>

BSSL_NAMESPACE_BEGIN

namespace {

std::optional<TreeHashConstSpan> NextProofHash(Span<const uint8_t> *proof) {
  if (proof->size() < SHA256_DIGEST_LENGTH) {
    return std::nullopt;
  }
  auto ret = proof->first<SHA256_DIGEST_LENGTH>();
  *proof = proof->subspan(SHA256_DIGEST_LENGTH);
  return ret;
}

// TODO(crbug.com/404286922): Use std::countr_one when we have C++20.
size_t TrailingOnes(uint64_t n) {
  size_t count = 0;
  while (n & 1) {
    n >>= 1;
    count++;
  }
  return count;
}

}  // namespace

// This value is equal to SHA256("").
const TreeHash MerkleTree::kEmptySubtreeHash = {
    0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
    0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b,
    0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
};

// Computes HASH(0x01 || left || right) and saves the result to `out`.
void HashNode(TreeHashConstSpan left, TreeHashConstSpan right,
              TreeHashSpan out) {
  static const uint8_t header = 0x01;
  SHA256_CTX ctx;
  SHA256_Init(&ctx);
  SHA256_Update(&ctx, &header, 1);
  SHA256_Update(&ctx, left.data(), left.size());
  SHA256_Update(&ctx, right.data(), right.size());
  SHA256_Final(out.data(), &ctx);
}

void HashLeaf(Span<const uint8_t> entry, TreeHashSpan out) {
  static const uint8_t header = 0x00;
  SHA256_CTX ctx;
  SHA256_Init(&ctx);
  SHA256_Update(&ctx, &header, 1);
  SHA256_Update(&ctx, entry.data(), entry.size());
  SHA256_Final(out.data(), &ctx);
}

namespace {

// Performs the procedure defined in section 4.4.3 of
// draft-davidben-tls-merkle-tree-certs-08, Verifying a Subtree Consistency
// Proof:
//
//   Given a Merkle Tree over `n` elements, a subtree defined by `[start, end)`,
//   a consistency proof `proof`, a subtree hash `node_hash`, and a root hash
//   `root_hash`
//
// The one difference between this function and the routine described in
// draft-davidben-tls-merkle-tree-certs-08 is that instead of taking `root_hash`
// as an input, this function returns the computed root hash and it is the
// caller's responsibility to verify that the computed root hash matches the
// expected root hash. This function returns std::nullopt if other steps of
// proof verification failed.
//
// This function does not accept empty subtrees, which are otherwise valid. For
// an empty subtree, the procedure to compute a root hash isn't coherent. If the
// subtree is empty, a consistency proof can only be verified, not evaluated.
std::optional<TreeHash> EvaluateMerkleSubtreeConsistencyProof(
    uint64_t n, const Subtree &subtree, Span<const uint8_t> proof,
    TreeHashConstSpan node_hash) {
  // For more detail on how subtree consistency proofs work, see appendix B
  // of draft-davidben-tls-merkle-tree-certs-08.

  // This function does not accept empty subtrees, which are otherwise valid.
  assert(subtree.start < subtree.end);

  // Check that inputs are valid. (Step 1)
  if (!subtree.IsValid() || n < subtree.end) {
    return std::nullopt;
  }

  // Initialize fn (first number), sn (second number), and tn (third number).
  // Each number is the path from the root of the tree to 1) the leftmost child
  // of the subtree, 2) the rightmost child of the subtree, and 3) the rightmost
  // child of the full tree. (Step 2)
  uint64_t fn = subtree.start;
  uint64_t sn = subtree.end - 1;
  uint64_t tn = n - 1;

  // The bit patterns of these numbers indicates whether the path goes left or
  // right (or in some cases on the rightmost edge of a (sub)tree, that a level
  // of the tree is skipped).
  //
  // When consuming the proof, we work up the tree from the bottom level (level
  // 0) up to the root, and moving up one level in the tree corresponds to
  // consuming the least significant bit from each of fn, sn, and tn. The proof
  // can start at a higher level than level 0 if the node on the right edge of
  // the subtree at that level is also a node of the overall tree.
  //
  // Remove bits equally from the right of fn, sn, and tn to skip to the level
  // of the tree where the proof starts. (Steps 3 and 4)
  if (sn == tn) {
    // If sn == tn, then the rightmost child of the subtree and the rightmost
    // child of the full tree are the same node, meaning that the subtree is
    // directly contained in the full tree. The proof starts at the same level
    // as the top of the subtree. That level is identified by advancing
    // bit-by-bit through fn and sn until they are the same, meaning that we've
    // moved up the levels of the tree to where the left and right edge of the
    // subtree reach the same point (the root of the subtree).
    //
    // (Step 3: right shift until fn is sn)
    while (fn != sn) {
      fn >>= 1;
      sn >>= 1;
      tn >>= 1;
    }
  } else {
    // Find the largest full (rather than partial) subtree that the rightmost
    // edge of the input subtree is still the rightmost edge of, without going
    // beyond the bounds of the input subtree. Any such full subtree is directly
    // contained in the tree of hash operations for the full tree, meaning that
    // the proof can start at that level rather than level 0.
    //
    // As long as the path to the rightmost edge of the input subtree is
    // indicating it's on the right side of its parent node (its LSB is 1), it's
    // still on the rightmost edge of a full (rather than partial) subtree.
    // Iteration stops when it's no longer on the rightmost edge of a full
    // subtree (LSB(sn) is not set) or when we reach the top of the input
    // subtree (fn is sn).
    //
    // (Step 4: right-shift until fn is sn or LSB(sn) is not set)
    while (fn != sn && (sn & 1) == 1) {
      fn >>= 1;
      sn >>= 1;
      tn >>= 1;
    }
  }

  // The proof array starts with the highest node from the subtree's right edge
  // that is also in the overall tree, and subsequent values from the proof
  // array are hashed in to compute the values that should be node_hash and
  // root_hash if the proof is valid. As an optimization, if node_hash is the
  // hash of the highest node from the subtree's right edge (i.e. the whole
  // subtree is directly contained in the overall tree), that value is omitted
  // from the proof.
  //
  // In this code, computed_node_hash and computed_root_hash are the values fr
  // and sr from draft-davidben-tls-merkle-tree-certs-08.
  // (Steps 5 and 6)
  TreeHash computed_node_hash, computed_root_hash;
  if (fn == sn) {
    // The optimization mentioned above. (Step 5)
    std::copy(node_hash.begin(), node_hash.end(), computed_node_hash.data());
    std::copy(node_hash.begin(), node_hash.end(), computed_root_hash.data());
  } else {
    // The hashes start from the first value of the proof (Step 6)
    std::optional<TreeHashConstSpan> first_hash = NextProofHash(&proof);
    if (!first_hash) {
      return std::nullopt;
    }
    std::copy(first_hash->begin(), first_hash->end(),
              computed_node_hash.data());
    std::copy(first_hash->begin(), first_hash->end(),
              computed_root_hash.data());
  }

  // Iterate over the (remaining) elements of the proof array and traverse up
  // the fn/sn/tn paths until we reach the root of the tree. Each step should
  // consume one element from the proof array and move one level up the tree,
  // and if the proof is valid both iterators end at the same time. (Step 7)
  while (!proof.empty()) {
    auto p = NextProofHash(&proof);
    if (!p) {
      return std::nullopt;
    }
    // (Step 7.1)
    if (tn == 0) {
      // We reached the root of the tree before running out of elements in the
      // proof.
      return std::nullopt;
    }
    // Update the computed root_hash, and if applicable the computed node_hash.
    // We stop updating computed_node_hash when we've reached the level of the
    // root of the subtree, which occurs when the paths to the leftmost and
    // rightmost nodes of the subtree are the same, i.e. fn == sn.
    //
    // (Step 7.2)
    if ((sn & 1) == 1 || sn == tn) {
      // (Step 7.2.1)
      if (fn < sn) {
        HashNode(*p, computed_node_hash, computed_node_hash);
      }
      // (Step 7.2.2)
      HashNode(*p, computed_root_hash, computed_root_hash);
      // Until LSB(sn) is set, right-shift fn, sn, and tn equally.
      // (Step 7.2.3)
      while ((sn & 1) == 0) {
        fn >>= 1;
        sn >>= 1;
        tn >>= 1;
      }
    } else {
      // (Step 7.3.1)
      HashNode(computed_root_hash, *p, computed_root_hash);
    }
    // Advance the iterators: (Step 7.4)
    fn >>= 1;
    sn >>= 1;
    tn >>= 1;
  }

  // Check that the iterators ended together: (Step 8)
  if (tn != 0) {
    return std::nullopt;
  }

  // Check that the computed values match the expected values: (Step 8)
  if (CRYPTO_memcmp(computed_node_hash.data(), node_hash.data(),
                    computed_node_hash.size()) != 0) {
    return std::nullopt;
  }
  // Return the computed root_hash for the caller to compare:
  return computed_root_hash;
}

}  // namespace

OPENSSL_EXPORT bool VerifyMerkleSubtreeConsistencyProof(
    uint64_t n, const Subtree &subtree, Span<const uint8_t> proof,
    TreeHashConstSpan node_hash, TreeHashConstSpan root_hash) {
  // Special case for empty subtrees.
  if (subtree.start == subtree.end) {
    return proof.empty() && node_hash == MerkleTree::kEmptySubtreeHash;
  }

  // Computation for non-empty subtrees.
  std::optional<TreeHash> computed_root_hash =
      EvaluateMerkleSubtreeConsistencyProof(n, subtree, proof, node_hash);
  return computed_root_hash.has_value() && *computed_root_hash == root_hash;
}

std::optional<TreeHash> EvaluateMerkleSubtreeInclusionProof(
    Span<const uint8_t> inclusion_proof, uint64_t index,
    TreeHashConstSpan entry_hash, const Subtree &subtree) {
  if (!subtree.IsValid() || !subtree.Contains(index) ||
      // Empty subtrees, which are otherwise valid, must fail inclusion proof
      // evaluation.
      subtree.start == subtree.end) {
    return std::nullopt;
  }
  // Re-root `index` inside of `subtree`.
  index -= subtree.start;
  return EvaluateMerkleSubtreeConsistencyProof(
      subtree.Size(), {index, index + 1}, inclusion_proof, entry_hash);
}

TreeHash MerkleTree::SubtreeHash(const Subtree &subtree) const {
  BSSL_CHECK(subtree.IsValid());
  BSSL_CHECK(subtree.end <= Size());

  if (subtree.Size() == 0) {
    return kEmptySubtreeHash;
  }

  // Start at the largest complete subtree on the right edge.
  uint64_t start = subtree.start, last = subtree.end - 1;
  size_t level = TrailingOnes(last - start);
  start = start >> level;
  last = last >> level;
  TreeHash ret = GetNode(level, last);

  // Invariants:
  // * `start <= last`
  // * `subtree.start` is `start << level` (The subtree invariant implies we
  //   only shift away zero bits from `start`.)
  // * `ret` is `SubtreeHash({last << level, end})`.
  while (start < last) {
    if (last & 1) {
      // Hash in the left neighbor.
      HashNode(GetNode(level, last - 1), ret, ret);
    }
    level++;
    start >>= 1;
    last >>= 1;
  }

  return ret;
}

std::vector<uint8_t> MerkleTree::SubtreeInclusionProof(
    uint64_t index, const Subtree &subtree) const {
  BSSL_CHECK(subtree.IsValid());
  BSSL_CHECK(subtree.end <= Size());
  BSSL_CHECK(subtree.Contains(index));

  // The inclusion proof consists of the neighbors of `index` at each level.
  std::vector<uint8_t> proof;
  uint64_t start = subtree.start, last = subtree.end - 1;
  size_t level = 0;
  // Invariant: `proof` contains the inclusion proof of the original `index`
  // parameter in `Subtree{index << level, min((index + 1) << level, end)}}`.
  while (start < last) {
    // Append the neighbor node, if it exists.
    uint64_t neighbor = index ^ 1;
    if (neighbor < last) {
      // The neighbor is complete, so we can look it up directly.
      const TreeHash &h = GetNode(level, neighbor);
      proof.insert(proof.end(), h.begin(), h.end());
    } else if (neighbor == last) {
      // The neighbor is on the right edge and may not be complete.
      TreeHash h = SubtreeHash({last << level, subtree.end});
      proof.insert(proof.end(), h.begin(), h.end());
    }
    level++;
    start >>= 1;
    index >>= 1;
    last >>= 1;
  }
  return proof;
}

MerkleTreeInMemory::MerkleTreeInMemory() { levels_.emplace_back(); }

MerkleTreeInMemory::MerkleTreeInMemory(
    Span<const std::vector<uint8_t>> entries) {
  // Compute the leaf nodes.
  std::vector<TreeHash> level;
  level.resize(entries.size());
  for (size_t i = 0; i < entries.size(); i++) {
    HashLeaf(entries[i], level[i]);
  }
  levels_.push_back(std::move(level));

  UpdateLevels();
}

uint64_t MerkleTreeInMemory::Size() const { return levels_[0].size(); }

TreeHash MerkleTreeInMemory::GetNode(size_t level, uint64_t index) const {
  BSSL_CHECK(level < levels_.size());
  BSSL_CHECK(index < levels_[level].size());
  return levels_[level][index];
}

void MerkleTreeInMemory::Append(Span<const uint8_t> entry) {
  TreeHash h;
  HashLeaf(entry, h);
  levels_[0].push_back(h);
  UpdateLevels();
}

void MerkleTreeInMemory::UpdateLevels() {
  assert(!levels_.empty());
  for (size_t level = 1, n = Size() / 2; n != 0; level++, n /= 2) {
    // Ensure level `level` exists and has `n` elements.
    if (level == levels_.size()) {
      levels_.emplace_back();
    }
    levels_[level].reserve(n);
    while (levels_[level].size() < n) {
      size_t i = levels_[level].size();
      TreeHash h;
      HashNode(levels_[level - 1][2 * i], levels_[level - 1][2 * i + 1], h);
      levels_[level].push_back(h);
    }
  }
}

BSSL_NAMESPACE_END
