From 91b25ef13b94828d9c1d8767c28014b9cb377a4b Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 19:02:26 +0000 Subject: [PATCH 01/10] delete completely unused index.hpp --- .../src/barretenberg/crypto/merkle_tree/index.hpp | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/index.hpp diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/index.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/index.hpp deleted file mode 100644 index 696cc0924e10..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/index.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } -// external_1: { status: not started, auditors: [], commit: } -// external_2: { status: not started, auditors: [], commit: } -// ===================== - -#pragma once -#include "hash.hpp" -#include "hash_path.hpp" -#include "memory_store.hpp" -#include "memory_tree.hpp" -#include "merkle_tree.hpp" From 5f91b98e4f26f163cfbfa2b8a8d6a541f60b6455 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 19:12:23 +0000 Subject: [PATCH 02/10] remove dead code used only in tests/bench --- .../src/barretenberg/benchmark/CMakeLists.txt | 1 - .../merkle_tree_bench/CMakeLists.txt | 1 - .../merkle_tree_bench/merkle_tree.bench.cpp | 77 --- .../crypto/merkle_tree/merkle_tree.hpp | 456 ------------------ .../crypto/merkle_tree/merkle_tree.test.cpp | 185 ------- .../nullifier_tree/nullifier_tree.cpp | 96 ---- .../nullifier_tree/nullifier_tree.hpp | 43 -- .../nullifier_tree/nullifier_tree.test.cpp | 144 ------ .../src/barretenberg/goblin/mock_circuits.hpp | 2 - 9 files changed, 1005 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt delete mode 100644 barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/merkle_tree.bench.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.test.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.test.cpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt index 4df12fa2646f..12d08f15e49a 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/CMakeLists.txt @@ -7,7 +7,6 @@ add_subdirectory(chonk_bench) add_subdirectory(pippenger_bench) add_subdirectory(relations_bench) add_subdirectory(poseidon2_bench) -add_subdirectory(merkle_tree_bench) add_subdirectory(indexed_tree_bench) add_subdirectory(append_only_tree_bench) add_subdirectory(ultra_bench) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt deleted file mode 100644 index 32f510cc1d64..000000000000 --- a/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -barretenberg_module(merkle_tree_bench crypto_poseidon2 ext_starknet_crypto_poseidon crypto_pedersen_hash crypto_merkle_tree) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/merkle_tree.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/merkle_tree.bench.cpp deleted file mode 100644 index 1fadcf94d282..000000000000 --- a/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/merkle_tree.bench.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "barretenberg/crypto/merkle_tree/merkle_tree.hpp" -#include "barretenberg/crypto/merkle_tree/hash.hpp" -#include "barretenberg/crypto/merkle_tree/memory_store.hpp" -#include "barretenberg/numeric/random/engine.hpp" -#include - -using namespace benchmark; -using namespace bb; -using namespace bb::crypto::merkle_tree; - -using TreeType = MerkleTree; - -namespace { -auto& engine = bb::numeric::get_debug_randomness(); -} // namespace - -constexpr size_t DEPTH = 256; -constexpr size_t MAX = 4096; - -static std::vector VALUES = []() { - std::vector values(MAX); - for (size_t i = 0; i < MAX; ++i) { - values[i] = fr(i); - } - return values; -}(); - -void hash(State& state) noexcept -{ - for (auto _ : state) { - PedersenHashPolicy::hash_pair({ 0, 0, 0, 0 }, { 1, 1, 1, 1 }); - } -} -BENCHMARK(hash)->MinTime(5); - -void update_first_element(State& state) noexcept -{ - MemoryStore store; - TreeType db(store, DEPTH); - - for (auto _ : state) { - db.update_element(0, VALUES[1]); - } -} -BENCHMARK(update_first_element)->Unit(benchmark::kMillisecond); - -void update_elements(State& state) noexcept -{ - for (auto _ : state) { - state.PauseTiming(); - MemoryStore store; - TreeType db(store, DEPTH); - state.ResumeTiming(); - for (size_t i = 0; i < (size_t)state.range(0); ++i) { - db.update_element(i, VALUES[i]); - } - } -} -BENCHMARK(update_elements)->Unit(benchmark::kMillisecond)->RangeMultiplier(2)->Range(256, MAX); - -void update_random_elements(State& state) noexcept -{ - for (auto _ : state) { - state.PauseTiming(); - MemoryStore store; - TreeType db(store, DEPTH); - for (size_t i = 0; i < (size_t)state.range(0); i++) { - state.PauseTiming(); - auto index = TreeType::index_t(engine.get_random_uint256()); - state.ResumeTiming(); - db.update_element(index, VALUES[i]); - } - } -} -BENCHMARK(update_random_elements)->Unit(benchmark::kMillisecond)->Range(100, 100)->Iterations(1); - -BENCHMARK_MAIN(); diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.hpp deleted file mode 100644 index 76c449d050b3..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.hpp +++ /dev/null @@ -1,456 +0,0 @@ -// === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } -// external_1: { status: not started, auditors: [], commit: } -// external_2: { status: not started, auditors: [], commit: } -// ===================== - -#pragma once -#include "barretenberg/common/assert.hpp" -#include "barretenberg/common/net.hpp" -#include "barretenberg/numeric/bitop/count_leading_zeros.hpp" -#include "barretenberg/numeric/bitop/keep_n_lsb.hpp" -#include "barretenberg/numeric/uint128/uint128.hpp" -#include "barretenberg/stdlib/primitives/field/field.hpp" -#include "hash_path.hpp" -#include "merkle_tree.hpp" -#include -#include - -namespace bb::crypto::merkle_tree { - -class MemoryStore; - -template class MerkleTree { - public: - typedef uint256_t index_t; - - MerkleTree(Store& store, size_t depth, uint8_t tree_id = 0); - MerkleTree(MerkleTree const& other) = delete; - MerkleTree(MerkleTree&& other); - ~MerkleTree(); - - fr_hash_path get_hash_path(index_t index); - - fr_sibling_path get_sibling_path(index_t index); - - fr update_element(index_t index, fr const& value); - - fr root() const; - - size_t depth() const { return depth_; } - - index_t size() const; - - protected: - void load_metadata(); - - /** - * Computes the root hash of a tree of `height`, that is empty other than `value` at `index`. - * - * @param height: The tree depth - * @param index: the index of the non-empty leaf - * @param value: the value to be stored in the non-empty leaf - * - * @see Check full documentation: https://hackmd.io/2zyJc6QhRuugyH8D78Tbqg?view - */ - fr update_element(fr const& root, fr const& value, index_t index, size_t height); - - fr get_element(fr const& root, index_t index, size_t height); - - /** - * Computes the root hash of a tree of `height`, that is empty other than `value` at `index`. - * - * @param height: The tree depth - * @param index: the index of the non-empty leaf - * @param value: the value to be stored in the non-empty leaf - */ - fr compute_zero_path_hash(size_t height, index_t index, fr const& value); - - /** - * Given child nodes `a` and `b` and index of `a`, compute their parent node `p` and store [p : (a, b)]. - * - * @param a_index: the index of the child node `a` - * @param a: child node - * @param b: child node - * @param height: the height of the parent node - */ - fr binary_put(index_t a_index, fr const& a, fr const& b, size_t height); - - fr fork_stump( - fr const& value1, index_t index1, fr const& value2, index_t index2, size_t height, size_t stump_height); - - /** - * Stores a parent node and child nodes in the database as [key : (left, right)]. - * - * @param key: The node value to be stored as key - * @param left: the left child node - * @param right: the right child node - */ - void put(fr const& key, fr const& left, fr const& right); - - /** - * Stores a stump [key : (value, index, true)] in the memory. - * The additional byte `true` is to denote this is a stump. - * - * @param key: The node value to be stored as key - * @param value: value of the non-empty leaf in the stump - * @param index: the index of the non-empty leaf in the stump - */ - void put_stump(fr const& key, index_t index, fr const& value); - - void remove(fr const& key); - - protected: - Store& store_; - std::vector zero_hashes_; - size_t depth_; - uint8_t tree_id_; -}; - -// Size of merkle tree nodes in bytes. -constexpr size_t REGULAR_NODE_SIZE = 64; -constexpr size_t STUMP_NODE_SIZE = 65; - -template inline bool bit_set(T const& index, size_t i) -{ - return bool((index >> i) & 0x1); -} - -template -MerkleTree::MerkleTree(Store& store, size_t depth, uint8_t tree_id) - : store_(store) - , depth_(depth) - , tree_id_(tree_id) -{ - BB_ASSERT_GTE(depth_, 1U); - BB_ASSERT_LTE(depth, 256U); - zero_hashes_.resize(depth); - - // Compute the zero values at each layer. - auto current = fr(0); - for (size_t i = 0; i < depth; ++i) { - zero_hashes_[i] = current; - current = HashingPolicy::hash_pair(current, current); - } -} - -template -MerkleTree::MerkleTree(MerkleTree&& other) - : store_(other.store_) - , zero_hashes_(std::move(other.zero_hashes_)) - , depth_(other.depth_) - , tree_id_(other.tree_id_) -{} - -template MerkleTree::~MerkleTree() {} - -template fr MerkleTree::root() const -{ - std::vector root; - std::vector key = { tree_id_ }; - bool status = store_.get(key, root); - return status ? from_buffer(root) : HashingPolicy::hash_pair(zero_hashes_.back(), zero_hashes_.back()); -} - -template -typename MerkleTree::index_t MerkleTree::size() const -{ - std::vector size_buf; - std::vector key = { tree_id_ }; - bool status = store_.get(key, size_buf); - return status ? from_buffer(size_buf, 32) : 0; -} - -template -fr_hash_path MerkleTree::get_hash_path(index_t index) -{ - fr_hash_path path(depth_); - - std::vector data; - bool status = store_.get(root().to_buffer(), data); - - for (size_t i = depth_ - 1; i < depth_; --i) { - if (!status) { - // This is an empty subtree. Fill in zero value. - path[i] = std::make_pair(zero_hashes_[i], zero_hashes_[i]); - continue; - } - - if (data.size() == REGULAR_NODE_SIZE) { - // This is a regular node with left and right trees. Descend according to index path. - auto left = from_buffer(data, 0); - auto right = from_buffer(data, 32); - path[i] = std::make_pair(left, right); - bool is_right = bit_set(index, i); - auto it = data.data() + (is_right ? 32 : 0); - status = store_.get(std::vector(it, it + 32), data); - } else { - // This is a stump. The hash path can be fully restored from this node. - BB_ASSERT_EQ(data.size(), - STUMP_NODE_SIZE, - "We store: [key : (value, local_index, true)], i.e. 65-byte data, in a thump."); - fr current = from_buffer(data, 0); - index_t element_index = from_buffer(data, 32); - index_t subtree_index = numeric::keep_n_lsb(index, i + 1); - index_t diff = element_index ^ subtree_index; - - if (diff < 2) { - // Requesting path to either the same element in the stump, or it's partner element. - // Starting at the bottom of the tree, compute the remaining path pairs. - for (size_t j = 0; j <= i; ++j) { - bool is_right = bit_set(element_index, j); - if (is_right) { - path[j] = std::make_pair(zero_hashes_[j], current); - } else { - path[j] = std::make_pair(current, zero_hashes_[j]); - } - current = HashingPolicy::hash_pair(path[j].first, path[j].second); - } - } else { - // Requesting path to a different, independent element. - // We know that this element exists in an empty subtree, of height determined by the common bits in the - // stumps index and the requested index. - size_t common_bits = numeric::count_leading_zeros(diff); - size_t common_height = sizeof(index_t) * 8 - common_bits - 1; - - for (size_t j = 0; j < common_height; ++j) { - path[j] = std::make_pair(zero_hashes_[j], zero_hashes_[j]); - } - current = compute_zero_path_hash(common_height, element_index, current); - for (size_t j = common_height; j <= i; ++j) { - bool is_right = bit_set(element_index, j); - if (is_right) { - path[j] = std::make_pair(zero_hashes_[j], current); - } else { - path[j] = std::make_pair(current, zero_hashes_[j]); - } - current = HashingPolicy::hash_pair(path[j].first, path[j].second); - } - } - break; - } - } - - return path; -} - -template -fr_sibling_path MerkleTree::get_sibling_path(index_t index) -{ - fr_sibling_path path(depth_); - - std::vector data; - bool status = store_.get(root().to_buffer(), data); - - for (size_t i = depth_ - 1; i < depth_; --i) { - if (!status) { - // This is an empty subtree. Fill in zero value. - path[i] = zero_hashes_[i]; - continue; - } - - if (data.size() == REGULAR_NODE_SIZE) { - // This is a regular node with left and right trees. Descend according to index path. - bool is_right = bit_set(index, i); - path[i] = from_buffer(data, is_right ? 0 : 32); - - auto it = data.data() + (is_right ? 32 : 0); - status = store_.get(std::vector(it, it + 32), data); - } else { - // This is a stump. The sibling path can be fully restored from this node. - // In case of a stump, we store: [key : (value, local_index, true)], i.e. 65-byte data. - BB_ASSERT_EQ(data.size(), STUMP_NODE_SIZE); - fr current = from_buffer(data, 0); - index_t element_index = from_buffer(data, 32); - index_t subtree_index = numeric::keep_n_lsb(index, i + 1); - index_t diff = element_index ^ subtree_index; - - // Populate the sibling path with zero hashes. - for (size_t j = 0; j <= i; ++j) { - path[j] = zero_hashes_[j]; - } - - // If diff == 0, we are requesting the sibling path of the only non-zero element in the stump which is - // populated only with zero hashes. - if (diff == 1) { - // Requesting path of the sibling of the non-zero leaf in the stump. - // Set the bottom element of the path to the non-zero leaf (the rest is already populated correctly - // with zero hashes). - path[0] = current; - } else if (diff > 1) { - // Requesting path to a different, independent element. - // We know that this element exists in an empty subtree, of height determined by the common bits in the - // stumps index and the requested index. - size_t common_bits = numeric::count_leading_zeros(diff); - size_t common_height = sizeof(index_t) * 8 - common_bits - 1; - - // Insert the only non-zero sibling at the common height. - path[common_height] = compute_zero_path_hash(common_height, element_index, current); - } - break; - } - } - - return path; -} - -template -fr MerkleTree::update_element(index_t index, fr const& value) -{ - auto leaf = value; - using serialize::write; - std::vector leaf_key; - write(leaf_key, tree_id_); - write(leaf_key, index); - store_.put(leaf_key, to_buffer(leaf)); - - auto r = update_element(root(), leaf, index, depth_); - - std::vector meta_key = { tree_id_ }; - std::vector meta_buf; - write(meta_buf, r); - write(meta_buf, index + 1); - store_.put(meta_key, meta_buf); - - return r; -} - -template -fr MerkleTree::binary_put(index_t a_index, fr const& a, fr const& b, size_t height) -{ - bool a_is_right = bit_set(a_index, height - 1); - auto left = a_is_right ? b : a; - auto right = a_is_right ? a : b; - auto key = HashingPolicy::hash_pair(left, right); - put(key, left, right); - return key; -} - -template -fr MerkleTree::fork_stump( - fr const& value1, index_t index1, fr const& value2, index_t index2, size_t height, size_t common_height) -{ - if (height == common_height) { - if (height == 1) { - index1 = numeric::keep_n_lsb(index1, 1); - index2 = numeric::keep_n_lsb(index2, 1); - return binary_put(index1, value1, value2, height); - } else { - size_t stump_height = height - 1; - index_t stump1_index = numeric::keep_n_lsb(index1, stump_height); - index_t stump2_index = numeric::keep_n_lsb(index2, stump_height); - - fr stump1_hash = compute_zero_path_hash(stump_height, stump1_index, value1); - fr stump2_hash = compute_zero_path_hash(stump_height, stump2_index, value2); - put_stump(stump1_hash, stump1_index, value1); - put_stump(stump2_hash, stump2_index, value2); - return binary_put(index1, stump1_hash, stump2_hash, height); - } - } else { - auto new_root = fork_stump(value1, index1, value2, index2, height - 1, common_height); - return binary_put(index1, new_root, zero_hashes_[height - 1], height); - } -} - -template -fr MerkleTree::update_element(fr const& root, fr const& value, index_t index, size_t height) -{ - // Base layer of recursion at height = 0. - if (height == 0) { - return value; - } - - std::vector data; - auto status = store_.get(root.to_buffer(), data); - - if (!status) { - fr key = compute_zero_path_hash(height, index, value); - put_stump(key, index, value); - return key; - } - - if (data.size() == STUMP_NODE_SIZE) { - // We've come across a stump. - index_t existing_index = from_buffer(data, 32); - - if (existing_index == index) { - // We are updating the stumps element. Easy update. - fr new_hash = compute_zero_path_hash(height, index, value); - put_stump(new_hash, existing_index, value); - return new_hash; - } - - fr existing_value = from_buffer(data, 0); - size_t common_bits = numeric::count_leading_zeros(existing_index ^ index); - size_t common_height = sizeof(index_t) * 8 - common_bits; - - return fork_stump(existing_value, existing_index, value, index, height, common_height); - } else { - BB_ASSERT_EQ(data.size(), REGULAR_NODE_SIZE, "If it's not a stump, the data size must be 64 bytes."); - bool is_right = bit_set(index, height - 1); - fr subtree_root = from_buffer(data, is_right ? 32 : 0); - fr subtree_root_copy = subtree_root; - auto left = from_buffer(data, 0); - auto right = from_buffer(data, 32); - subtree_root = update_element(subtree_root, value, numeric::keep_n_lsb(index, height - 1), height - 1); - if (is_right) { - right = subtree_root; - } else { - left = subtree_root; - } - auto new_root = HashingPolicy::hash_pair(left, right); - put(new_root, left, right); - - // Remove the old node only while rolling back in recursion. - if (!(subtree_root_copy == subtree_root)) { - remove(subtree_root_copy); - } - return new_root; - } -} - -template -fr MerkleTree::compute_zero_path_hash(size_t height, index_t index, fr const& value) -{ - fr current = value; - for (size_t i = 0; i < height; ++i) { - bool is_right = bit_set(index, i); - fr left, right; - if (is_right) { - left = zero_hashes_[i]; - right = current; - } else { - right = zero_hashes_[i]; - left = current; - } - current = HashingPolicy::hash_pair(left, right); - } - return current; -} - -template -void MerkleTree::put(fr const& key, fr const& left, fr const& right) -{ - std::vector value; - write(value, left); - write(value, right); - store_.put(key.to_buffer(), value); -} - -template -void MerkleTree::put_stump(fr const& key, index_t index, fr const& value) -{ - std::vector buf; - write(buf, value); - write(buf, index); - // Add an additional byte, to signify we are a stump. - write(buf, true); - store_.put(key.to_buffer(), buf); -} - -template void MerkleTree::remove(fr const& key) -{ - store_.del(key.to_buffer()); -} - -} // namespace bb::crypto::merkle_tree diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.test.cpp deleted file mode 100644 index e2fd2d55d562..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/merkle_tree.test.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "merkle_tree.hpp" -#include "barretenberg/common/streams.hpp" -#include "barretenberg/common/test.hpp" -#include "barretenberg/numeric/random/engine.hpp" -#include "memory_store.hpp" -#include "memory_tree.hpp" - -using namespace bb; -using namespace bb::stdlib; -using namespace bb::crypto::merkle_tree; - -using Builder = UltraCircuitBuilder; - -using field_ct = field_t; -using witness_ct = witness_t; -namespace { -auto& engine = numeric::get_debug_randomness(); -auto& random_engine = numeric::get_randomness(); -} // namespace - -static std::vector VALUES = []() { - std::vector values(1024); - for (size_t i = 0; i < 1024; ++i) { - values[i] = i; - } - return values; -}(); - -TEST(crypto_merkle_tree, test_kv_memory_vs_memory_consistency) -{ - constexpr size_t depth = 10; - MemoryTree memdb(depth); - - MemoryStore store; - MerkleTree db(store, depth); - - std::vector indicies(1 << depth); - std::iota(indicies.begin(), indicies.end(), 0); - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(indicies.begin(), indicies.end(), g); - - for (size_t i = 0; i < indicies.size(); ++i) { - size_t idx = indicies[i]; - memdb.update_element(idx, VALUES[idx]); - db.update_element(idx, VALUES[idx]); - } - - for (size_t i = 0; i < indicies.size(); ++i) { - size_t idx = indicies[i]; - EXPECT_EQ(db.get_hash_path(idx), memdb.get_hash_path(idx)); - } - - EXPECT_EQ(db.root(), memdb.root()); -} - -TEST(crypto_merkle_tree, test_size) -{ - MemoryStore store; - auto db = MerkleTree(store, 256); - - EXPECT_EQ(db.size(), 0ULL); - - // Add first. - db.update_element(0, VALUES[1]); - EXPECT_EQ(db.size(), 1ULL); - - // Add second. - db.update_element(1, VALUES[2]); - EXPECT_EQ(db.size(), 2ULL); - - // Set second to same value. - db.update_element(1, VALUES[2]); - EXPECT_EQ(db.size(), 2ULL); - - // Set second to new value. - db.update_element(1, VALUES[3]); - EXPECT_EQ(db.size(), 2ULL); - - // Set third to new value. - db.update_element(2, VALUES[4]); - EXPECT_EQ(db.size(), 3ULL); -} - -TEST(crypto_merkle_tree, test_get_hash_path) -{ - MemoryTree memdb(10); - - MemoryStore store; - auto db = MerkleTree(store, 10); - - EXPECT_EQ(memdb.get_hash_path(512), db.get_hash_path(512)); - - memdb.update_element(512, VALUES[512]); - db.update_element(512, VALUES[512]); - - EXPECT_EQ(db.get_hash_path(512), memdb.get_hash_path(512)); - - for (size_t i = 0; i < 1024; ++i) { - memdb.update_element(i, VALUES[i]); - db.update_element(i, VALUES[i]); - } - - EXPECT_EQ(db.get_hash_path(512), memdb.get_hash_path(512)); -} - -TEST(crypto_merkle_tree, test_get_sibling_path) -{ - MemoryTree memdb(10); - - MemoryStore store; - auto db = MerkleTree(store, 10); - - EXPECT_EQ(memdb.get_sibling_path(512), db.get_sibling_path(512)); - - memdb.update_element(512, VALUES[512]); - db.update_element(512, VALUES[512]); - - EXPECT_EQ(db.get_sibling_path(512), memdb.get_sibling_path(512)); - - for (size_t i = 0; i < 1024; ++i) { - memdb.update_element(i, VALUES[i]); - db.update_element(i, VALUES[i]); - } - - EXPECT_EQ(db.get_sibling_path(512), memdb.get_sibling_path(512)); -} - -TEST(crypto_merkle_tree, test_get_hash_path_layers) -{ - { - MemoryStore store; - auto db = MerkleTree(store, 3); - - auto before = db.get_hash_path(1); - db.update_element(0, VALUES[1]); - auto after = db.get_hash_path(1); - - EXPECT_NE(before[0], after[0]); - EXPECT_NE(before[1], after[1]); - EXPECT_NE(before[2], after[2]); - } - - { - MemoryStore store; - auto db = MerkleTree(store, 3); - - auto before = db.get_hash_path(7); - db.update_element(0x0, VALUES[1]); - auto after = db.get_hash_path(7); - - EXPECT_EQ(before[0], after[0]); - EXPECT_EQ(before[1], after[1]); - EXPECT_NE(before[2], after[2]); - } -} - -TEST(crypto_merkle_tree, test_get_sibling_path_layers) -{ - { - MemoryStore store; - auto db = MerkleTree(store, 3); - - auto before = db.get_sibling_path(1); - db.update_element(0, VALUES[1]); - auto after = db.get_sibling_path(1); - - EXPECT_NE(before[0], after[0]); - EXPECT_EQ(before[1], after[1]); - EXPECT_EQ(before[2], after[2]); - } - - { - MemoryStore store; - auto db = MerkleTree(store, 3); - - auto before = db.get_sibling_path(7); - db.update_element(0x0, VALUES[1]); - auto after = db.get_sibling_path(7); - - EXPECT_EQ(before[0], after[0]); - EXPECT_EQ(before[1], after[1]); - EXPECT_NE(before[2], after[2]); - } -} diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.cpp deleted file mode 100644 index 61717f145f11..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } -// external_1: { status: not started, auditors: [], commit: } -// external_2: { status: not started, auditors: [], commit: } -// ===================== - -#include "nullifier_tree.hpp" -#include "../hash.hpp" -#include "../memory_store.hpp" -#include "../merkle_tree.hpp" -#include "barretenberg/common/assert.hpp" -#include "barretenberg/common/net.hpp" -#include "barretenberg/numeric/bitop/count_leading_zeros.hpp" -#include "barretenberg/numeric/bitop/keep_n_lsb.hpp" -#include "barretenberg/numeric/uint128/uint128.hpp" -#include -#include - -namespace bb::crypto::merkle_tree { - -template -NullifierTree::NullifierTree(Store& store, size_t depth, size_t initial_size, uint8_t tree_id) - : MerkleTree(store, depth, tree_id) -{ - BB_ASSERT_GTE(depth_, 1U); - BB_ASSERT_LTE(depth, 256U); - BB_ASSERT_GT(initial_size, 0U); - zero_hashes_.resize(depth); - - // Create the zero hashes for the tree - auto current = fr::zero(); - for (size_t i = 0; i < depth; ++i) { - zero_hashes_[i] = current; - current = HashingPolicy::hash_pair(current, current); - } - - // Insert the initial leaves - for (size_t i = 0; i < initial_size; i++) { - auto initial_leaf = WrappedNullifierLeaf( - indexed_nullifier_leaf{ .value = i, .nextIndex = i + 1, .nextValue = i + 1 }); - leaves.push_back(initial_leaf); - } - - leaves[initial_size - 1] = WrappedNullifierLeaf( - indexed_nullifier_leaf{ .value = leaves[initial_size - 1].unwrap().value, .nextIndex = 0, .nextValue = 0 }); - - for (size_t i = 0; i < initial_size; ++i) { - update_element(i, leaves[i].hash()); - } -} - -template -NullifierTree::NullifierTree(NullifierTree&& other) - : MerkleTree(std::move(other)) -{} - -template NullifierTree::~NullifierTree() {} - -template -fr NullifierTree::update_element(fr const& value) -{ - // Find the leaf with the value closest and less than `value` - size_t current; - bool is_already_present; - std::tie(current, is_already_present) = find_closest_leaf(leaves, value); - - indexed_nullifier_leaf current_leaf = leaves[current].unwrap(); - WrappedNullifierLeaf new_leaf = WrappedNullifierLeaf( - { .value = value, .nextIndex = current_leaf.nextIndex, .nextValue = current_leaf.nextValue }); - if (!is_already_present) { - // Update the current leaf to point it to the new leaf - current_leaf.nextIndex = leaves.size(); - current_leaf.nextValue = value; - - leaves[current].set(current_leaf); - - // Insert the new leaf with (nextIndex, nextValue) of the current leaf - leaves.push_back(new_leaf); - } - - // Update the old leaf in the tree - auto old_leaf_hash = leaves[current].hash(); - index_t old_leaf_index = current; - auto r = update_element(old_leaf_index, old_leaf_hash); - - // Insert the new leaf in the tree - auto new_leaf_hash = new_leaf.hash(); - index_t new_leaf_index = is_already_present ? old_leaf_index : leaves.size() - 1; - r = update_element(new_leaf_index, new_leaf_hash); - - return r; -} - -template class NullifierTree; - -} // namespace bb::crypto::merkle_tree diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.hpp deleted file mode 100644 index 45149098be3a..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } -// external_1: { status: not started, auditors: [], commit: } -// external_2: { status: not started, auditors: [], commit: } -// ===================== - -#pragma once -#include "../hash.hpp" -#include "../merkle_tree.hpp" -#include "nullifier_leaf.hpp" - -namespace bb::crypto::merkle_tree { - -template class NullifierTree : public MerkleTree { - public: - typedef uint256_t index_t; - - NullifierTree(Store& store, size_t depth, size_t initial_size = 1, uint8_t tree_id = 0); - NullifierTree(NullifierTree const& other) = delete; - NullifierTree(NullifierTree&& other); - ~NullifierTree(); - - using MerkleTree::get_hash_path; - using MerkleTree::root; - using MerkleTree::size; - using MerkleTree::depth; - - fr update_element(fr const& value); - - private: - using MerkleTree::update_element; - using MerkleTree::get_element; - using MerkleTree::compute_zero_path_hash; - - private: - using MerkleTree::store_; - using MerkleTree::zero_hashes_; - using MerkleTree::depth_; - using MerkleTree::tree_id_; - std::vector> leaves; -}; - -} // namespace bb::crypto::merkle_tree diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.test.cpp deleted file mode 100644 index 63622db56430..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_tree.test.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "nullifier_tree.hpp" -#include "../memory_store.hpp" -#include "barretenberg/common/streams.hpp" -#include "barretenberg/common/test.hpp" -#include "barretenberg/numeric/random/engine.hpp" -#include "nullifier_memory_tree.hpp" - -using namespace bb; -using namespace bb::crypto::merkle_tree; - -namespace { -auto& engine = numeric::get_debug_randomness(); -auto& random_engine = numeric::get_randomness(); -} // namespace - -const size_t NUM_VALUES = 1024; -static std::vector VALUES = []() { - std::vector values(NUM_VALUES); - for (size_t i = 0; i < NUM_VALUES; ++i) { - values[i] = fr(random_engine.get_random_uint256()); - } - return values; -}(); - -inline void print_tree(const size_t depth, std::vector hashes, std::string const& msg) -{ - info("\n", msg); - size_t offset = 0; - for (size_t i = 0; i < depth; i++) { - info("i = ", i); - size_t layer_size = (1UL << (depth - i)); - for (size_t j = 0; j < layer_size; j++) { - info("j = ", j, ": ", hashes[offset + j]); - } - offset += layer_size; - } -} - -TEST(stdlib_nullifier_tree, test_kv_memory_vs_memory_consistency) -{ - constexpr size_t depth = 2; - constexpr size_t prefill = 2; - NullifierMemoryTree memdb(depth, prefill); - - MemoryStore store; - NullifierTree db(store, depth, prefill); - - EXPECT_EQ(db.root(), memdb.root()); - - std::vector indicies((1 << depth) - prefill); - std::iota(indicies.begin(), indicies.end(), 0); - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(indicies.begin(), indicies.end(), g); - - for (size_t i = 0; i < indicies.size(); ++i) { - size_t idx = indicies[i]; - memdb.update_element(VALUES[idx]); - db.update_element(VALUES[idx]); - } - - for (size_t i = 0; i < indicies.size(); ++i) { - size_t idx = indicies[i]; - EXPECT_EQ(db.get_hash_path(idx), memdb.get_hash_path(idx)); - } - - EXPECT_EQ(db.root(), memdb.root()); -} - -TEST(stdlib_nullifier_tree, test_size) -{ - MemoryStore store; - auto db = NullifierTree(store, 256); - - // We assume that the first leaf is already filled with (0, 0, 0). - EXPECT_EQ(db.size(), 1ULL); - - // Add a new non-zero leaf at index 1. - db.update_element(30); - EXPECT_EQ(db.size(), 2ULL); - - // Add third. - db.update_element(10); - EXPECT_EQ(db.size(), 3ULL); - - // Add forth. - db.update_element(20); - EXPECT_EQ(db.size(), 4ULL); - - // Add forth but with same value. - db.update_element(20); - EXPECT_EQ(db.size(), 4ULL); -} - -TEST(stdlib_nullifier_tree, test_get_hash_path) -{ - NullifierMemoryTree memdb(10, 2); - - MemoryStore store; - auto db = NullifierTree(store, 10, 2); - - EXPECT_EQ(memdb.get_hash_path(512), db.get_hash_path(512)); - - memdb.update_element(VALUES[512]); - db.update_element(VALUES[512]); - - EXPECT_EQ(db.get_hash_path(512), memdb.get_hash_path(512)); - - for (size_t i = 0; i < 512; ++i) { - memdb.update_element(VALUES[i]); - db.update_element(VALUES[i]); - } - - EXPECT_EQ(db.get_hash_path(512), memdb.get_hash_path(512)); -} - -TEST(stdlib_nullifier_tree, test_get_hash_path_layers) -{ - { - MemoryStore store; - auto db = NullifierTree(store, 3); - - auto before = db.get_hash_path(1); - db.update_element(VALUES[1]); - auto after = db.get_hash_path(1); - - EXPECT_NE(before[0], after[0]); - EXPECT_NE(before[1], after[1]); - EXPECT_NE(before[2], after[2]); - } - - { - MemoryStore store; - auto db = NullifierTree(store, 3); - - auto before = db.get_hash_path(7); - db.update_element(VALUES[1]); - auto after = db.get_hash_path(7); - - EXPECT_EQ(before[0], after[0]); - EXPECT_EQ(before[1], after[1]); - EXPECT_NE(before[2], after[2]); - } -} diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 265ba9591cad..c7d718f36dee 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -3,8 +3,6 @@ #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/common/bb_bench.hpp" #include "barretenberg/crypto/ecdsa/ecdsa.hpp" -#include "barretenberg/crypto/merkle_tree/memory_store.hpp" -#include "barretenberg/crypto/merkle_tree/merkle_tree.hpp" #include "barretenberg/flavor/mega_flavor.hpp" #include "barretenberg/goblin/goblin.hpp" #include "barretenberg/srs/global_crs.hpp" From 605af967df27e8eca52015bd60ced2ca0b029ff5 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 19:29:20 +0000 Subject: [PATCH 03/10] remove more completely unused --- .../content_addressed_indexed_tree.test.cpp | 17 +++- .../merkle_tree/indexed_tree/fixtures.hpp | 22 ----- .../crypto/merkle_tree/memory_store.hpp | 93 ------------------- .../vm2/simulation/gadgets/sha256.test.cpp | 1 - 4 files changed, 16 insertions(+), 117 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/fixtures.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_store.hpp diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.test.cpp index 8d9166879d80..e4d29a7f92d8 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.test.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.test.cpp @@ -4,7 +4,6 @@ #include "../node_store/array_store.hpp" #include "../nullifier_tree/nullifier_memory_tree.hpp" #include "../test_fixtures.hpp" -#include "./fixtures.hpp" #include "barretenberg/common/streams.hpp" #include "barretenberg/common/test.hpp" #include "barretenberg/common/thread_pool.hpp" @@ -38,6 +37,22 @@ using PublicDataTreeType = ContentAddressedIndexedTree; +using IndexedPublicDataLeafType = IndexedLeaf; + +inline IndexedNullifierLeafType create_indexed_nullifier_leaf(const fr& value, index_t nextIndex, const fr& nextValue) +{ + return IndexedNullifierLeafType{ NullifierLeafValue(value), nextIndex, nextValue }; +} + +inline IndexedPublicDataLeafType create_indexed_public_data_leaf(const fr& slot, + const fr& value, + index_t nextIndex, + const fr& nextValue) +{ + return IndexedPublicDataLeafType{ PublicDataLeafValue(slot, value), nextIndex, nextValue }; +} + class PersistedContentAddressedIndexedTreeTest : public testing::Test { protected: void SetUp() override diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/fixtures.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/fixtures.hpp deleted file mode 100644 index 77669b481525..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/fixtures.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "../types.hpp" -#include "barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp" - -namespace bb::crypto::merkle_tree { -using IndexedNullifierLeafType = IndexedLeaf; -using IndexedPublicDataLeafType = IndexedLeaf; - -inline IndexedNullifierLeafType create_indexed_nullifier_leaf(const fr& value, index_t nextIndex, const fr& nextValue) -{ - return IndexedNullifierLeafType{ NullifierLeafValue(value), nextIndex, nextValue }; -} - -inline IndexedPublicDataLeafType create_indexed_public_data_leaf(const fr& slot, - const fr& value, - index_t nextIndex, - const fr& nextValue) -{ - return IndexedPublicDataLeafType{ PublicDataLeafValue(slot, value), nextIndex, nextValue }; -} -} // namespace bb::crypto::merkle_tree diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_store.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_store.hpp deleted file mode 100644 index ecdbafc5a8fa..000000000000 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_store.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } -// external_1: { status: not started, auditors: [], commit: } -// external_2: { status: not started, auditors: [], commit: } -// ===================== - -#pragma once -#include "barretenberg/common/streams.hpp" -#include "hash_path.hpp" -#include -#include - -namespace bb::crypto::merkle_tree { - -class MemoryStore { - public: - MemoryStore() {} - - MemoryStore(MemoryStore const& rhs) = default; - MemoryStore(MemoryStore&& rhs) = default; - MemoryStore& operator=(MemoryStore const& rhs) = default; - MemoryStore& operator=(MemoryStore&& rhs) = default; - - bool put(std::vector const& key, std::vector const& value) - { - auto key_str = to_string(key); - return put(key_str, value); - } - - bool put(std::string const& key, std::vector const& value) - { - puts_[key] = to_string(value); - deletes_.erase(key); - return true; - } - - bool del(std::vector const& key) - { - auto key_str = to_string(key); - puts_.erase(key_str); - deletes_.insert(key_str); - return true; - }; - - bool get(std::vector const& key, std::vector& value) { return get(to_string(key), value); } - - bool get(std::string const& key, std::vector& value) - { - if (deletes_.find(key) != deletes_.end()) { - return false; - } - auto it = puts_.find(key); - if (it != puts_.end()) { - value = std::vector(it->second.begin(), it->second.end()); - return true; - } else { - std::string result; - auto it = store_.find(key); - if (it != store_.end()) { - value = { it->second.begin(), it->second.end() }; - return true; - } - return false; - } - } - - void commit() - { - for (auto it : puts_) { - store_.insert(it); - } - for (auto key : deletes_) { - store_.erase(key); - } - puts_.clear(); - deletes_.clear(); - } - - void rollback() - { - puts_.clear(); - deletes_.clear(); - } - - private: - std::string to_string(std::vector const& input) { return std::string((char*)input.data(), input.size()); } - - std::map store_; - std::map puts_; - std::set deletes_; -}; - -} // namespace bb::crypto::merkle_tree diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/sha256.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/sha256.test.cpp index cae3e61540b3..86d0ca966e95 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/sha256.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/gadgets/sha256.test.cpp @@ -3,7 +3,6 @@ #include #include -#include "barretenberg/crypto/merkle_tree/memory_store.hpp" #include "barretenberg/vm2/common/memory_types.hpp" #include "barretenberg/vm2/simulation/events/event_emitter.hpp" #include "barretenberg/vm2/simulation/events/memory_event.hpp" From 9390cf34570d4976314e66f9d11fecc5f162240a Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 20:07:17 +0000 Subject: [PATCH 04/10] update scope --- .../audit_scopes/merkle_tree_audit_scope.md | 93 ++--- .../indexed_tree/indexed_tree.test.cpp | 331 ------------------ 2 files changed, 50 insertions(+), 374 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/stdlib/merkle_tree/indexed_tree/indexed_tree.test.cpp diff --git a/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md b/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md index dbb604661061..b195b3963382 100644 --- a/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md +++ b/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md @@ -6,59 +6,66 @@ Commit hash: TBD (link) ## Files to Audit Note: Paths relative to `aztec-packages/barretenberg/cpp/src/barretenberg` -### Core Merkle Tree Implementation -1. `crypto/merkle_tree/merkle_tree.hpp` -2. `crypto/merkle_tree/memory_tree.hpp` -3. `crypto/merkle_tree/hash.hpp` -4. `crypto/merkle_tree/hash_path.hpp` -5. `crypto/merkle_tree/types.hpp` -6. `crypto/merkle_tree/index.hpp` -7. `crypto/merkle_tree/response.hpp` -8. `crypto/merkle_tree/signal.hpp` - -### Storage Implementations -9. `crypto/merkle_tree/memory_store.hpp` -10. `crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp` -11. `crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp` - -### Node Store -12. `crypto/merkle_tree/node_store/array_store.hpp` -13. `crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp` -14. `crypto/merkle_tree/node_store/content_addressed_cache.hpp` -15. `crypto/merkle_tree/node_store/tree_meta.hpp` +### Core Types and Utilities +1. `crypto/merkle_tree/types.hpp` +2. `crypto/merkle_tree/hash.hpp` +3. `crypto/merkle_tree/hash_path.hpp` +4. `crypto/merkle_tree/response.hpp` +5. `crypto/merkle_tree/signal.hpp` + +### Storage Layer +6. `crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp` +7. `crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp` + +### Node Store (Cache + Metadata) +8. `crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp` +9. `crypto/merkle_tree/node_store/content_addressed_cache.hpp` +10. `crypto/merkle_tree/node_store/tree_meta.hpp` ### Append-Only Tree -16. `crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.hpp` +11. `crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.hpp` ### Indexed Tree -17. `crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp` -18. `crypto/merkle_tree/indexed_tree/indexed_leaf.hpp` -19. `crypto/merkle_tree/indexed_tree/fixtures.hpp` +12. `crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp` +13. `crypto/merkle_tree/indexed_tree/indexed_leaf.hpp` -### Nullifier Tree -20. `crypto/merkle_tree/nullifier_tree/nullifier_tree.cpp` -21. `crypto/merkle_tree/nullifier_tree/nullifier_tree.hpp` -22. `crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp` -23. `crypto/merkle_tree/nullifier_tree/nullifier_leaf.hpp` +## Summary of Module -### Test Fixtures -24. `crypto/merkle_tree/fixtures.hpp` -25. `crypto/merkle_tree/test_fixtures.hpp` +The `merkle_tree` module implements the persistent Merkle tree infrastructure for the Aztec protocol's world state. It provides two tree variants: append-only trees (used for NOTE_HASH_TREE, L1_TO_L2_MESSAGE_TREE, and ARCHIVE) and indexed trees (used for NULLIFIER_TREE and PUBLIC_DATA_TREE). Both use Poseidon2 hashing. -## Summary of Module +The storage architecture is two-layered: `ContentAddressedCachedTreeStore` wraps an in-memory cache (`ContentAddressedCache`) over a persistent LMDB backend (`LMDBTreeStore`). All tree operations are asynchronous, using thread pools and callback-based completion. The system supports block-level history, forking, checkpointing, and rollback for the world state managed by `world_state/`. -The `merkle_tree` module provides a comprehensive implementation of Merkle tree data structures for the Aztec protocol, including standard Merkle trees, append-only trees, indexed trees, and nullifier trees. The module supports multiple hash policies (Pedersen hash and Poseidon2) and provides both in-memory and persistent LMDB-backed storage options. The core implementation includes content-addressed storage with caching, allowing efficient tree operations and proof generation. The append-only tree implementation is optimized for sequential insertions, while the indexed tree maintains an ordered set of leaves with nullifier functionality. The nullifier tree is a specialized indexed tree used for tracking spent notes in the Aztec protocol. The module includes utilities for computing Merkle paths, tree roots, and managing tree metadata across multiple storage backends. +### Production usage chain + +``` +yarn-project (TypeScript) + → nodejs_module/world_state (NAPI bindings) + → WorldState (world_state/) + → Fork { FrTree, NullifierTree, PublicDataTree } + → ContentAddressedAppendOnlyTree / ContentAddressedIndexedTree + → ContentAddressedCachedTreeStore + → ContentAddressedCache (in-memory) + → LMDBTreeStore (persistent LMDB) +``` ## Test Files -1. `crypto/merkle_tree/merkle_tree.test.cpp` -2. `crypto/merkle_tree/memory_tree.test.cpp` -3. `crypto/merkle_tree/fixtures.test.cpp` -4. `crypto/merkle_tree/lmdb_store/lmdb_tree_store.test.cpp` -5. `crypto/merkle_tree/node_store/content_addressed_cache.test.cpp` -6. `crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.test.cpp` -7. `crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.test.cpp` -8. `crypto/merkle_tree/nullifier_tree/nullifier_tree.test.cpp` -9. `crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.test.cpp` +1. `crypto/merkle_tree/memory_tree.test.cpp` +2. `crypto/merkle_tree/fixtures.test.cpp` +3. `crypto/merkle_tree/lmdb_store/lmdb_tree_store.test.cpp` +4. `crypto/merkle_tree/node_store/content_addressed_cache.test.cpp` +5. `crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.test.cpp` +6. `crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.test.cpp` +7. `crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.test.cpp` + +### Test Infrastructure +Non-production code used for testing and benchmarking the production files above: + +- `crypto/merkle_tree/memory_tree.hpp` — Simple in-memory tree. Also used by vm2/simulation as a lightweight tree for AVM transaction execution. +- `crypto/merkle_tree/fixtures.hpp` — Test utility functions (random directories, values, thread pools). +- `crypto/merkle_tree/test_fixtures.hpp` — GTest assertion wrappers for tree state verification. +- `crypto/merkle_tree/node_store/array_store.hpp` — Lightweight in-memory store substitute for LMDB in tests/benchmarks. +- `crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp` — Reference implementation of an indexed nullifier tree, used for differential testing of `ContentAddressedIndexedTree`. +- `crypto/merkle_tree/nullifier_tree/nullifier_leaf.hpp` — Leaf types used by `nullifier_memory_tree.hpp`. ## Security Mechanisms None identified. diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merkle_tree/indexed_tree/indexed_tree.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/merkle_tree/indexed_tree/indexed_tree.test.cpp deleted file mode 100644 index d1dc13d95e52..000000000000 --- a/barretenberg/cpp/src/barretenberg/stdlib/merkle_tree/indexed_tree/indexed_tree.test.cpp +++ /dev/null @@ -1,331 +0,0 @@ -#include "indexed_tree.hpp" -#include "../array_store.hpp" -#include "../hash.hpp" -#include "../nullifier_tree/nullifier_memory_tree.hpp" -#include "barretenberg/common/streams.hpp" -#include "barretenberg/common/test.hpp" -#include "barretenberg/numeric/random/engine.hpp" -#include "leaves_cache.hpp" - -using namespace bb; -using namespace bb::crypto::merkle_tree; - -using HashPolicy = Poseidon2HashPolicy; - -namespace { -auto& engine = numeric::get_debug_randomness(); -auto& random_engine = numeric::get_randomness(); -} // namespace - -const size_t NUM_VALUES = 1024; -static std::vector VALUES = []() { - std::vector values(NUM_VALUES); - for (size_t i = 0; i < NUM_VALUES; ++i) { - values[i] = fr(random_engine.get_random_uint256()); - } - return values; -}(); - -TEST(stdlib_indexed_tree, can_create) -{ - ArrayStore store(10); - IndexedTree tree = IndexedTree(store, 10); - EXPECT_EQ(tree.size(), 1ULL); - - NullifierMemoryTree memdb(10); - EXPECT_EQ(memdb.root(), tree.root()); -} - -TEST(stdlib_indexed_tree, test_size) -{ - ArrayStore store(32); - auto db = IndexedTree(store, 32); - - // We assume that the first leaf is already filled with (0, 0, 0). - EXPECT_EQ(db.size(), 1ULL); - - // Add a new non-zero leaf at index 1. - db.add_value(30); - EXPECT_EQ(db.size(), 2ULL); - - // Add third. - db.add_value(10); - EXPECT_EQ(db.size(), 3ULL); - - // Add forth. - db.add_value(20); - EXPECT_EQ(db.size(), 4ULL); -} - -TEST(stdlib_indexed_tree, test_get_hash_path) -{ - NullifierMemoryTree memdb(10); - - ArrayStore store(10); - auto db = IndexedTree(store, 10); - - EXPECT_EQ(memdb.root(), db.root()); - - EXPECT_EQ(memdb.get_hash_path(0), db.get_hash_path(0)); - - memdb.update_element(VALUES[512]); - db.add_value(VALUES[512]); - - EXPECT_EQ(db.get_hash_path(0), memdb.get_hash_path(0)); - - for (size_t i = 0; i < 512; ++i) { - memdb.update_element(VALUES[i]); - db.add_value(VALUES[i]); - } - - EXPECT_EQ(db.get_hash_path(512), memdb.get_hash_path(512)); -} - -TEST(stdlib_indexed_tree, test_batch_insert) -{ - const size_t batch_size = 16; - const size_t num_batches = 16; - size_t depth = 10; - NullifierMemoryTree memdb(depth, batch_size); - - ArrayStore store1(depth); - IndexedTree tree1 = - IndexedTree(store1, depth, batch_size); - - ArrayStore store2(depth); - IndexedTree tree2 = - IndexedTree(store2, depth, batch_size); - - EXPECT_EQ(memdb.root(), tree1.root()); - EXPECT_EQ(tree1.root(), tree2.root()); - - EXPECT_EQ(memdb.get_hash_path(0), tree1.get_hash_path(0)); - EXPECT_EQ(tree1.get_hash_path(0), tree2.get_hash_path(0)); - - EXPECT_EQ(memdb.get_hash_path(512), tree1.get_hash_path(512)); - EXPECT_EQ(tree1.get_hash_path(512), tree2.get_hash_path(512)); - - for (size_t i = 0; i < num_batches; i++) { - std::vector batch; - std::vector memory_tree_hash_paths; - for (size_t j = 0; j < batch_size; j++) { - batch.push_back(fr(random_engine.get_random_uint256())); - fr_hash_path path = memdb.update_element(batch[j]); - memory_tree_hash_paths.push_back(path); - } - std::vector tree1_hash_paths = tree1.add_or_update_values(batch, true); - std::vector tree2_hash_paths = tree2.add_or_update_values(batch); - EXPECT_EQ(memdb.root(), tree1.root()); - EXPECT_EQ(tree1.root(), tree2.root()); - - EXPECT_EQ(memdb.get_hash_path(0), tree1.get_hash_path(0)); - EXPECT_EQ(tree1.get_hash_path(0), tree2.get_hash_path(0)); - - EXPECT_EQ(memdb.get_hash_path(512), tree1.get_hash_path(512)); - EXPECT_EQ(tree1.get_hash_path(512), tree2.get_hash_path(512)); - - for (size_t j = 0; j < batch_size; j++) { - EXPECT_EQ(tree1_hash_paths[j], tree2_hash_paths[j]); - // EXPECT_EQ(tree1_hash_paths[j], memory_tree_hash_paths[j]); - } - } -} - -fr hash_leaf(const indexed_leaf& leaf) -{ - return HashPolicy::hash(leaf.get_hash_inputs()); -} - -bool check_hash_path(const fr& root, const fr_hash_path& path, const indexed_leaf& leaf_value, const size_t idx) -{ - auto current = hash_leaf(leaf_value); - size_t depth_ = path.size(); - size_t index = idx; - for (size_t i = 0; i < depth_; ++i) { - fr left = (index & 1) ? path[i].first : current; - fr right = (index & 1) ? current : path[i].second; - current = HashPolicy::hash_pair(left, right); - index >>= 1; - } - return current == root; -} - -TEST(stdlib_indexed_tree, test_indexed_memory) -{ - // Create a depth-3 indexed merkle tree - constexpr size_t depth = 3; - ArrayStore store(depth); - IndexedTree tree = - IndexedTree(store, depth, 1); - - /** - * Intial state: - * - * index 0 1 2 3 4 5 6 7 - * --------------------------------------------------------------------- - * val 0 0 0 0 0 0 0 0 - * nextIdx 0 0 0 0 0 0 0 0 - * nextVal 0 0 0 0 0 0 0 0 - */ - indexed_leaf zero_leaf = { 0, 0, 0 }; - EXPECT_EQ(tree.size(), 1); - EXPECT_EQ(tree.get_leaf(0), zero_leaf); - - /** - * Add new value 30: - * - * index 0 1 2 3 4 5 6 7 - * --------------------------------------------------------------------- - * val 0 30 0 0 0 0 0 0 - * nextIdx 1 0 0 0 0 0 0 0 - * nextVal 30 0 0 0 0 0 0 0 - */ - tree.add_value(30); - EXPECT_EQ(tree.size(), 2); - EXPECT_EQ(hash_leaf(tree.get_leaf(0)), hash_leaf({ 0, 1, 30 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(1)), hash_leaf({ 30, 0, 0 })); - - /** - * Add new value 10: - * - * index 0 1 2 3 4 5 6 7 - * --------------------------------------------------------------------- - * val 0 30 10 0 0 0 0 0 - * nextIdx 2 0 1 0 0 0 0 0 - * nextVal 10 0 30 0 0 0 0 0 - */ - tree.add_value(10); - EXPECT_EQ(tree.size(), 3); - EXPECT_EQ(hash_leaf(tree.get_leaf(0)), hash_leaf({ 0, 2, 10 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(1)), hash_leaf({ 30, 0, 0 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(2)), hash_leaf({ 10, 1, 30 })); - - /** - * Add new value 20: - * - * index 0 1 2 3 4 5 6 7 - * --------------------------------------------------------------------- - * val 0 30 10 20 0 0 0 0 - * nextIdx 2 0 3 1 0 0 0 0 - * nextVal 10 0 20 30 0 0 0 0 - */ - tree.add_value(20); - EXPECT_EQ(tree.size(), 4); - EXPECT_EQ(hash_leaf(tree.get_leaf(0)), hash_leaf({ 0, 2, 10 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(1)), hash_leaf({ 30, 0, 0 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(2)), hash_leaf({ 10, 3, 20 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(3)), hash_leaf({ 20, 1, 30 })); - - // Adding the same value must not affect anything - // tree.update_element(20); - // EXPECT_EQ(tree.get_leaves().size(), 4); - // EXPECT_EQ(tree.get_leaves()[0], hash_leaf({ 0, 2, 10 })); - // EXPECT_EQ(tree.get_leaves()[1], hash_leaf({ 30, 0, 0 })); - // EXPECT_EQ(tree.get_leaves()[2], hash_leaf({ 10, 3, 20 })); - // EXPECT_EQ(tree.get_leaves()[3], hash_leaf({ 20, 1, 30 })); - - /** - * Add new value 50: - * - * index 0 1 2 3 4 5 6 7 - * --------------------------------------------------------------------- - * val 0 30 10 20 50 0 0 0 - * nextIdx 2 4 3 1 0 0 0 0 - * nextVal 10 50 20 30 0 0 0 0 - */ - tree.add_value(50); - EXPECT_EQ(tree.size(), 5); - EXPECT_EQ(hash_leaf(tree.get_leaf(0)), hash_leaf({ 0, 2, 10 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(1)), hash_leaf({ 30, 4, 50 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(2)), hash_leaf({ 10, 3, 20 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(3)), hash_leaf({ 20, 1, 30 })); - EXPECT_EQ(hash_leaf(tree.get_leaf(4)), hash_leaf({ 50, 0, 0 })); - - // Manually compute the node values - auto e000 = hash_leaf(tree.get_leaf(0)); - auto e001 = hash_leaf(tree.get_leaf(1)); - auto e010 = hash_leaf(tree.get_leaf(2)); - auto e011 = hash_leaf(tree.get_leaf(3)); - auto e100 = hash_leaf(tree.get_leaf(4)); - auto e101 = hash_leaf({ 0, 0, 0 }); - auto e110 = hash_leaf({ 0, 0, 0 }); - auto e111 = hash_leaf({ 0, 0, 0 }); - - auto e00 = HashPolicy::hash_pair(e000, e001); - auto e01 = HashPolicy::hash_pair(e010, e011); - auto e10 = HashPolicy::hash_pair(e100, e101); - auto e11 = HashPolicy::hash_pair(e110, e111); - - auto e0 = HashPolicy::hash_pair(e00, e01); - auto e1 = HashPolicy::hash_pair(e10, e11); - auto root = HashPolicy::hash_pair(e0, e1); - - // Check the hash path at index 2 and 3 - // Note: This merkle proof would also serve as a non-membership proof of values in (10, 20) and (20, 30) - fr_hash_path expected = { - std::make_pair(e000, e001), - std::make_pair(e00, e01), - std::make_pair(e0, e1), - }; - EXPECT_EQ(tree.get_hash_path(0), expected); - EXPECT_EQ(tree.get_hash_path(1), expected); - fr_hash_path expected2 = { - std::make_pair(e010, e011), - std::make_pair(e00, e01), - std::make_pair(e0, e1), - }; - EXPECT_EQ(tree.get_hash_path(2), expected2); - EXPECT_EQ(tree.get_hash_path(3), expected2); - EXPECT_EQ(tree.root(), root); - - // Check the hash path at index 6 and 7 - expected = { - std::make_pair(e110, e111), - std::make_pair(e10, e11), - std::make_pair(e0, e1), - }; - EXPECT_EQ(tree.get_hash_path(6), expected); - EXPECT_EQ(tree.get_hash_path(7), expected); -} - -TEST(stdlib_indexed_tree, test_indexed_tree) -{ - // Create a depth-8 indexed merkle tree - constexpr size_t depth = 8; - ArrayStore store(depth); - IndexedTree tree = - IndexedTree(store, depth, 1); - - indexed_leaf zero_leaf = { 0, 0, 0 }; - EXPECT_EQ(tree.size(), 1); - EXPECT_EQ(hash_leaf(tree.get_leaf(0)), hash_leaf(zero_leaf)); - - // Add 20 random values to the tree - for (size_t i = 0; i < 20; i++) { - auto value = fr::random_element(); - tree.add_value(value); - } - - auto abs_diff = [](uint256_t a, uint256_t b) { - if (a > b) { - return (a - b); - } else { - return (b - a); - } - }; - - // Check if a new random value is not a member of this tree. - fr new_member = fr::random_element(); - std::vector differences; - for (size_t i = 0; i < size_t(tree.size()); i++) { - uint256_t diff_hi = abs_diff(uint256_t(new_member), uint256_t(tree.get_leaf(i).value)); - uint256_t diff_lo = abs_diff(uint256_t(new_member), uint256_t(tree.get_leaf(i).value)); - differences.push_back(diff_hi + diff_lo); - } - auto it = std::min_element(differences.begin(), differences.end()); - auto index = static_cast(it - differences.begin()); - - // Merkle proof at `index` proves non-membership of `new_member` - auto hash_path = tree.get_hash_path(index); - EXPECT_TRUE(check_hash_path(tree.root(), hash_path, tree.get_leaf(index), index)); -} \ No newline at end of file From 296f88625900f21d0bfee3c8adecadd37d281fe0 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 20:36:15 +0000 Subject: [PATCH 05/10] remove comment --- .../audit/audit_scopes/merkle_tree_audit_scope.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md b/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md index b195b3963382..44323f33605e 100644 --- a/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md +++ b/barretenberg/cpp/scripts/audit/audit_scopes/merkle_tree_audit_scope.md @@ -35,19 +35,6 @@ The `merkle_tree` module implements the persistent Merkle tree infrastructure fo The storage architecture is two-layered: `ContentAddressedCachedTreeStore` wraps an in-memory cache (`ContentAddressedCache`) over a persistent LMDB backend (`LMDBTreeStore`). All tree operations are asynchronous, using thread pools and callback-based completion. The system supports block-level history, forking, checkpointing, and rollback for the world state managed by `world_state/`. -### Production usage chain - -``` -yarn-project (TypeScript) - → nodejs_module/world_state (NAPI bindings) - → WorldState (world_state/) - → Fork { FrTree, NullifierTree, PublicDataTree } - → ContentAddressedAppendOnlyTree / ContentAddressedIndexedTree - → ContentAddressedCachedTreeStore - → ContentAddressedCache (in-memory) - → LMDBTreeStore (persistent LMDB) -``` - ## Test Files 1. `crypto/merkle_tree/memory_tree.test.cpp` 2. `crypto/merkle_tree/fixtures.test.cpp` From 1d8c48d86c61475684a67524b25ff190d123d979 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 20:49:47 +0000 Subject: [PATCH 06/10] remove dead methods --- .../merkle_tree/indexed_tree/indexed_leaf.hpp | 5 ---- .../lmdb_store/lmdb_tree_store.hpp | 25 ------------------- 2 files changed, 30 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp index 2d0a3ecbeb3b..70dc6f533efe 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp @@ -6,7 +6,6 @@ #pragma once -#include "barretenberg/common/utils.hpp" #include "barretenberg/crypto/merkle_tree/types.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/serialize/msgpack.hpp" @@ -68,8 +67,6 @@ struct NullifierLeafValue { static NullifierLeafValue padding(index_t i) { return { i }; } static std::string name() { return "NullifierLeafValue"; }; - - size_t hash() const noexcept { return std::hash{}(nullifier); } }; struct PublicDataLeafValue { @@ -130,8 +127,6 @@ struct PublicDataLeafValue { static PublicDataLeafValue padding(index_t i) { return { i, fr::zero() }; } static std::string name() { return "PublicDataLeafValue"; }; - - size_t hash() const noexcept { return utils::hash_as_tuple(value, slot); } }; template struct IndexedLeaf { diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp index f9829883ddcb..bfd7c01395de 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp @@ -77,17 +77,6 @@ struct BlockIndexPayload { block_number_t get_min_block_number() { return blockNumbers[0]; } - bool contains(const block_number_t& blockNumber) - { - if (is_empty()) { - return false; - } - if (blockNumbers.size() == 1) { - return blockNumbers[0] == blockNumber; - } - return blockNumber >= blockNumbers[0] && blockNumber <= blockNumbers[1]; - } - void delete_block(const block_number_t& blockNumber) { // Shouldn't be possible, but no need to do anything here @@ -224,20 +213,6 @@ class LMDBTreeStore : public LMDBStoreBase { void delete_leaf_by_hash(const fr& leafHash, WriteTransaction& tx); - void write_leaf_key_by_index(const fr& leafKey, const index_t& index, WriteTransaction& tx); - - template bool read_leaf_key_by_index(const index_t& index, fr& leafKey, TxType& tx); - - template - void read_all_leaf_keys_after_or_equal_index(const index_t& index, std::vector& leafKeys, TxType& tx); - - void delete_all_leaf_keys_after_or_equal_index(const index_t& index, WriteTransaction& tx); - - template - void read_all_leaf_keys_before_or_equal_index(const index_t& index, std::vector& leafKeys, TxType& tx); - - void delete_all_leaf_keys_before_or_equal_index(const index_t& index, WriteTransaction& tx); - private: std::string _name; LMDBDatabase::Ptr _blockDatabase; From 8f71293f4794c364e9fcefe0374f0406d95a3966 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 21:01:48 +0000 Subject: [PATCH 07/10] more dead methods --- .../crypto/merkle_tree/hash_path.hpp | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp index 69378f504b5d..d6e9694fc4ff 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp @@ -5,52 +5,19 @@ // ===================== #pragma once -#include "barretenberg/stdlib/primitives/field/field.hpp" #include "hash.hpp" -#include #include namespace bb::crypto::merkle_tree { using fr_hash_path = std::vector>; using fr_sibling_path = std::vector; -template using hash_path = std::vector, bb::stdlib::field_t>>; - -inline fr_hash_path get_random_hash_path(size_t const& tree_depth) -{ - fr_hash_path path; - for (size_t i = 0; i < tree_depth; ++i) { - path.push_back(std::make_pair(fr::random_element(), fr::random_element())); - } - return path; -} - -template inline hash_path create_witness_hash_path(Ctx& ctx, fr_hash_path const& input) -{ - hash_path result; - std::transform(input.begin(), input.end(), std::back_inserter(result), [&](auto const& v) { - return std::make_pair(bb::stdlib::field_t(bb::stdlib::witness_t(&ctx, v.first)), - bb::stdlib::field_t(bb::stdlib::witness_t(&ctx, v.second))); - }); - return result; -} } // namespace bb::crypto::merkle_tree // We add to std namespace as fr_hash_path is actually a std::vector, and this is the only way // to achieve effective ADL. namespace std { -template -inline std::ostream& operator<<(std::ostream& os, bb::crypto::merkle_tree::hash_path const& path) -{ - os << "[\n"; - for (size_t i = 0; i < path.size(); ++i) { - os << " (" << i << ": " << path[i].first << ", " << path[i].second << ")\n"; - } - os << "]\n"; - return os; -} - inline std::ostream& operator<<(std::ostream& os, bb::crypto::merkle_tree::fr_hash_path const& path) { os << "[\n"; From effed44f7e565d30994b8cce150f0f5821a45e7b Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 21:42:31 +0000 Subject: [PATCH 08/10] remove pedersen paraphernalia --- .../append_only_tree_bench/append_only_tree.bench.cpp | 1 - .../benchmark/indexed_tree_bench/indexed_tree.bench.cpp | 1 - .../cpp/src/barretenberg/crypto/merkle_tree/hash.hpp | 9 --------- .../barretenberg/crypto/merkle_tree/memory_tree.test.cpp | 2 +- .../nullifier_tree/nullifier_memory_tree.test.cpp | 2 +- 5 files changed, 2 insertions(+), 13 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/append_only_tree.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/append_only_tree.bench.cpp index cbbeb76cfe3d..ed54fd5debc5 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/append_only_tree.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/append_only_tree.bench.cpp @@ -21,7 +21,6 @@ using namespace bb::crypto::merkle_tree; namespace { using StoreType = ContentAddressedCachedTreeStore; -using Pedersen = ContentAddressedAppendOnlyTree; using Poseidon2 = ContentAddressedAppendOnlyTree; const size_t TREE_DEPTH = 32; diff --git a/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/indexed_tree.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/indexed_tree.bench.cpp index a388c30f1eae..ec649651882e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/indexed_tree.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/indexed_tree.bench.cpp @@ -18,7 +18,6 @@ using namespace bb::crypto::merkle_tree; using StoreType = ContentAddressedCachedTreeStore; using Poseidon2 = ContentAddressedIndexedTree; -using Pedersen = ContentAddressedIndexedTree; const size_t TREE_DEPTH = 40; const size_t MAX_BATCH_SIZE = 64; diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp index 755e92fa40b6..bbf56f87719b 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp @@ -5,20 +5,11 @@ // ===================== #pragma once -#include "barretenberg/crypto/pedersen_hash/pedersen.hpp" #include "barretenberg/crypto/poseidon2/poseidon2.hpp" #include namespace bb::crypto::merkle_tree { -struct PedersenHashPolicy { - static fr hash(const std::vector& inputs) { return crypto::pedersen_hash::hash(inputs); } - - static fr hash_pair(const fr& lhs, const fr& rhs) { return hash(std::vector({ lhs, rhs })); } - - static fr zero_hash() { return fr::zero(); } -}; - struct Poseidon2HashPolicy { static fr hash(const std::vector& inputs) { diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.test.cpp index 56cca4b03bc9..e38c420cdcfe 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.test.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.test.cpp @@ -4,7 +4,7 @@ using namespace bb; using namespace bb::crypto::merkle_tree; -using HashPolicy = PedersenHashPolicy; +using HashPolicy = Poseidon2HashPolicy; static std::vector VALUES = []() { std::vector values(4); diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.test.cpp index 77ad97982a1a..6ace67b4cb26 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.test.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.test.cpp @@ -4,7 +4,7 @@ using namespace bb; using namespace bb::crypto::merkle_tree; -using HashPolicy = PedersenHashPolicy; +using HashPolicy = Poseidon2HashPolicy; using WrappedLeaf = WrappedNullifierLeaf; void print_tree(const size_t depth, std::vector hashes, std::string const& msg) From 00438b45ea084484df53cf4c7b03f798a619afb2 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 21:46:47 +0000 Subject: [PATCH 09/10] update audit headers --- .../append_only_tree/content_addressed_append_only_tree.hpp | 2 +- barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp | 2 +- .../cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp | 2 +- .../merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp | 2 +- .../crypto/merkle_tree/indexed_tree/indexed_leaf.hpp | 2 +- .../crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp | 2 +- .../crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp | 2 +- .../cpp/src/barretenberg/crypto/merkle_tree/memory_tree.hpp | 2 +- .../barretenberg/crypto/merkle_tree/node_store/array_store.hpp | 2 +- .../node_store/cached_content_addressed_tree_store.hpp | 2 +- .../crypto/merkle_tree/node_store/content_addressed_cache.hpp | 2 +- .../barretenberg/crypto/merkle_tree/node_store/tree_meta.hpp | 2 +- .../crypto/merkle_tree/nullifier_tree/nullifier_leaf.hpp | 2 +- .../crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp | 2 +- .../cpp/src/barretenberg/crypto/merkle_tree/response.hpp | 2 +- barretenberg/cpp/src/barretenberg/crypto/merkle_tree/signal.hpp | 2 +- barretenberg/cpp/src/barretenberg/crypto/merkle_tree/types.hpp | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.hpp index 0a7eaf4d4905..b58aa1250645 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/append_only_tree/content_addressed_append_only_tree.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp index bbf56f87719b..371771eca23a 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp index d6e9694fc4ff..5282dfa7a8a4 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/hash_path.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp index 705c943b9d85..bccb48b65fe4 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/content_addressed_indexed_tree.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp index 70dc6f533efe..5634ad5ea911 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp index 6ecdc9ec1229..7328b0e377e6 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp index bfd7c01395de..4c2b54c1e31b 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.hpp index 263ddd261791..fe8dc8947e37 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/memory_tree.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/array_store.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/array_store.hpp index b9a634ccc702..3beafb369ce1 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/array_store.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/array_store.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp index d72d8686698f..f1f078e68a1e 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/cached_content_addressed_tree_store.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/content_addressed_cache.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/content_addressed_cache.hpp index 31fb0a37ae17..e9fa2bfcfaf2 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/content_addressed_cache.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/content_addressed_cache.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/tree_meta.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/tree_meta.hpp index a8fbd2b66724..3f5d82acb9d1 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/tree_meta.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/node_store/tree_meta.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_leaf.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_leaf.hpp index 8eaa792afc9f..45c0edf95816 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_leaf.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_leaf.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp index eece6597a861..af9cf855574e 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/response.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/response.hpp index 8aba60bfa249..5d7b4d898684 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/response.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/response.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/signal.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/signal.hpp index 87a2a67d56e1..4e8f9292122b 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/signal.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/signal.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/types.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/types.hpp index 810828277db6..ac344e221be2 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/types.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/types.hpp @@ -1,5 +1,5 @@ // === AUDIT STATUS === -// internal: { status: Planned, auditors: [Raju], commit: } +// internal: { status: Planned, auditors: [], commit: } // external_1: { status: not started, auditors: [], commit: } // external_2: { status: not started, auditors: [], commit: } // ===================== From 48b219cfacfa5341a41dc91746bd145353626b8f Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 18 Feb 2026 23:12:27 +0000 Subject: [PATCH 10/10] fix build --- .../crypto/merkle_tree/indexed_tree/indexed_leaf.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp index 5634ad5ea911..ade20dad2db8 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp @@ -6,6 +6,7 @@ #pragma once +#include "barretenberg/common/utils.hpp" #include "barretenberg/crypto/merkle_tree/types.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/serialize/msgpack.hpp" @@ -66,6 +67,8 @@ struct NullifierLeafValue { static NullifierLeafValue padding(index_t i) { return { i }; } + size_t hash() const noexcept { return std::hash{}(nullifier); } + static std::string name() { return "NullifierLeafValue"; }; }; @@ -126,6 +129,8 @@ struct PublicDataLeafValue { static PublicDataLeafValue padding(index_t i) { return { i, fr::zero() }; } + size_t hash() const noexcept { return utils::hash_as_tuple(value, slot); } + static std::string name() { return "PublicDataLeafValue"; }; };