diff --git a/src/fcmp/CMakeLists.txt b/src/fcmp/CMakeLists.txt index 2c4543e19..8af1b1f6b 100644 --- a/src/fcmp/CMakeLists.txt +++ b/src/fcmp/CMakeLists.txt @@ -27,8 +27,7 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. set(fcmp_sources - curve_trees.cpp - tower_cycle_types.cpp) + tower_cycle.cpp) monero_find_all_headers(fcmp_headers "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/src/fcmp/curve_trees.cpp b/src/fcmp/curve_trees.cpp deleted file mode 100644 index 3e58f484d..000000000 --- a/src/fcmp/curve_trees.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2024, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// 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 "curve_trees.h" - -namespace fcmp -{ -namespace curve_trees -{ - -LeafTuple output_to_leaf_tuple(const crypto::public_key &O, const crypto::public_key &C) -{ - crypto::ec_point I; - crypto::derive_key_image_generator(O, I); - - return LeafTuple{ - .O_x = tower_cycle::selene::SELENE.ed_25519_point_to_scalar(O), - .I_x = tower_cycle::selene::SELENE.ed_25519_point_to_scalar(I), - .C_x = tower_cycle::selene::SELENE.ed_25519_point_to_scalar(C) - }; -} - -// TODO: move into curves tree file -std::vector flatten_leaves(const std::vector &leaves) -{ - std::vector flattened_leaves; - flattened_leaves.reserve(leaves.size() * LEAF_TUPLE_SIZE); - - for (const auto &l : leaves) - { - // TODO: implement without cloning - flattened_leaves.emplace_back(tower_cycle::selene::SELENE.clone(l.O_x)); - flattened_leaves.emplace_back(tower_cycle::selene::SELENE.clone(l.I_x)); - flattened_leaves.emplace_back(tower_cycle::selene::SELENE.clone(l.C_x)); - } - - return flattened_leaves; -}; - -} //namespace curve_trees -} //namespace fcmp diff --git a/src/fcmp/curve_trees.h b/src/fcmp/curve_trees.h index 49a7bafd8..5190aa5dc 100644 --- a/src/fcmp/curve_trees.h +++ b/src/fcmp/curve_trees.h @@ -30,7 +30,7 @@ #include "crypto/crypto.h" #include "misc_log_ex.h" -#include "tower_cycle_types.h" +#include "tower_cycle.h" #include @@ -40,16 +40,16 @@ namespace curve_trees { -// TODO: template all the curve things // TODO: CurveTree class instantiated with the curves and widths // TODO: move "TEST" functions -// TODO: template +// TODO: make part of CurveTrees class +template struct LeafTuple final { - tower_cycle::selene::Selene::Scalar O_x; - tower_cycle::selene::Selene::Scalar I_x; - tower_cycle::selene::Selene::Scalar C_x; + typename C::Scalar O_x; + typename C::Scalar I_x; + typename C::Scalar C_x; }; static const std::size_t LEAF_TUPLE_SIZE = 3; @@ -57,15 +57,18 @@ static const std::size_t LEAF_TUPLE_SIZE = 3; // TODO: make this a const class member that's set on initialization static const std::size_t LEAF_LAYER_CHUNK_WIDTH = LEAF_TUPLE_SIZE * tower_cycle::selene::SELENE.WIDTH; +// TODO: make part of CurveTrees class // Tree structure +template struct Leaves final { // Starting index in the leaf layer - std::size_t start_idx; + std::size_t start_idx; // Contiguous leaves in a tree that start at the start_idx - std::vector tuples; + std::vector> tuples; }; +// TODO: make part of CurveTrees class // A layer of contiguous hashes starting from a specific start_idx in the tree template struct LayerExtension final @@ -74,15 +77,17 @@ struct LayerExtension final std::vector hashes; }; +// TODO: make part of CurveTrees class // A struct useful to extend an existing tree, layers alternate between C1 and C2 template struct TreeExtension final { - Leaves leaves; + Leaves leaves; std::vector> c1_layer_extensions; std::vector> c2_layer_extensions; }; +// TODO: make part of CurveTrees class // Useful data from the last chunk in a layer template struct LastChunkData final @@ -99,6 +104,7 @@ struct LastChunkData final /*TODO: const*/ std::size_t parent_layer_size; }; +// TODO: make part of CurveTrees class template struct LastChunks final { @@ -106,9 +112,40 @@ struct LastChunks final std::vector> c2_last_chunks; }; -// TODO: template -LeafTuple output_to_leaf_tuple(const crypto::public_key &O, const crypto::public_key &C); -std::vector flatten_leaves(const std::vector &leaves); +// TODO: make part of CurveTrees class +template +LeafTuple output_to_leaf_tuple(const C2 &curve, + const crypto::public_key &O, + const crypto::public_key &C) +{ + crypto::ec_point I; + crypto::derive_key_image_generator(O, I); + + return LeafTuple{ + .O_x = curve.ed_25519_point_to_scalar(O), + .I_x = curve.ed_25519_point_to_scalar(I), + .C_x = curve.ed_25519_point_to_scalar(C) + }; +}; + +// TODO: make part of CurveTrees class +template +std::vector flatten_leaves(const C &curve, + const std::vector> &leaves) +{ + std::vector flattened_leaves; + flattened_leaves.reserve(leaves.size() * LEAF_TUPLE_SIZE); + + for (const auto &l : leaves) + { + // TODO: implement without cloning + flattened_leaves.emplace_back(curve.clone(l.O_x)); + flattened_leaves.emplace_back(curve.clone(l.I_x)); + flattened_leaves.emplace_back(curve.clone(l.C_x)); + } + + return flattened_leaves; +}; template static void extend_scalars_from_cycle_points(const C_POINTS &curve, @@ -125,7 +162,7 @@ static void extend_scalars_from_cycle_points(const C_POINTS &curve, } } -// TODO: move to tower_cycle_types +// TODO: move to tower_cycle template static void extend_zeroes(const C &curve, const std::size_t num_zeroes, @@ -154,6 +191,7 @@ static typename C::Point get_new_parent(const C &curve, ); } +// TODO: make part of CurveTrees class template static typename C::Point get_first_leaf_parent(const C &curve, const typename C::Chunk &new_children, @@ -176,6 +214,7 @@ static typename C::Point get_first_leaf_parent(const C &curve, ); } +// TODO: make part of CurveTrees class template static typename C::Point get_first_non_leaf_parent(const C &curve, const typename C::Chunk &new_children, @@ -222,6 +261,7 @@ static typename C::Point get_first_non_leaf_parent(const C &curve, } // TODO: look into consolidating hash_layer and hash_leaf_layer into 1 function +// TODO: make part of CurveTrees class template void hash_layer(const C_CHILD &c_child, const C_PARENT &c_parent, @@ -322,10 +362,11 @@ void hash_layer(const C_CHILD &c_child, } } +// TODO: make part of CurveTrees class template void hash_leaf_layer(const C2 &c2, const LastChunkData *last_chunk_ptr, - const Leaves &leaves, + const Leaves &leaves, LayerExtension &parents_out) { parents_out.start_idx = (last_chunk_ptr == nullptr) ? 0 : last_chunk_ptr->parent_layer_size; @@ -335,7 +376,7 @@ void hash_leaf_layer(const C2 &c2, return; // Flatten leaves [(O.x, I.x, C.x),(O.x, I.x, C.x),...] -> [scalar, scalar, scalar, scalar, scalar, scalar,...] - const std::vector children = flatten_leaves(leaves.tuples); + const std::vector children = flatten_leaves(c2, leaves.tuples); const std::size_t max_chunk_size = LEAF_LAYER_CHUNK_WIDTH; const std::size_t offset = (last_chunk_ptr == nullptr) ? 0 : last_chunk_ptr->child_offset; @@ -385,9 +426,10 @@ void hash_leaf_layer(const C2 &c2, } } +// TODO: make part of CurveTrees class template TreeExtension get_tree_extension(const LastChunks &existing_last_chunks, - const Leaves &new_leaves, + const Leaves &new_leaves, const C1 &c1, const C2 &c2) { @@ -409,7 +451,7 @@ TreeExtension get_tree_extension(const LastChunks &existing_last tree_extension.leaves.tuples.reserve(new_leaves.tuples.size()); for (const auto &leaf : new_leaves.tuples) { - tree_extension.leaves.tuples.emplace_back(LeafTuple{ + tree_extension.leaves.tuples.emplace_back(LeafTuple{ .O_x = c2.clone(leaf.O_x), .I_x = c2.clone(leaf.I_x), .C_x = c2.clone(leaf.C_x) @@ -494,7 +536,7 @@ using Layer = std::vector; template struct Tree final { - std::vector leaves; + std::vector> leaves; std::vector> c1_layers; std::vector> c2_layers; }; @@ -502,7 +544,7 @@ struct Tree final // TEST template LastChunkData get_last_leaf_chunk(const C2 &c2, - const std::vector &leaves, + const std::vector> &leaves, const std::vector &parent_layer) { CHECK_AND_ASSERT_THROW_MES(!leaves.empty(), "empty leaf layer"); @@ -654,7 +696,7 @@ void extend_tree(const TreeExtension &tree_extension, tree_inout.leaves.reserve(tree_inout.leaves.size() + tree_extension.leaves.tuples.size()); for (const auto &leaf : tree_extension.leaves.tuples) { - tree_inout.leaves.emplace_back(LeafTuple{ + tree_inout.leaves.emplace_back(LeafTuple{ .O_x = c2.clone(leaf.O_x), .I_x = c2.clone(leaf.I_x), .C_x = c2.clone(leaf.C_x) @@ -832,7 +874,7 @@ bool validate_tree(const Tree &tree, const C1 &c1, const C2 &c2) } // Now validate leaves - return validate_layer(c2, c2_layers[0], flatten_leaves(leaves), LEAF_LAYER_CHUNK_WIDTH); + return validate_layer(c2, c2_layers[0], flatten_leaves(c2, leaves), LEAF_LAYER_CHUNK_WIDTH); } } //namespace curve_trees diff --git a/src/fcmp/tower_cycle_types.cpp b/src/fcmp/tower_cycle.cpp similarity index 98% rename from src/fcmp/tower_cycle_types.cpp rename to src/fcmp/tower_cycle.cpp index 4069e1bed..e90125667 100644 --- a/src/fcmp/tower_cycle_types.cpp +++ b/src/fcmp/tower_cycle.cpp @@ -26,7 +26,7 @@ // 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 "tower_cycle_types.h" +#include "tower_cycle.h" namespace fcmp { @@ -47,7 +47,7 @@ SeleneScalar Helios::point_to_cycle_scalar(const Helios::Point &point) const namespace selene { //---------------------------------------------------------------------------------------------------------------------- -SeleneScalar Selene::ed_25519_point_to_scalar(const crypto::ec_point &point) +SeleneScalar Selene::ed_25519_point_to_scalar(const crypto::ec_point &point) const { static_assert(sizeof(RustEd25519Point) == sizeof(crypto::ec_point), "expected same size ed25519 point to rust representation"); diff --git a/src/fcmp/tower_cycle_types.h b/src/fcmp/tower_cycle.h similarity index 99% rename from src/fcmp/tower_cycle_types.h rename to src/fcmp/tower_cycle.h index 3660aeb16..36177f072 100644 --- a/src/fcmp/tower_cycle_types.h +++ b/src/fcmp/tower_cycle.h @@ -122,7 +122,7 @@ static struct Selene final static const std::size_t WIDTH = 5; // Ed25519 point x-coordinates are Selene scalars - SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point); + 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; diff --git a/tests/unit_tests/curve_trees.cpp b/tests/unit_tests/curve_trees.cpp index 07a98c787..a8e7a4459 100644 --- a/tests/unit_tests/curve_trees.cpp +++ b/tests/unit_tests/curve_trees.cpp @@ -29,14 +29,15 @@ #include "gtest/gtest.h" #include "fcmp/curve_trees.h" -#include "fcmp/tower_cycle_types.h" +#include "fcmp/tower_cycle.h" #include "misc_log_ex.h" #include -static const fcmp::curve_trees::Leaves generate_leaves(const std::size_t num_leaves) +template +static const fcmp::curve_trees::Leaves generate_leaves(const C2 &curve, const std::size_t num_leaves) { - std::vector tuples; + std::vector> tuples; tuples.reserve(num_leaves); for (std::size_t i = 0; i < num_leaves; ++i) @@ -47,10 +48,12 @@ static const fcmp::curve_trees::Leaves generate_leaves(const std::size_t num_lea crypto::generate_keys(O, o, o, false); crypto::generate_keys(C, c, c, false); - tuples.emplace_back(fcmp::curve_trees::output_to_leaf_tuple(O, C)); + auto leaf_tuple = fcmp::curve_trees::output_to_leaf_tuple(curve, O, C); + + tuples.emplace_back(std::move(leaf_tuple)); } - return fcmp::curve_trees::Leaves{ + return fcmp::curve_trees::Leaves{ .start_idx = 0, .tuples = std::move(tuples) }; @@ -209,7 +212,7 @@ static void log_last_chunks(const fcmp::curve_trees::LastChunks N_LEAVES{ 1, @@ -241,7 +244,7 @@ TEST(fcmp_tree, grow_tree) const auto tree_extension = fcmp::curve_trees::get_tree_extension( fcmp::curve_trees::LastChunks{}, - generate_leaves(init_leaves), + generate_leaves(fcmp::tower_cycle::selene::SELENE, init_leaves), fcmp::tower_cycle::helios::HELIOS, fcmp::tower_cycle::selene::SELENE); @@ -278,7 +281,7 @@ TEST(fcmp_tree, grow_tree) const auto tree_extension = fcmp::curve_trees::get_tree_extension( last_chunks, - generate_leaves(ext_leaves), + generate_leaves(fcmp::tower_cycle::selene::SELENE, ext_leaves), fcmp::tower_cycle::helios::HELIOS, fcmp::tower_cycle::selene::SELENE);