From d874501b9f9daaf0b5ecf8e5d48d2f0206a8f0f0 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+cheethas@users.noreply.github.com> Date: Mon, 3 Apr 2023 07:47:54 -0700 Subject: [PATCH] feat(memory_tree|a3): add sibling path calculations (#301) * feat(memory_tree): frontier paths * fix: sibling path rename, nullifier tree -> protected vars * clean * test: sibling path test --------- Co-authored-by: cheethas --- .../stdlib/merkle_tree/hash_path.hpp | 1 + .../stdlib/merkle_tree/memory_tree.cpp | 18 +++++++++ .../stdlib/merkle_tree/memory_tree.hpp | 2 + .../stdlib/merkle_tree/memory_tree.test.cpp | 37 ++++++++++++++++++- .../nullifier_tree/nullifier_leaf.hpp | 3 +- .../nullifier_tree/nullifier_memory_tree.hpp | 3 +- 6 files changed, 61 insertions(+), 3 deletions(-) diff --git a/cpp/src/barretenberg/stdlib/merkle_tree/hash_path.hpp b/cpp/src/barretenberg/stdlib/merkle_tree/hash_path.hpp index d47ceb6ffc..e6e5bfcdf6 100644 --- a/cpp/src/barretenberg/stdlib/merkle_tree/hash_path.hpp +++ b/cpp/src/barretenberg/stdlib/merkle_tree/hash_path.hpp @@ -11,6 +11,7 @@ namespace merkle_tree { using namespace barretenberg; typedef std::vector> fr_hash_path; +typedef std::vector fr_sibling_path; template using hash_path = std::vector, field_t>>; inline fr_hash_path get_new_hash_path(fr_hash_path const& old_path, uint128_t index, fr const& value) diff --git a/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.cpp b/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.cpp index a5498a49a5..a1d38e7092 100644 --- a/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.cpp +++ b/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.cpp @@ -40,6 +40,24 @@ fr_hash_path MemoryTree::get_hash_path(size_t index) return path; } +fr_sibling_path MemoryTree::get_sibling_path(size_t index) +{ + fr_sibling_path path(depth_); + size_t offset = 0; + size_t layer_size = total_size_; + for (size_t i = 0; i < depth_; i++) { + if (index % 2 == 0) { + path[i] = hashes_[offset + index + 1]; + } else { + path[i] = hashes_[offset + index - 1]; + } + offset += layer_size; + layer_size >>= 1; + index >>= 1; + } + return path; +} + fr MemoryTree::update_element(size_t index, fr const& value) { size_t offset = 0; diff --git a/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.hpp b/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.hpp index ce638d92a0..ac1b6bd0bf 100644 --- a/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.hpp +++ b/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.hpp @@ -30,6 +30,8 @@ class MemoryTree { fr_hash_path get_hash_path(size_t index); + fr_sibling_path get_sibling_path(size_t index); + fr update_element(size_t index, fr const& value); fr root() const { return root_; } diff --git a/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.test.cpp b/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.test.cpp index 904fe41b16..2b91a36b59 100644 --- a/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.test.cpp +++ b/cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.test.cpp @@ -1,6 +1,5 @@ #include "memory_tree.hpp" #include -#include "barretenberg/stdlib/types/types.hpp" using namespace barretenberg; using namespace proof_system::plonk::stdlib::merkle_tree; @@ -43,3 +42,39 @@ TEST(stdlib_merkle_tree, test_memory_store) EXPECT_EQ(db.get_hash_path(3), expected); EXPECT_EQ(db.root(), root); } + +TEST(stdlib_merkle_tree, test_memory_store_sibling_path) +{ + fr e00 = 0; + fr e01 = VALUES[1]; + fr e02 = VALUES[2]; + fr e03 = VALUES[3]; + fr e10 = hash_pair_native(e00, e01); + fr e11 = hash_pair_native(e02, e03); + fr root = hash_pair_native(e10, e11); + + MemoryTree db(2); + for (size_t i = 0; i < 4; ++i) { + db.update_element(i, VALUES[i]); + } + + // Check correct paths are generated for each layer 0 element + fr_sibling_path expected00 = { + e01, + e11, + }; + fr_sibling_path expected01 = { e00, e11 }; + fr_sibling_path expected02 = { + e03, + e10, + }; + fr_sibling_path expected03 = { + e02, + e10, + }; + EXPECT_EQ(db.get_sibling_path(0), expected00); + EXPECT_EQ(db.get_sibling_path(1), expected01); + EXPECT_EQ(db.get_sibling_path(2), expected02); + EXPECT_EQ(db.get_sibling_path(3), expected03); + EXPECT_EQ(db.root(), root); +} diff --git a/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_leaf.hpp b/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_leaf.hpp index d94c6638a0..03a6a25d91 100644 --- a/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_leaf.hpp +++ b/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_leaf.hpp @@ -44,9 +44,10 @@ inline std::pair find_closest_leaf(std::vector con { std::vector diff; bool repeated = false; + auto new_value_ = uint256_t(new_value); + for (size_t i = 0; i < leaves_.size(); i++) { auto leaf_value_ = uint256_t(leaves_[i].value); - auto new_value_ = uint256_t(new_value); if (leaf_value_ > new_value_) { diff.push_back(leaf_value_); } else if (leaf_value_ == new_value_) { diff --git a/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp b/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp index 3b49fc19bd..6fc273675b 100644 --- a/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp +++ b/cpp/src/barretenberg/stdlib/merkle_tree/nullifier_tree/nullifier_memory_tree.hpp @@ -79,8 +79,9 @@ class NullifierMemoryTree : public MemoryTree { const std::vector& get_hashes() { return hashes_; } const std::vector& get_leaves() { return leaves_; } + const nullifier_leaf& get_leaf(size_t index) { return leaves_[index]; } - private: + protected: using MemoryTree::depth_; using MemoryTree::hashes_; using MemoryTree::root_;