diff --git a/src/fcmp/curve_trees.h b/src/fcmp/curve_trees.h index a841c41e3..7bcdb139e 100644 --- a/src/fcmp/curve_trees.h +++ b/src/fcmp/curve_trees.h @@ -133,9 +133,9 @@ public: crypto::derive_key_image_generator(O, I); return LeafTuple{ - .O_x = m_c2.ed_25519_point_to_scalar(O), - .I_x = m_c2.ed_25519_point_to_scalar(I), - .C_x = m_c2.ed_25519_point_to_scalar(C) + .O_x = fcmp::tower_cycle::ed_25519_point_to_scalar(O), + .I_x = fcmp::tower_cycle::ed_25519_point_to_scalar(I), + .C_x = fcmp::tower_cycle::ed_25519_point_to_scalar(C) }; }; @@ -265,8 +265,7 @@ private: fcmp::tower_cycle::extend_zeroes(curve, new_children.size(), prior_children); return curve.hash_grow( - curve.GENERATORS, - curve.HASH_INIT_POINT, + curve.m_hash_init_point, 0,/*offset*/ typename C::Chunk{prior_children.data(), prior_children.size()}, new_children @@ -286,7 +285,6 @@ private: fcmp::tower_cycle::extend_zeroes(m_c2, new_children.size(), prior_children); return m_c2.hash_grow( - m_c2.GENERATORS, last_chunk_ptr->last_parent, last_chunk_ptr->child_offset, typename C2::Chunk{prior_children.data(), prior_children.size()}, @@ -333,7 +331,6 @@ private: } return curve.hash_grow( - curve.GENERATORS, last_chunk_ptr->last_parent, offset, typename C::Chunk{prior_children.data(), prior_children.size()}, @@ -505,6 +502,7 @@ private: } } +//member variables private: const C1 &m_c1; const C2 &m_c2; diff --git a/src/fcmp/tower_cycle.cpp b/src/fcmp/tower_cycle.cpp index e90125667..a44bc5f15 100644 --- a/src/fcmp/tower_cycle.cpp +++ b/src/fcmp/tower_cycle.cpp @@ -26,28 +26,125 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "string_tools.h" #include "tower_cycle.h" namespace fcmp { namespace tower_cycle { - -namespace helios -{ //---------------------------------------------------------------------------------------------------------------------- -SeleneScalar Helios::point_to_cycle_scalar(const Helios::Point &point) const +//---------------------------------------------------------------------------------------------------------------------- +Helios::CycleScalar Helios::point_to_cycle_scalar(const Helios::Point &point) const { return fcmp_rust::helios_point_to_selene_scalar(point); -}; +} //---------------------------------------------------------------------------------------------------------------------- -} //namespace helios -//---------------------------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------------------------- -namespace selene +Selene::CycleScalar Selene::point_to_cycle_scalar(const Selene::Point &point) const { + return fcmp_rust::selene_point_to_helios_scalar(point); +} //---------------------------------------------------------------------------------------------------------------------- -SeleneScalar Selene::ed_25519_point_to_scalar(const crypto::ec_point &point) const +Helios::Point Helios::hash_grow( + const Helios::Point &existing_hash, + const std::size_t offset, + const Helios::Chunk &prior_children, + const Helios::Chunk &new_children) const +{ + return fcmp_rust::hash_grow_helios( + m_generators, + existing_hash, + offset, + prior_children, + new_children); +} +//---------------------------------------------------------------------------------------------------------------------- +Selene::Point Selene::hash_grow( + const Selene::Point &existing_hash, + const std::size_t offset, + const Selene::Chunk &prior_children, + const Selene::Chunk &new_children) const +{ + return fcmp_rust::hash_grow_selene( + m_generators, + existing_hash, + offset, + prior_children, + new_children); +} +//---------------------------------------------------------------------------------------------------------------------- +Helios::Scalar Helios::clone(const Helios::Scalar &scalar) const +{ + return fcmp_rust::clone_helios_scalar(scalar); +} +//---------------------------------------------------------------------------------------------------------------------- +Selene::Scalar Selene::clone(const Selene::Scalar &scalar) const +{ + return fcmp_rust::clone_selene_scalar(scalar); +} +//---------------------------------------------------------------------------------------------------------------------- +Helios::Point Helios::clone(const Helios::Point &point) const +{ + return fcmp_rust::clone_helios_point(point); +} +//---------------------------------------------------------------------------------------------------------------------- +Selene::Point Selene::clone(const Selene::Point &point) const +{ + return fcmp_rust::clone_selene_point(point); +} +//---------------------------------------------------------------------------------------------------------------------- +Helios::Scalar Helios::zero_scalar() const +{ + return fcmp_rust::helios_zero_scalar(); +} +//---------------------------------------------------------------------------------------------------------------------- +Selene::Scalar Selene::zero_scalar() const +{ + return fcmp_rust::selene_zero_scalar(); +} +//---------------------------------------------------------------------------------------------------------------------- +std::array Helios::to_bytes(const Helios::Scalar &scalar) const +{ + return fcmp_rust::helios_scalar_to_bytes(scalar); +} +//---------------------------------------------------------------------------------------------------------------------- +std::array Selene::to_bytes(const Selene::Scalar &scalar) const +{ + return fcmp_rust::selene_scalar_to_bytes(scalar); +} +//---------------------------------------------------------------------------------------------------------------------- +std::array Helios::to_bytes(const Helios::Point &point) const +{ + return fcmp_rust::helios_point_to_bytes(point); +} +//---------------------------------------------------------------------------------------------------------------------- +std::array Selene::to_bytes(const Selene::Point &point) const +{ + return fcmp_rust::selene_point_to_bytes(point); +} +//---------------------------------------------------------------------------------------------------------------------- +std::string Helios::to_string(const typename Helios::Scalar &scalar) const +{ + return epee::string_tools::pod_to_hex(this->to_bytes(scalar)); +} +//---------------------------------------------------------------------------------------------------------------------- +std::string Selene::to_string(const typename Selene::Scalar &scalar) const +{ + return epee::string_tools::pod_to_hex(this->to_bytes(scalar)); +} +//---------------------------------------------------------------------------------------------------------------------- +std::string Helios::to_string(const typename Helios::Point &point) const +{ + return epee::string_tools::pod_to_hex(this->to_bytes(point)); +} +//---------------------------------------------------------------------------------------------------------------------- +std::string Selene::to_string(const typename Selene::Point &point) const +{ + return epee::string_tools::pod_to_hex(this->to_bytes(point)); +} +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point) { static_assert(sizeof(RustEd25519Point) == sizeof(crypto::ec_point), "expected same size ed25519 point to rust representation"); @@ -56,15 +153,28 @@ SeleneScalar Selene::ed_25519_point_to_scalar(const crypto::ec_point &point) con fcmp::tower_cycle::RustEd25519Point rust_point; memcpy(&rust_point, &point, sizeof(fcmp::tower_cycle::RustEd25519Point)); return fcmp_rust::ed25519_point_to_selene_scalar(rust_point); -}; +} //---------------------------------------------------------------------------------------------------------------------- -HeliosScalar Selene::point_to_cycle_scalar(const Selene::Point &point) const +Helios::Generators random_helios_generators() { - return fcmp_rust::selene_point_to_helios_scalar(point); -}; + return fcmp_rust::random_helios_generators(); +} //---------------------------------------------------------------------------------------------------------------------- -} //namespace selene +Selene::Generators random_selene_generators() +{ + return fcmp_rust::random_selene_generators(); +} +//---------------------------------------------------------------------------------------------------------------------- +Helios::Point random_helios_hash_init_point() +{ + return fcmp_rust::random_helios_hash_init_point(); +} +//---------------------------------------------------------------------------------------------------------------------- +Selene::Point random_selene_hash_init_point() +{ + return fcmp_rust::random_selene_hash_init_point(); +} //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- -} //namespace curves +} //namespace tower_cycle } //namespace fcmp diff --git a/src/fcmp/tower_cycle.h b/src/fcmp/tower_cycle.h index 2d9e77297..b871b6f98 100644 --- a/src/fcmp/tower_cycle.h +++ b/src/fcmp/tower_cycle.h @@ -31,7 +31,6 @@ #include "crypto/crypto.h" #include "fcmp_rust/cxx.h" #include "fcmp_rust/fcmp_rust.h" -#include "string_tools.h" #include @@ -41,119 +40,162 @@ namespace tower_cycle { //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- +// Rust types +//---------------------------------------------------------------------------------------------------------------------- using RustEd25519Point = std::array; // Need to forward declare Scalar types for point_to_cycle_scalar below using SeleneScalar = rust::Box; using HeliosScalar = rust::Box; //---------------------------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------------------------- -namespace helios +struct HeliosT final { + using Generators = rust::Box; + using Scalar = HeliosScalar; + using Point = rust::Box; + using Chunk = rust::Slice; + using CycleScalar = SeleneScalar; +}; //---------------------------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------------------------- -// TODO: Curve classes that inherit from a parent -static struct Helios final +struct SeleneT final { - using Generators = rust::Box; - using Scalar = HeliosScalar; - using Point = rust::Box; - using Chunk = rust::Slice; + using Generators = rust::Box; + using Scalar = SeleneScalar; + using Point = rust::Box; + using Chunk = rust::Slice; + using CycleScalar = HeliosScalar; +}; +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// Parent curve class that curves in a curve cycle must implement +//---------------------------------------------------------------------------------------------------------------------- +template +class Curve +{ +//constructor +public: + Curve(const typename C::Generators &generators, const typename C::Point &hash_init_point): + m_generators{generators}, + m_hash_init_point{hash_init_point} + {}; - // TODO: static constants - const Generators GENERATORS = fcmp_rust::random_helios_generators(); - const Point HASH_INIT_POINT = fcmp_rust::random_helios_hash_init_point(); +//member functions +public: + // Read the x-coordinate from this curve's point to get this curve's cycle scalar + virtual typename C::CycleScalar point_to_cycle_scalar(const typename C::Point &point) const = 0; - // Helios point x-coordinates are Selene scalars - SeleneScalar point_to_cycle_scalar(const Point &point) const; + virtual typename C::Point hash_grow( + const typename C::Point &existing_hash, + const std::size_t offset, + const typename C::Chunk &prior_children, + const typename C::Chunk &new_children) const = 0; + + virtual typename C::Scalar clone(const typename C::Scalar &scalar) const = 0; + virtual typename C::Point clone(const typename C::Point &point) const = 0; + + virtual typename C::Scalar zero_scalar() const = 0; + + virtual std::array to_bytes(const typename C::Scalar &scalar) const = 0; + virtual std::array to_bytes(const typename C::Point &point) const = 0; + + virtual std::string to_string(const typename C::Scalar &scalar) const = 0; + virtual std::string to_string(const typename C::Point &point) const = 0; + +//member variables +public: + // TODO: make these static constants + const typename C::Generators &m_generators; + const typename C::Point &m_hash_init_point; +}; +//---------------------------------------------------------------------------------------------------------------------- +class Helios final : public Curve +{ +//typedefs +public: + using Generators = HeliosT::Generators; + using Scalar = HeliosT::Scalar; + using Point = HeliosT::Point; + using Chunk = HeliosT::Chunk; + using CycleScalar = HeliosT::CycleScalar; + +//constructor +public: + Helios(const Generators &generators, const Point &hash_init_point) + : Curve(generators, hash_init_point) + {}; + +//member functions +public: + CycleScalar point_to_cycle_scalar(const Point &point) const override; Point hash_grow( - const Generators &generators, const Point &existing_hash, const std::size_t offset, const Chunk &prior_children, - const Chunk &new_children) const - { - return fcmp_rust::hash_grow_helios( - generators, - existing_hash, - offset, - prior_children, - new_children); - } + const Chunk &new_children) const override; - Scalar clone(const Scalar &scalar) const { return fcmp_rust::clone_helios_scalar(scalar); } - Point clone(const Point &point) const { return fcmp_rust::clone_helios_point(point); } + Scalar clone(const Scalar &scalar) const override; + Point clone(const Point &point) const override; - Scalar zero_scalar() const { return fcmp_rust::helios_zero_scalar(); } + Scalar zero_scalar() const override; - std::array to_bytes(const Scalar &scalar) const - { return fcmp_rust::helios_scalar_to_bytes(scalar); } - std::array to_bytes(const Point &point) const - { return fcmp_rust::helios_point_to_bytes(point); } + std::array to_bytes(const Scalar &scalar) const override; + std::array to_bytes(const Point &point) const override; - std::string to_string(const Scalar &scalar) const - { return epee::string_tools::pod_to_hex(to_bytes(scalar)); } - std::string to_string(const Point &point) const - { return epee::string_tools::pod_to_hex(to_bytes(point)); } -} HELIOS; -}//namespace helios + std::string to_string(const Scalar &scalar) const override; + std::string to_string(const Point &point) const override; +}; //---------------------------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------------------------- -namespace selene +class Selene final : public Curve { -//---------------------------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------------------------- -static struct Selene final -{ - using Generators = rust::Box; - using Scalar = SeleneScalar; - using Point = rust::Box; - using Chunk = rust::Slice; +//typedefs +public: + using Generators = SeleneT::Generators; + using Scalar = SeleneT::Scalar; + using Point = SeleneT::Point; + using Chunk = SeleneT::Chunk; + using CycleScalar = SeleneT::CycleScalar; - // TODO: static constants - const Generators GENERATORS = fcmp_rust::random_selene_generators(); - const Point HASH_INIT_POINT = fcmp_rust::random_selene_hash_init_point(); +//constructor +public: + Selene(const Generators &generators, const Point &hash_init_point) + : Curve(generators, hash_init_point) + {}; - // Ed25519 point x-coordinates are Selene scalars - SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point) const; - - // Selene point x-coordinates are Helios scalars - HeliosScalar point_to_cycle_scalar(const Point &point) const; +//member functions +public: + CycleScalar point_to_cycle_scalar(const Point &point) const override; Point hash_grow( - const Generators &generators, const Point &existing_hash, const std::size_t offset, const Chunk &prior_children, - const Chunk &new_children) const - { - return fcmp_rust::hash_grow_selene( - generators, - existing_hash, - offset, - prior_children, - new_children); - }; + const Chunk &new_children) const override; - Scalar clone(const Scalar &scalar) const { return fcmp_rust::clone_selene_scalar(scalar); } - Point clone(const Point &point) const { return fcmp_rust::clone_selene_point(point); } + Scalar clone(const Scalar &scalar) const override; + Point clone(const Point &point) const override; - Scalar zero_scalar() const { return fcmp_rust::selene_zero_scalar(); } + Scalar zero_scalar() const override; - std::array to_bytes(const Scalar &scalar) const - { return fcmp_rust::selene_scalar_to_bytes(scalar); } - std::array to_bytes(const Point &point) const - { return fcmp_rust::selene_point_to_bytes(point); } + std::array to_bytes(const Scalar &scalar) const override; + std::array to_bytes(const Point &point) const override; - std::string to_string(const Scalar &scalar) const - { return epee::string_tools::pod_to_hex(to_bytes(scalar)); } - std::string to_string(const Point &point) const - { return epee::string_tools::pod_to_hex(to_bytes(point)); } -} SELENE; -}// namespace selene + std::string to_string(const Scalar &scalar) const override; + std::string to_string(const Point &point) const override; +}; //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- +// Ed25519 point x-coordinates are Selene scalars +SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point); +//---------------------------------------------------------------------------------------------------------------------- +// TODO: use static constants and get rid of the below functions +Helios::Generators random_helios_generators(); +Selene::Generators random_selene_generators(); +Helios::Point random_helios_hash_init_point(); +Selene::Point random_selene_hash_init_point(); +//---------------------------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------------------------- +// TODO: implement in cpp file template static void extend_zeroes(const C &curve, const std::size_t num_zeroes, @@ -165,6 +207,7 @@ static void extend_zeroes(const C &curve, zeroes_inout.emplace_back(curve.zero_scalar()); } //---------------------------------------------------------------------------------------------------------------------- +// TODO: move impl into cpp template static void extend_scalars_from_cycle_points(const C_POINTS &curve, const std::vector &points, diff --git a/tests/unit_tests/curve_trees.cpp b/tests/unit_tests/curve_trees.cpp index b40df6d33..8038c56e6 100644 --- a/tests/unit_tests/curve_trees.cpp +++ b/tests/unit_tests/curve_trees.cpp @@ -365,10 +365,9 @@ bool CurveTreesUnitTest::validate_tree(const CurveTreesUnitTest::Tree &tree) m_curve_trees.m_leaf_layer_chunk_width); } //---------------------------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------------------------- // Logging helpers //---------------------------------------------------------------------------------------------------------------------- -static void log_last_chunks(const CurveTreesV1::LastChunks &last_chunks) +void CurveTreesUnitTest::log_last_chunks(const CurveTreesV1::LastChunks &last_chunks) { const auto &c1_last_chunks = last_chunks.c1_last_chunks; const auto &c2_last_chunks = last_chunks.c2_last_chunks; @@ -388,8 +387,8 @@ static void log_last_chunks(const CurveTreesV1::LastChunks &last_chunks) const CurveTreesV1::LastChunkData &last_chunk = c2_last_chunks[c2_idx]; MDEBUG("child_offset: " << last_chunk.child_offset - << " , last_child: " << fcmp::tower_cycle::selene::SELENE.to_string(last_chunk.last_child) - << " , last_parent: " << fcmp::tower_cycle::selene::SELENE.to_string(last_chunk.last_parent) + << " , last_child: " << m_curve_trees.m_c2.to_string(last_chunk.last_child) + << " , last_parent: " << m_curve_trees.m_c2.to_string(last_chunk.last_parent) << " , child_layer_size: " << last_chunk.child_layer_size << " , parent_layer_size: " << last_chunk.parent_layer_size); @@ -402,8 +401,8 @@ static void log_last_chunks(const CurveTreesV1::LastChunks &last_chunks) const CurveTreesV1::LastChunkData &last_chunk = c1_last_chunks[c1_idx]; MDEBUG("child_offset: " << last_chunk.child_offset - << " , last_child: " << fcmp::tower_cycle::helios::HELIOS.to_string(last_chunk.last_child) - << " , last_parent: " << fcmp::tower_cycle::helios::HELIOS.to_string(last_chunk.last_parent) + << " , last_child: " << m_curve_trees.m_c1.to_string(last_chunk.last_child) + << " , last_parent: " << m_curve_trees.m_c1.to_string(last_chunk.last_parent) << " , child_layer_size: " << last_chunk.child_layer_size << " , parent_layer_size: " << last_chunk.parent_layer_size); @@ -414,7 +413,7 @@ static void log_last_chunks(const CurveTreesV1::LastChunks &last_chunks) } } //---------------------------------------------------------------------------------------------------------------------- -static void log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension) +void CurveTreesUnitTest::log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension) { const auto &c1_extensions = tree_extension.c1_layer_extensions; const auto &c2_extensions = tree_extension.c2_layer_extensions; @@ -427,9 +426,9 @@ static void log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension { const auto &leaf = tree_extension.leaves.tuples[i]; - const auto O_x = fcmp::tower_cycle::selene::SELENE.to_string(leaf.O_x); - const auto I_x = fcmp::tower_cycle::selene::SELENE.to_string(leaf.I_x); - const auto C_x = fcmp::tower_cycle::selene::SELENE.to_string(leaf.C_x); + const auto O_x = m_curve_trees.m_c2.to_string(leaf.O_x); + const auto I_x = m_curve_trees.m_c2.to_string(leaf.I_x); + const auto C_x = m_curve_trees.m_c2.to_string(leaf.C_x); MDEBUG("Leaf idx " << ((i*CurveTreesV1::LEAF_TUPLE_SIZE) + tree_extension.leaves.start_idx) << " : { O_x: " << O_x << " , I_x: " << I_x << " , C_x: " << C_x << " }"); @@ -449,7 +448,7 @@ static void log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension for (std::size_t j = 0; j < c2_layer.hashes.size(); ++j) MDEBUG("Hash idx: " << (j + c2_layer.start_idx) << " , hash: " - << fcmp::tower_cycle::selene::SELENE.to_string(c2_layer.hashes[j])); + << m_curve_trees.m_c2.to_string(c2_layer.hashes[j])); ++c2_idx; } @@ -462,7 +461,7 @@ static void log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension for (std::size_t j = 0; j < c1_layer.hashes.size(); ++j) MDEBUG("Hash idx: " << (j + c1_layer.start_idx) << " , hash: " - << fcmp::tower_cycle::helios::HELIOS.to_string(c1_layer.hashes[j])); + << m_curve_trees.m_c1.to_string(c1_layer.hashes[j])); ++c1_idx; } @@ -471,7 +470,7 @@ static void log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension } } //---------------------------------------------------------------------------------------------------------------------- -static void log_tree(const CurveTreesUnitTest::Tree &tree) +void CurveTreesUnitTest::log_tree(const CurveTreesUnitTest::Tree &tree) { MDEBUG("Tree has " << tree.leaves.size() << " leaves, " << tree.c1_layers.size() << " helios layers, " << tree.c2_layers.size() << " selene layers"); @@ -480,9 +479,9 @@ static void log_tree(const CurveTreesUnitTest::Tree &tree) { const auto &leaf = tree.leaves[i]; - const auto O_x = fcmp::tower_cycle::selene::SELENE.to_string(leaf.O_x); - const auto I_x = fcmp::tower_cycle::selene::SELENE.to_string(leaf.I_x); - const auto C_x = fcmp::tower_cycle::selene::SELENE.to_string(leaf.C_x); + const auto O_x = m_curve_trees.m_c2.to_string(leaf.O_x); + const auto I_x = m_curve_trees.m_c2.to_string(leaf.I_x); + const auto C_x = m_curve_trees.m_c2.to_string(leaf.C_x); MDEBUG("Leaf idx " << i << " : { O_x: " << O_x << " , I_x: " << I_x << " , C_x: " << C_x << " }"); } @@ -500,7 +499,7 @@ static void log_tree(const CurveTreesUnitTest::Tree &tree) MDEBUG("Selene layer size: " << c2_layer.size() << " , tree layer: " << i); for (std::size_t j = 0; j < c2_layer.size(); ++j) - MDEBUG("Hash idx: " << j << " , hash: " << fcmp::tower_cycle::selene::SELENE.to_string(c2_layer[j])); + MDEBUG("Hash idx: " << j << " , hash: " << m_curve_trees.m_c2.to_string(c2_layer[j])); ++c2_idx; } @@ -512,7 +511,7 @@ static void log_tree(const CurveTreesUnitTest::Tree &tree) MDEBUG("Helios layer size: " << c1_layer.size() << " , tree layer: " << i); for (std::size_t j = 0; j < c1_layer.size(); ++j) - MDEBUG("Hash idx: " << j << " , hash: " << fcmp::tower_cycle::helios::HELIOS.to_string(c1_layer[j])); + MDEBUG("Hash idx: " << j << " , hash: " << m_curve_trees.m_c1.to_string(c1_layer[j])); ++c1_idx; } @@ -524,7 +523,7 @@ static void log_tree(const CurveTreesUnitTest::Tree &tree) //---------------------------------------------------------------------------------------------------------------------- // Test helpers //---------------------------------------------------------------------------------------------------------------------- -static const CurveTreesV1::Leaves generate_leaves(const CurveTreesV1 &curve_trees, const std::size_t num_leaves) +static const CurveTreesV1::Leaves generate_random_leaves(const CurveTreesV1 &curve_trees, const std::size_t num_leaves) { std::vector tuples; tuples.reserve(num_leaves); @@ -553,17 +552,25 @@ static void grow_tree_test(CurveTreesV1 &curve_trees, const std::size_t num_leaves, CurveTreesUnitTest::Tree &tree_inout) { + // Get the last chunk from each layer in the tree; empty if tree is empty const auto last_chunks = curve_trees_accessor.get_last_chunks(tree_inout); - log_last_chunks(last_chunks); + curve_trees_accessor.log_last_chunks(last_chunks); + + // Get a tree extension object to the existing tree using randomly generated leaves + // - The tree extension includes all elements we'll need to add to the existing tree when adding the new leaves const auto tree_extension = curve_trees.get_tree_extension( last_chunks, - generate_leaves(curve_trees, num_leaves)); - log_tree_extension(tree_extension); + generate_random_leaves(curve_trees, num_leaves)); + curve_trees_accessor.log_tree_extension(tree_extension); + + // Use the tree extension to extend the existing tree curve_trees_accessor.extend_tree(tree_extension, tree_inout); - log_tree(tree_inout); + curve_trees_accessor.log_tree(tree_inout); + + // Validate tree structure and all hashes ASSERT_TRUE(curve_trees_accessor.validate_tree(tree_inout)); } //---------------------------------------------------------------------------------------------------------------------- @@ -572,13 +579,23 @@ static void grow_tree_test(CurveTreesV1 &curve_trees, //---------------------------------------------------------------------------------------------------------------------- TEST(curve_trees, grow_tree) { + // TODO: use static constant generators and hash init points + const Helios::Generators HELIOS_GENERATORS = fcmp::tower_cycle::random_helios_generators(); + const Selene::Generators SELENE_GENERATORS = fcmp::tower_cycle::random_selene_generators(); + + const Helios::Point HELIOS_HASH_INIT_POINT = fcmp::tower_cycle::random_helios_hash_init_point(); + const Selene::Point SELENE_HASH_INIT_POINT = fcmp::tower_cycle::random_selene_hash_init_point(); + + Helios helios(HELIOS_GENERATORS, HELIOS_HASH_INIT_POINT); + Selene selene(SELENE_GENERATORS, SELENE_HASH_INIT_POINT); + // TODO: test varying widths const std::size_t HELIOS_CHUNK_WIDTH = 5; const std::size_t SELENE_CHUNK_WIDTH = 5; auto curve_trees = CurveTreesV1( - fcmp::tower_cycle::helios::HELIOS, - fcmp::tower_cycle::selene::SELENE, + helios, + selene, HELIOS_CHUNK_WIDTH, SELENE_CHUNK_WIDTH); diff --git a/tests/unit_tests/curve_trees.h b/tests/unit_tests/curve_trees.h index f8456e4ab..16527827a 100644 --- a/tests/unit_tests/curve_trees.h +++ b/tests/unit_tests/curve_trees.h @@ -32,8 +32,8 @@ #include "fcmp/tower_cycle.h" #include "misc_log_ex.h" -using Helios = fcmp::tower_cycle::helios::Helios; -using Selene = fcmp::tower_cycle::selene::Selene; +using Helios = fcmp::tower_cycle::Helios; +using Selene = fcmp::tower_cycle::Selene; // TODO: make this the instantiation in curve_trees.h/.cpp using CurveTreesV1 = fcmp::CurveTrees; @@ -67,6 +67,11 @@ public: // Validate the in-memory tree by re-hashing every layer, starting from root and working down to leaf layer bool validate_tree(const Tree &tree); + // logging helpers + void log_last_chunks(const CurveTreesV1::LastChunks &last_chunks); + void log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension); + void log_tree(const CurveTreesUnitTest::Tree &tree); + //private member functions private: template