mirror of
https://github.com/monero-project/monero.git
synced 2025-01-08 09:07:52 -05:00
Cleaner template usage, moved static functions out of CurveTrees class
This commit is contained in:
parent
9ba00be519
commit
5ad026975a
@ -31,192 +31,22 @@
|
||||
|
||||
namespace fcmp
|
||||
{
|
||||
namespace curve_trees
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
using Helios = tower_cycle::Helios;
|
||||
using Selene = tower_cycle::Selene;
|
||||
|
||||
// Instantiate the tower cycle types
|
||||
template class CurveTrees<Helios, Selene>;
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<>
|
||||
CurveTrees<Helios, Selene>::LeafTuple CurveTrees<Helios, Selene>::output_to_leaf_tuple(
|
||||
const crypto::public_key &O,
|
||||
const crypto::public_key &C) const
|
||||
{
|
||||
crypto::ec_point I;
|
||||
crypto::derive_key_image_generator(O, I);
|
||||
|
||||
return LeafTuple{
|
||||
.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)
|
||||
};
|
||||
};
|
||||
// Public helper functions
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template <typename C1, typename C2>
|
||||
typename CurveTrees<C1, C2>::TreeExtension CurveTrees<C1, C2>::get_tree_extension(
|
||||
const LastChunks &existing_last_chunks,
|
||||
const std::vector<LeafTuple> &new_leaf_tuples)
|
||||
{
|
||||
TreeExtension tree_extension;
|
||||
|
||||
if (new_leaf_tuples.empty())
|
||||
return tree_extension;
|
||||
|
||||
const auto &c1_last_chunks = existing_last_chunks.c1_last_chunks;
|
||||
const auto &c2_last_chunks = existing_last_chunks.c2_last_chunks;
|
||||
|
||||
// Set the leaf start idx
|
||||
tree_extension.leaves.start_idx = c2_last_chunks.empty()
|
||||
? 0
|
||||
: c2_last_chunks[0].child_layer_size;
|
||||
|
||||
// Copy the leaves
|
||||
// TODO: don't copy here
|
||||
tree_extension.leaves.tuples.reserve(new_leaf_tuples.size());
|
||||
for (const auto &leaf : new_leaf_tuples)
|
||||
{
|
||||
tree_extension.leaves.tuples.emplace_back(LeafTuple{
|
||||
.O_x = m_c2.clone(leaf.O_x),
|
||||
.I_x = m_c2.clone(leaf.I_x),
|
||||
.C_x = m_c2.clone(leaf.C_x)
|
||||
});
|
||||
}
|
||||
|
||||
auto &c1_layer_extensions_out = tree_extension.c1_layer_extensions;
|
||||
auto &c2_layer_extensions_out = tree_extension.c2_layer_extensions;
|
||||
|
||||
const std::vector<typename C2::Scalar> flattened_leaves = this->flatten_leaves(new_leaf_tuples);
|
||||
|
||||
// Hash the leaf layer
|
||||
LayerExtension<C2> leaf_parents;
|
||||
this->hash_layer(m_c2,
|
||||
c2_last_chunks.empty() ? nullptr : &c2_last_chunks[0],
|
||||
flattened_leaves,
|
||||
tree_extension.leaves.start_idx,
|
||||
m_leaf_layer_chunk_width,
|
||||
leaf_parents);
|
||||
|
||||
c2_layer_extensions_out.emplace_back(std::move(leaf_parents));
|
||||
|
||||
// Check if we just added the root
|
||||
if (c2_layer_extensions_out.back().hashes.size() == 1 && c2_layer_extensions_out.back().start_idx == 0)
|
||||
return tree_extension;
|
||||
|
||||
// Alternate between hashing c2 children, c1 children, c2, c1, ...
|
||||
bool parent_is_c1 = true;
|
||||
|
||||
std::size_t c1_last_idx = 0;
|
||||
std::size_t c2_last_idx = 0;
|
||||
// TODO: calculate max number of layers it should take to add all leaves (existing leaves + new leaves)
|
||||
while (true)
|
||||
{
|
||||
const LastChunkData<C1> *c1_last_chunk_ptr = (c1_last_chunks.size() <= c1_last_idx)
|
||||
? nullptr
|
||||
: &c1_last_chunks[c1_last_idx];
|
||||
|
||||
const LastChunkData<C2> *c2_last_chunk_ptr = (c2_last_chunks.size() <= c2_last_idx)
|
||||
? nullptr
|
||||
: &c2_last_chunks[c2_last_idx];
|
||||
|
||||
// TODO: templated function
|
||||
if (parent_is_c1)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c2_layer_extensions_out.size() > c2_last_idx, "missing c2 layer");
|
||||
|
||||
const auto &c2_child_extension = c2_layer_extensions_out[c2_last_idx];
|
||||
|
||||
const auto c1_child_scalars = this->next_child_scalars_from_children<C2, C1>(m_c2,
|
||||
c2_last_chunk_ptr,
|
||||
c1_last_chunk_ptr,
|
||||
c2_child_extension);
|
||||
|
||||
LayerExtension<C1> c1_layer_extension;
|
||||
this->hash_layer<C1>(m_c1,
|
||||
c1_last_chunk_ptr,
|
||||
c1_child_scalars,
|
||||
c2_child_extension.start_idx,
|
||||
m_c1_width,
|
||||
c1_layer_extension);
|
||||
|
||||
c1_layer_extensions_out.emplace_back(std::move(c1_layer_extension));
|
||||
|
||||
// Check if we just added the root
|
||||
if (c1_layer_extensions_out.back().hashes.size() == 1 && c1_layer_extensions_out.back().start_idx == 0)
|
||||
return tree_extension;
|
||||
|
||||
++c2_last_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c1_layer_extensions_out.size() > c1_last_idx, "missing c1 layer");
|
||||
|
||||
const auto &c1_child_extension = c1_layer_extensions_out[c1_last_idx];
|
||||
|
||||
const auto c2_child_scalars = this->next_child_scalars_from_children<C1, C2>(m_c1,
|
||||
c1_last_chunk_ptr,
|
||||
c2_last_chunk_ptr,
|
||||
c1_child_extension);
|
||||
|
||||
LayerExtension<C2> c2_layer_extension;
|
||||
this->hash_layer<C2>(m_c2,
|
||||
c2_last_chunk_ptr,
|
||||
c2_child_scalars,
|
||||
c1_child_extension.start_idx,
|
||||
m_c2_width,
|
||||
c2_layer_extension);
|
||||
|
||||
c2_layer_extensions_out.emplace_back(std::move(c2_layer_extension));
|
||||
|
||||
// Check if we just added the root
|
||||
if (c2_layer_extensions_out.back().hashes.size() == 1 && c2_layer_extensions_out.back().start_idx == 0)
|
||||
return tree_extension;
|
||||
|
||||
++c1_last_idx;
|
||||
}
|
||||
|
||||
parent_is_c1 = !parent_is_c1;
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Private member functions
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template <typename C1, typename C2>
|
||||
std::vector<typename C2::Scalar> CurveTrees<C1, C2>::flatten_leaves(const std::vector<LeafTuple> &leaves) const
|
||||
{
|
||||
std::vector<typename C2::Scalar> flattened_leaves;
|
||||
flattened_leaves.reserve(leaves.size() * LEAF_TUPLE_SIZE);
|
||||
|
||||
for (const auto &l : leaves)
|
||||
{
|
||||
// TODO: implement without cloning
|
||||
flattened_leaves.emplace_back(m_c2.clone(l.O_x));
|
||||
flattened_leaves.emplace_back(m_c2.clone(l.I_x));
|
||||
flattened_leaves.emplace_back(m_c2.clone(l.C_x));
|
||||
}
|
||||
|
||||
return flattened_leaves;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Explicit instantiations
|
||||
template Helios::Point CurveTrees<Helios, Selene>::get_new_parent(const Helios &curve,
|
||||
const Helios::Chunk &new_children) const;
|
||||
|
||||
template Selene::Point CurveTrees<Helios, Selene>::get_new_parent(const Selene &curve,
|
||||
const Selene::Chunk &new_children) const;
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Implementation
|
||||
template <typename C1, typename C2>
|
||||
template <typename C>
|
||||
typename C::Point CurveTrees<C1, C2>::get_new_parent(const C &curve,
|
||||
const typename C::Chunk &new_children) const
|
||||
template<typename C>
|
||||
typename C::Point get_new_parent(const C &curve, const typename C::Chunk &new_children)
|
||||
{
|
||||
// New parent means no prior children, fill priors with 0
|
||||
std::vector<typename C::Scalar> prior_children;
|
||||
fcmp::tower_cycle::extend_zeroes(curve, new_children.size(), prior_children);
|
||||
tower_cycle::extend_zeroes(curve, new_children.size(), prior_children);
|
||||
|
||||
return curve.hash_grow(
|
||||
curve.m_hash_init_point,
|
||||
@ -227,34 +57,20 @@ typename C::Point CurveTrees<C1, C2>::get_new_parent(const C &curve,
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Explicit instantiations
|
||||
template Helios::Point CurveTrees<Helios, Selene>::get_first_parent(const Helios &curve,
|
||||
const Helios::Chunk &new_children,
|
||||
const std::size_t chunk_width,
|
||||
const bool child_layer_last_hash_updated,
|
||||
const LastChunkData<Helios> *last_chunk_ptr,
|
||||
const std::size_t offset) const;
|
||||
|
||||
template Selene::Point CurveTrees<Helios, Selene>::get_first_parent(const Selene &curve,
|
||||
const Selene::Chunk &new_children,
|
||||
const std::size_t chunk_width,
|
||||
const bool child_layer_last_hash_updated,
|
||||
const LastChunkData<Selene> *last_chunk_ptr,
|
||||
const std::size_t offset) const;
|
||||
// Static functions
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Implementation
|
||||
template <typename C1, typename C2>
|
||||
template <typename C>
|
||||
typename C::Point CurveTrees<C1, C2>::get_first_parent(const C &curve,
|
||||
// Hash the first chunk of children being added to a layer
|
||||
template<typename C>
|
||||
static typename C::Point get_first_parent(const C &curve,
|
||||
const typename C::Chunk &new_children,
|
||||
const std::size_t chunk_width,
|
||||
const bool child_layer_last_hash_updated,
|
||||
const LastChunkData<C> *last_chunk_ptr,
|
||||
const std::size_t offset) const
|
||||
const std::size_t offset)
|
||||
{
|
||||
// If no last chunk exists, we can get a new parent
|
||||
if (last_chunk_ptr == nullptr)
|
||||
return this->get_new_parent<C>(curve, new_children);
|
||||
return get_new_parent<C>(curve, new_children);
|
||||
|
||||
std::vector<typename C::Scalar> prior_children;
|
||||
|
||||
@ -265,18 +81,18 @@ typename C::Point CurveTrees<C1, C2>::get_first_parent(const C &curve,
|
||||
|
||||
// Extend prior children by zeroes for any additional new children, since they must be new
|
||||
if (new_children.size() > 1)
|
||||
fcmp::tower_cycle::extend_zeroes(curve, new_children.size() - 1, prior_children);
|
||||
tower_cycle::extend_zeroes(curve, new_children.size() - 1, prior_children);
|
||||
}
|
||||
else if (offset > 0)
|
||||
{
|
||||
// If we're updating the parent hash and no children were updated, then we're just adding new children
|
||||
// to the existing last chunk and can fill priors with 0
|
||||
fcmp::tower_cycle::extend_zeroes(curve, new_children.size(), prior_children);
|
||||
tower_cycle::extend_zeroes(curve, new_children.size(), prior_children);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the last chunk is already full and isn't updated in any way, then we just get a new parent
|
||||
return this->get_new_parent<C>(curve, new_children);
|
||||
return get_new_parent<C>(curve, new_children);
|
||||
}
|
||||
|
||||
return curve.hash_grow(
|
||||
@ -287,22 +103,10 @@ typename C::Point CurveTrees<C1, C2>::get_first_parent(const C &curve,
|
||||
);
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Explicit instantiations
|
||||
template std::vector<Helios::Scalar> CurveTrees<Helios, Selene>::next_child_scalars_from_children(const Selene &c_child,
|
||||
const LastChunkData<Selene> *last_child_chunk_ptr,
|
||||
const LastChunkData<Helios> *last_parent_chunk_ptr,
|
||||
const LayerExtension<Selene> &children);
|
||||
|
||||
template std::vector<Selene::Scalar> CurveTrees<Helios, Selene>::next_child_scalars_from_children(const Helios &c_child,
|
||||
const LastChunkData<Helios> *last_child_chunk_ptr,
|
||||
const LastChunkData<Selene> *last_parent_chunk_ptr,
|
||||
const LayerExtension<Helios> &children);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Implementation
|
||||
template <typename C1, typename C2>
|
||||
// After hashing a layer of children points, convert those children x-coordinates into their respective cycle
|
||||
// scalars, and prepare them to be hashed for the next layer
|
||||
template<typename C_CHILD, typename C_PARENT>
|
||||
std::vector<typename C_PARENT::Scalar> CurveTrees<C1, C2>::next_child_scalars_from_children(const C_CHILD &c_child,
|
||||
static std::vector<typename C_PARENT::Scalar> next_child_scalars_from_children(const C_CHILD &c_child,
|
||||
const LastChunkData<C_CHILD> *last_child_chunk_ptr,
|
||||
const LastChunkData<C_PARENT> *last_parent_chunk_ptr,
|
||||
const LayerExtension<C_CHILD> &children)
|
||||
@ -333,26 +137,9 @@ std::vector<typename C_PARENT::Scalar> CurveTrees<C1, C2>::next_child_scalars_fr
|
||||
return child_scalars;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Explicit instantiations
|
||||
template void CurveTrees<Helios, Selene>::hash_layer(const Helios &curve,
|
||||
const LastChunkData<Helios> *last_parent_chunk_ptr,
|
||||
const std::vector<Helios::Scalar> &child_scalars,
|
||||
const std::size_t children_start_idx,
|
||||
const std::size_t chunk_width,
|
||||
LayerExtension<Helios> &parents_out);
|
||||
|
||||
template void CurveTrees<Helios, Selene>::hash_layer(const Selene &curve,
|
||||
const LastChunkData<Selene> *last_parent_chunk_ptr,
|
||||
const std::vector<Selene::Scalar> &child_scalars,
|
||||
const std::size_t children_start_idx,
|
||||
const std::size_t chunk_width,
|
||||
LayerExtension<Selene> &parents_out);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Implementation
|
||||
template <typename C1, typename C2>
|
||||
// Hash chunks of a layer of new children, outputting the next layer's parents
|
||||
template<typename C>
|
||||
void CurveTrees<C1, C2>::hash_layer(const C &curve,
|
||||
static void hash_layer(const C &curve,
|
||||
const LastChunkData<C> *last_parent_chunk_ptr,
|
||||
const std::vector<typename C::Scalar> &child_scalars,
|
||||
const std::size_t children_start_idx,
|
||||
@ -415,7 +202,7 @@ void CurveTrees<C1, C2>::hash_layer(const C &curve,
|
||||
child_layer_last_hash_updated,
|
||||
last_parent_chunk_ptr,
|
||||
offset)
|
||||
: this->get_new_parent<C>(curve, chunk);
|
||||
: get_new_parent<C>(curve, chunk);
|
||||
|
||||
MDEBUG("Hash chunk_start_idx " << chunk_start_idx << " result: " << curve.to_string(chunk_hash)
|
||||
<< " , chunk_size: " << chunk_size);
|
||||
@ -437,4 +224,169 @@ void CurveTrees<C1, C2>::hash_layer(const C &curve,
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// CurveTrees public member functions
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<>
|
||||
CurveTrees<Helios, Selene>::LeafTuple CurveTrees<Helios, Selene>::output_to_leaf_tuple(
|
||||
const crypto::public_key &O,
|
||||
const crypto::public_key &C) const
|
||||
{
|
||||
crypto::ec_point I;
|
||||
crypto::derive_key_image_generator(O, I);
|
||||
|
||||
return LeafTuple{
|
||||
.O_x = tower_cycle::ed_25519_point_to_scalar(O),
|
||||
.I_x = tower_cycle::ed_25519_point_to_scalar(I),
|
||||
.C_x = tower_cycle::ed_25519_point_to_scalar(C)
|
||||
};
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<typename C1, typename C2>
|
||||
typename CurveTrees<C1, C2>::TreeExtension CurveTrees<C1, C2>::get_tree_extension(
|
||||
const LastChunks &existing_last_chunks,
|
||||
const std::vector<LeafTuple> &new_leaf_tuples)
|
||||
{
|
||||
TreeExtension tree_extension;
|
||||
|
||||
if (new_leaf_tuples.empty())
|
||||
return tree_extension;
|
||||
|
||||
const auto &c1_last_chunks = existing_last_chunks.c1_last_chunks;
|
||||
const auto &c2_last_chunks = existing_last_chunks.c2_last_chunks;
|
||||
|
||||
// Set the leaf start idx
|
||||
tree_extension.leaves.start_idx = c2_last_chunks.empty()
|
||||
? 0
|
||||
: c2_last_chunks[0].child_layer_size;
|
||||
|
||||
// Copy the leaves
|
||||
// TODO: don't copy here
|
||||
tree_extension.leaves.tuples.reserve(new_leaf_tuples.size());
|
||||
for (const auto &leaf : new_leaf_tuples)
|
||||
{
|
||||
tree_extension.leaves.tuples.emplace_back(LeafTuple{
|
||||
.O_x = m_c2.clone(leaf.O_x),
|
||||
.I_x = m_c2.clone(leaf.I_x),
|
||||
.C_x = m_c2.clone(leaf.C_x)
|
||||
});
|
||||
}
|
||||
|
||||
auto &c1_layer_extensions_out = tree_extension.c1_layer_extensions;
|
||||
auto &c2_layer_extensions_out = tree_extension.c2_layer_extensions;
|
||||
|
||||
const std::vector<typename C2::Scalar> flattened_leaves = this->flatten_leaves(new_leaf_tuples);
|
||||
|
||||
// Hash the leaf layer
|
||||
LayerExtension<C2> leaf_parents;
|
||||
hash_layer(m_c2,
|
||||
c2_last_chunks.empty() ? nullptr : &c2_last_chunks[0],
|
||||
flattened_leaves,
|
||||
tree_extension.leaves.start_idx,
|
||||
m_leaf_layer_chunk_width,
|
||||
leaf_parents);
|
||||
|
||||
c2_layer_extensions_out.emplace_back(std::move(leaf_parents));
|
||||
|
||||
// Check if we just added the root
|
||||
if (c2_layer_extensions_out.back().hashes.size() == 1 && c2_layer_extensions_out.back().start_idx == 0)
|
||||
return tree_extension;
|
||||
|
||||
// Alternate between hashing c2 children, c1 children, c2, c1, ...
|
||||
bool parent_is_c1 = true;
|
||||
|
||||
std::size_t c1_last_idx = 0;
|
||||
std::size_t c2_last_idx = 0;
|
||||
// TODO: calculate max number of layers it should take to add all leaves (existing leaves + new leaves)
|
||||
while (true)
|
||||
{
|
||||
const LastChunkData<C1> *c1_last_chunk_ptr = (c1_last_chunks.size() <= c1_last_idx)
|
||||
? nullptr
|
||||
: &c1_last_chunks[c1_last_idx];
|
||||
|
||||
const LastChunkData<C2> *c2_last_chunk_ptr = (c2_last_chunks.size() <= c2_last_idx)
|
||||
? nullptr
|
||||
: &c2_last_chunks[c2_last_idx];
|
||||
|
||||
// TODO: templated function
|
||||
if (parent_is_c1)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c2_layer_extensions_out.size() > c2_last_idx, "missing c2 layer");
|
||||
|
||||
const auto &c2_child_extension = c2_layer_extensions_out[c2_last_idx];
|
||||
|
||||
const auto c1_child_scalars = next_child_scalars_from_children<C2, C1>(m_c2,
|
||||
c2_last_chunk_ptr,
|
||||
c1_last_chunk_ptr,
|
||||
c2_child_extension);
|
||||
|
||||
LayerExtension<C1> c1_layer_extension;
|
||||
hash_layer<C1>(m_c1,
|
||||
c1_last_chunk_ptr,
|
||||
c1_child_scalars,
|
||||
c2_child_extension.start_idx,
|
||||
m_c1_width,
|
||||
c1_layer_extension);
|
||||
|
||||
c1_layer_extensions_out.emplace_back(std::move(c1_layer_extension));
|
||||
|
||||
// Check if we just added the root
|
||||
if (c1_layer_extensions_out.back().hashes.size() == 1 && c1_layer_extensions_out.back().start_idx == 0)
|
||||
return tree_extension;
|
||||
|
||||
++c2_last_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c1_layer_extensions_out.size() > c1_last_idx, "missing c1 layer");
|
||||
|
||||
const auto &c1_child_extension = c1_layer_extensions_out[c1_last_idx];
|
||||
|
||||
const auto c2_child_scalars = next_child_scalars_from_children<C1, C2>(m_c1,
|
||||
c1_last_chunk_ptr,
|
||||
c2_last_chunk_ptr,
|
||||
c1_child_extension);
|
||||
|
||||
LayerExtension<C2> c2_layer_extension;
|
||||
hash_layer<C2>(m_c2,
|
||||
c2_last_chunk_ptr,
|
||||
c2_child_scalars,
|
||||
c1_child_extension.start_idx,
|
||||
m_c2_width,
|
||||
c2_layer_extension);
|
||||
|
||||
c2_layer_extensions_out.emplace_back(std::move(c2_layer_extension));
|
||||
|
||||
// Check if we just added the root
|
||||
if (c2_layer_extensions_out.back().hashes.size() == 1 && c2_layer_extensions_out.back().start_idx == 0)
|
||||
return tree_extension;
|
||||
|
||||
++c1_last_idx;
|
||||
}
|
||||
|
||||
parent_is_c1 = !parent_is_c1;
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// CurveTrees private member functions
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<typename C1, typename C2>
|
||||
std::vector<typename C2::Scalar> CurveTrees<C1, C2>::flatten_leaves(const std::vector<LeafTuple> &leaves) const
|
||||
{
|
||||
std::vector<typename C2::Scalar> flattened_leaves;
|
||||
flattened_leaves.reserve(leaves.size() * LEAF_TUPLE_SIZE);
|
||||
|
||||
for (const auto &l : leaves)
|
||||
{
|
||||
// TODO: implement without cloning
|
||||
flattened_leaves.emplace_back(m_c2.clone(l.O_x));
|
||||
flattened_leaves.emplace_back(m_c2.clone(l.I_x));
|
||||
flattened_leaves.emplace_back(m_c2.clone(l.C_x));
|
||||
}
|
||||
|
||||
return flattened_leaves;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
} //namespace curve_trees
|
||||
} //namespace fcmp
|
||||
|
@ -37,10 +37,45 @@
|
||||
// forward declarations
|
||||
class CurveTreesUnitTest;
|
||||
|
||||
|
||||
namespace fcmp
|
||||
{
|
||||
namespace curve_trees
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Hash a chunk of new children
|
||||
template<typename C>
|
||||
typename C::Point get_new_parent(const C &curve, const typename C::Chunk &new_children);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// A layer of contiguous hashes starting from a specific start_idx in the tree
|
||||
template<typename C>
|
||||
struct LayerExtension final
|
||||
{
|
||||
std::size_t start_idx;
|
||||
std::vector<typename C::Point> hashes;
|
||||
};
|
||||
|
||||
// TODO: longer descriptions
|
||||
// Useful data from the last chunk in a layer
|
||||
template<typename C>
|
||||
struct LastChunkData final
|
||||
{
|
||||
// The total number of children % child layer chunk width
|
||||
const std::size_t child_offset;
|
||||
// The last child in the chunk (and therefore the last child in the child layer)
|
||||
/* TODO: const */ typename C::Scalar last_child;
|
||||
// The hash of the last chunk of child scalars
|
||||
/* TODO: const */ typename C::Point last_parent;
|
||||
// Total number of children in the child layer
|
||||
const std::size_t child_layer_size;
|
||||
// Total number of hashes in the parent layer
|
||||
const std::size_t parent_layer_size;
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// This class is useful help update the curve trees tree without needing to keep the entire tree in memory
|
||||
// - It requires instantiation with the C1 and C2 curve classes and widths, hardening the tree structure
|
||||
// - It ties the C2 curve in the tree to the leaf layer
|
||||
template<typename C1, typename C2>
|
||||
class CurveTrees
|
||||
{
|
||||
@ -72,7 +107,7 @@ public:
|
||||
static const std::size_t LEAF_TUPLE_SIZE = 3;
|
||||
static_assert(sizeof(LeafTuple) == (sizeof(typename C2::Scalar) * LEAF_TUPLE_SIZE), "unexpected LeafTuple size");
|
||||
|
||||
// Leaves in the tree
|
||||
// Contiguous leaves in the tree, starting a specified start_idx in the leaf layer
|
||||
struct Leaves final
|
||||
{
|
||||
// Starting index in the leaf layer
|
||||
@ -81,14 +116,6 @@ public:
|
||||
std::vector<LeafTuple> tuples;
|
||||
};
|
||||
|
||||
// A layer of contiguous hashes starting from a specific start_idx in the tree
|
||||
template<typename C>
|
||||
struct LayerExtension final
|
||||
{
|
||||
std::size_t start_idx;
|
||||
std::vector<typename C::Point> hashes;
|
||||
};
|
||||
|
||||
// A struct useful to extend an existing tree
|
||||
// - layers alternate between C1 and C2
|
||||
// - c2_layer_extensions[0] is first layer after leaves, then c1_layer_extensions[0], c2_layer_extensions[1], etc
|
||||
@ -99,22 +126,6 @@ public:
|
||||
std::vector<LayerExtension<C2>> c2_layer_extensions;
|
||||
};
|
||||
|
||||
// Useful data from the last chunk in a layer
|
||||
template<typename C>
|
||||
struct LastChunkData final
|
||||
{
|
||||
// The total number of children % child layer chunk width
|
||||
/*TODO: const*/ std::size_t child_offset;
|
||||
// The last child in the chunk (and therefore the last child in the child layer)
|
||||
/*TODO: const*/ typename C::Scalar last_child;
|
||||
// The hash of the last chunk of child scalars
|
||||
/*TODO: const*/ typename C::Point last_parent;
|
||||
// Total number of children in the child layer
|
||||
/*TODO: const*/ std::size_t child_layer_size;
|
||||
// Total number of hashes in the parent layer
|
||||
/*TODO: const*/ std::size_t parent_layer_size;
|
||||
};
|
||||
|
||||
// Last chunk data from each layer in the tree
|
||||
// - layers alternate between C1 and C2
|
||||
// - c2_last_chunks[0] is first layer after leaves, then c1_last_chunks[0], then c2_last_chunks[1], etc
|
||||
@ -139,46 +150,24 @@ private:
|
||||
// Flatten leaves [(O.x, I.x, C.x),(O.x, I.x, C.x),...] -> [scalar,scalar,scalar,scalar,scalar,scalar,...]
|
||||
std::vector<typename C2::Scalar> flatten_leaves(const std::vector<LeafTuple> &leaves) const;
|
||||
|
||||
// TODO: make below functions static functions inside curve_trees.cpp
|
||||
// Hash a chunk of new children
|
||||
template <typename C>
|
||||
typename C::Point get_new_parent(const C &curve, const typename C::Chunk &new_children) const;
|
||||
|
||||
// Hash the first chunk of children being added to a layer
|
||||
template <typename C>
|
||||
typename C::Point get_first_parent(const C &curve,
|
||||
const typename C::Chunk &new_children,
|
||||
const std::size_t chunk_width,
|
||||
const bool child_layer_last_hash_updated,
|
||||
const LastChunkData<C> *last_chunk_ptr,
|
||||
const std::size_t offset) const;
|
||||
|
||||
// After hashing a layer of children points, convert those children x-coordinates into their respective cycle
|
||||
// scalars, and prepare them to be hashed for the next layer
|
||||
template<typename C_CHILD, typename C_PARENT>
|
||||
std::vector<typename C_PARENT::Scalar> next_child_scalars_from_children(const C_CHILD &c_child,
|
||||
const LastChunkData<C_CHILD> *last_child_chunk_ptr,
|
||||
const LastChunkData<C_PARENT> *last_parent_chunk_ptr,
|
||||
const LayerExtension<C_CHILD> &children);
|
||||
|
||||
// Hash chunks of a layer of new children, outputting the next layer's parents
|
||||
template<typename C>
|
||||
void hash_layer(const C &curve,
|
||||
const LastChunkData<C> *last_parent_chunk_ptr,
|
||||
const std::vector<typename C::Scalar> &child_scalars,
|
||||
const std::size_t children_start_idx,
|
||||
const std::size_t chunk_width,
|
||||
LayerExtension<C> &parents_out);
|
||||
|
||||
//member variables
|
||||
private:
|
||||
// The curves
|
||||
const C1 &m_c1;
|
||||
const C2 &m_c2;
|
||||
|
||||
// The chunk widths of the layers in the tree tied to each curve
|
||||
const std::size_t m_c1_width;
|
||||
const std::size_t m_c2_width;
|
||||
|
||||
// The leaf layer has a distinct chunk width than the other layers
|
||||
const std::size_t m_leaf_layer_chunk_width;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
using Helios = tower_cycle::Helios;
|
||||
using Selene = tower_cycle::Selene;
|
||||
using CurveTreesV1 = CurveTrees<Helios, Selene>;
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
} //namespace curve_trees
|
||||
} //namespace fcmp
|
||||
|
@ -144,16 +144,7 @@ std::string Selene::to_string(const typename Selene::Point &point) const
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
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");
|
||||
|
||||
// TODO: implement reading just the x coordinate of ed25519 point in C/C++
|
||||
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);
|
||||
}
|
||||
// Exposed helper functions
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Helios::Generators random_helios_generators(std::size_t n)
|
||||
{
|
||||
@ -175,6 +166,61 @@ Selene::Point random_selene_hash_init_point()
|
||||
return fcmp_rust::random_selene_hash_init_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");
|
||||
|
||||
// TODO: implement reading just the x coordinate of ed25519 point in C/C++
|
||||
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);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<typename C>
|
||||
void extend_zeroes(const C &curve,
|
||||
const std::size_t num_zeroes,
|
||||
std::vector<typename C::Scalar> &zeroes_inout)
|
||||
{
|
||||
zeroes_inout.reserve(zeroes_inout.size() + num_zeroes);
|
||||
|
||||
for (std::size_t i = 0; i < num_zeroes; ++i)
|
||||
zeroes_inout.emplace_back(curve.zero_scalar());
|
||||
}
|
||||
|
||||
// Explicit instantiations
|
||||
template void extend_zeroes<Helios>(const Helios &curve,
|
||||
const std::size_t num_zeroes,
|
||||
std::vector<Helios::Scalar> &zeroes_inout);
|
||||
|
||||
template void extend_zeroes<Selene>(const Selene &curve,
|
||||
const std::size_t num_zeroes,
|
||||
std::vector<Selene::Scalar> &zeroes_inout);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<typename C_POINTS, typename C_SCALARS>
|
||||
void extend_scalars_from_cycle_points(const C_POINTS &curve,
|
||||
const std::vector<typename C_POINTS::Point> &points,
|
||||
std::vector<typename C_SCALARS::Scalar> &scalars_out)
|
||||
{
|
||||
scalars_out.reserve(scalars_out.size() + points.size());
|
||||
|
||||
for (const auto &point : points)
|
||||
{
|
||||
// TODO: implement reading just the x coordinate of points on curves in curve cycle in C/C++
|
||||
typename C_SCALARS::Scalar scalar = curve.point_to_cycle_scalar(point);
|
||||
scalars_out.push_back(std::move(scalar));
|
||||
}
|
||||
}
|
||||
|
||||
// Explicit instantiations
|
||||
template void extend_scalars_from_cycle_points<Helios, Selene>(const Helios &curve,
|
||||
const std::vector<Helios::Point> &points,
|
||||
std::vector<Selene::Scalar> &scalars_out);
|
||||
|
||||
template void extend_scalars_from_cycle_points<Selene, Helios>(const Selene &curve,
|
||||
const std::vector<Selene::Point> &points,
|
||||
std::vector<Helios::Scalar> &scalars_out);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
} //namespace tower_cycle
|
||||
} //namespace fcmp
|
||||
|
@ -67,8 +67,7 @@ struct SeleneT final
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Parent curve class that curves in a cycle must implement
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Abstract parent curve class that curves in a cycle must implement
|
||||
template<typename C>
|
||||
class Curve
|
||||
{
|
||||
@ -185,9 +184,6 @@ public:
|
||||
};
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// 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 (WARNING: number of generators must be >= curve's
|
||||
// width, and also need to account for selene leaf layer 3x)
|
||||
Helios::Generators random_helios_generators(std::size_t n);
|
||||
@ -195,35 +191,19 @@ Selene::Generators random_selene_generators(std::size_t n);
|
||||
Helios::Point random_helios_hash_init_point();
|
||||
Selene::Point random_selene_hash_init_point();
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Ed25519 point x-coordinates are Selene scalars
|
||||
SeleneScalar ed_25519_point_to_scalar(const crypto::ec_point &point);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// TODO: implement in cpp file
|
||||
template <typename C>
|
||||
static void extend_zeroes(const C &curve,
|
||||
template<typename C>
|
||||
void extend_zeroes(const C &curve,
|
||||
const std::size_t num_zeroes,
|
||||
std::vector<typename C::Scalar> &zeroes_inout)
|
||||
{
|
||||
zeroes_inout.reserve(zeroes_inout.size() + num_zeroes);
|
||||
|
||||
for (std::size_t i = 0; i < num_zeroes; ++i)
|
||||
zeroes_inout.emplace_back(curve.zero_scalar());
|
||||
}
|
||||
std::vector<typename C::Scalar> &zeroes_inout);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// TODO: move impl into cpp
|
||||
template <typename C_POINTS, typename C_SCALARS>
|
||||
static void extend_scalars_from_cycle_points(const C_POINTS &curve,
|
||||
template<typename C_POINTS, typename C_SCALARS>
|
||||
void extend_scalars_from_cycle_points(const C_POINTS &curve,
|
||||
const std::vector<typename C_POINTS::Point> &points,
|
||||
std::vector<typename C_SCALARS::Scalar> &scalars_out)
|
||||
{
|
||||
scalars_out.reserve(scalars_out.size() + points.size());
|
||||
|
||||
for (const auto &point : points)
|
||||
{
|
||||
// TODO: implement reading just the x coordinate of points on curves in curve cycle in C/C++
|
||||
typename C_SCALARS::Scalar scalar = curve.point_to_cycle_scalar(point);
|
||||
scalars_out.push_back(std::move(scalar));
|
||||
}
|
||||
}
|
||||
std::vector<typename C_SCALARS::Scalar> &scalars_out);
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
}//namespace curves
|
||||
}//namespace tower_cycle
|
||||
}//namespace fcmp
|
||||
|
@ -35,7 +35,7 @@
|
||||
// CurveTreesUnitTest helpers
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<typename C>
|
||||
static CurveTreesV1::LastChunkData<C> get_last_child_layer_chunk(const C &curve,
|
||||
static fcmp::curve_trees::LastChunkData<C> get_last_child_layer_chunk(const C &curve,
|
||||
const std::size_t child_layer_size,
|
||||
const std::size_t parent_layer_size,
|
||||
const std::size_t chunk_width,
|
||||
@ -47,7 +47,7 @@ static CurveTreesV1::LastChunkData<C> get_last_child_layer_chunk(const C &curve,
|
||||
|
||||
const std::size_t child_offset = child_layer_size % chunk_width;
|
||||
|
||||
return CurveTreesV1::LastChunkData<C>{
|
||||
return fcmp::curve_trees::LastChunkData<C>{
|
||||
.child_offset = child_offset,
|
||||
.last_child = curve.clone(last_child),
|
||||
.last_parent = curve.clone(last_parent),
|
||||
@ -56,6 +56,39 @@ static CurveTreesV1::LastChunkData<C> get_last_child_layer_chunk(const C &curve,
|
||||
};
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<typename C_PARENT>
|
||||
static bool validate_layer(const C_PARENT &c_parent,
|
||||
const CurveTreesUnitTest::Layer<C_PARENT> &parents,
|
||||
const std::vector<typename C_PARENT::Scalar> &child_scalars,
|
||||
const std::size_t max_chunk_size)
|
||||
{
|
||||
// Hash chunk of children scalars, then see if the hash matches up to respective parent
|
||||
std::size_t chunk_start_idx = 0;
|
||||
for (std::size_t i = 0; i < parents.size(); ++i)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(child_scalars.size() > chunk_start_idx, false, "chunk start too high");
|
||||
const std::size_t chunk_size = std::min(child_scalars.size() - chunk_start_idx, max_chunk_size);
|
||||
CHECK_AND_ASSERT_MES(child_scalars.size() >= (chunk_start_idx + chunk_size), false, "chunk size too large");
|
||||
|
||||
const typename C_PARENT::Point &parent = parents[i];
|
||||
|
||||
const auto chunk_start = child_scalars.data() + chunk_start_idx;
|
||||
const typename C_PARENT::Chunk chunk{chunk_start, chunk_size};
|
||||
|
||||
const typename C_PARENT::Point chunk_hash = fcmp::curve_trees::get_new_parent(c_parent, chunk);
|
||||
|
||||
const auto actual_bytes = c_parent.to_bytes(parent);
|
||||
const auto expected_bytes = c_parent.to_bytes(chunk_hash);
|
||||
CHECK_AND_ASSERT_MES(actual_bytes == expected_bytes, false, "unexpected hash");
|
||||
|
||||
chunk_start_idx += chunk_size;
|
||||
}
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(chunk_start_idx == child_scalars.size(), "unexpected ending chunk start idx");
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// CurveTreesUnitTest implementations
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
@ -191,7 +224,7 @@ void CurveTreesUnitTest::extend_tree(const CurveTreesV1::TreeExtension &tree_ext
|
||||
if (use_c2)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c2_idx < c2_extensions.size(), "unexpected c2 layer extension");
|
||||
const CurveTreesV1::LayerExtension<Selene> &c2_ext = c2_extensions[c2_idx];
|
||||
const fcmp::curve_trees::LayerExtension<Selene> &c2_ext = c2_extensions[c2_idx];
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(!c2_ext.hashes.empty(), "empty c2 layer extension");
|
||||
|
||||
@ -217,7 +250,7 @@ void CurveTreesUnitTest::extend_tree(const CurveTreesV1::TreeExtension &tree_ext
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c1_idx < c1_extensions.size(), "unexpected c1 layer extension");
|
||||
const CurveTreesV1::LayerExtension<Helios> &c1_ext = c1_extensions[c1_idx];
|
||||
const fcmp::curve_trees::LayerExtension<Helios> &c1_ext = c1_extensions[c1_idx];
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(!c1_ext.hashes.empty(), "empty c1 layer extension");
|
||||
|
||||
@ -245,39 +278,6 @@ void CurveTreesUnitTest::extend_tree(const CurveTreesV1::TreeExtension &tree_ext
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
template<typename C_PARENT>
|
||||
bool CurveTreesUnitTest::validate_layer(const C_PARENT &c_parent,
|
||||
const CurveTreesUnitTest::Layer<C_PARENT> &parents,
|
||||
const std::vector<typename C_PARENT::Scalar> &child_scalars,
|
||||
const std::size_t max_chunk_size)
|
||||
{
|
||||
// Hash chunk of children scalars, then see if the hash matches up to respective parent
|
||||
std::size_t chunk_start_idx = 0;
|
||||
for (std::size_t i = 0; i < parents.size(); ++i)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(child_scalars.size() > chunk_start_idx, false, "chunk start too high");
|
||||
const std::size_t chunk_size = std::min(child_scalars.size() - chunk_start_idx, max_chunk_size);
|
||||
CHECK_AND_ASSERT_MES(child_scalars.size() >= (chunk_start_idx + chunk_size), false, "chunk size too large");
|
||||
|
||||
const typename C_PARENT::Point &parent = parents[i];
|
||||
|
||||
const auto chunk_start = child_scalars.data() + chunk_start_idx;
|
||||
const typename C_PARENT::Chunk chunk{chunk_start, chunk_size};
|
||||
|
||||
const typename C_PARENT::Point chunk_hash = m_curve_trees.get_new_parent(c_parent, chunk);
|
||||
|
||||
const auto actual_bytes = c_parent.to_bytes(parent);
|
||||
const auto expected_bytes = c_parent.to_bytes(chunk_hash);
|
||||
CHECK_AND_ASSERT_MES(actual_bytes == expected_bytes, false, "unexpected hash");
|
||||
|
||||
chunk_start_idx += chunk_size;
|
||||
}
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(chunk_start_idx == child_scalars.size(), "unexpected ending chunk start idx");
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
bool CurveTreesUnitTest::validate_tree(const CurveTreesUnitTest::Tree &tree)
|
||||
{
|
||||
const auto &leaves = tree.leaves;
|
||||
@ -317,7 +317,7 @@ bool CurveTreesUnitTest::validate_tree(const CurveTreesUnitTest::Tree &tree)
|
||||
children,
|
||||
child_scalars);
|
||||
|
||||
const bool valid = this->validate_layer<Selene>(m_curve_trees.m_c2,
|
||||
const bool valid = validate_layer<Selene>(m_curve_trees.m_c2,
|
||||
parents,
|
||||
child_scalars,
|
||||
m_curve_trees.m_c2_width);
|
||||
@ -342,7 +342,7 @@ bool CurveTreesUnitTest::validate_tree(const CurveTreesUnitTest::Tree &tree)
|
||||
children,
|
||||
child_scalars);
|
||||
|
||||
const bool valid = this->validate_layer<Helios>(
|
||||
const bool valid = validate_layer<Helios>(
|
||||
m_curve_trees.m_c1,
|
||||
parents,
|
||||
child_scalars,
|
||||
@ -357,7 +357,7 @@ bool CurveTreesUnitTest::validate_tree(const CurveTreesUnitTest::Tree &tree)
|
||||
}
|
||||
|
||||
// Now validate leaves
|
||||
return this->validate_layer<Selene>(m_curve_trees.m_c2,
|
||||
return validate_layer<Selene>(m_curve_trees.m_c2,
|
||||
c2_layers[0],
|
||||
m_curve_trees.flatten_leaves(leaves),
|
||||
m_curve_trees.m_leaf_layer_chunk_width);
|
||||
@ -382,7 +382,7 @@ void CurveTreesUnitTest::log_last_chunks(const CurveTreesV1::LastChunks &last_ch
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c2_idx < c2_last_chunks.size(), "unexpected c2 layer");
|
||||
|
||||
const CurveTreesV1::LastChunkData<Selene> &last_chunk = c2_last_chunks[c2_idx];
|
||||
const fcmp::curve_trees::LastChunkData<Selene> &last_chunk = c2_last_chunks[c2_idx];
|
||||
|
||||
MDEBUG("child_offset: " << last_chunk.child_offset
|
||||
<< " , last_child: " << m_curve_trees.m_c2.to_string(last_chunk.last_child)
|
||||
@ -396,7 +396,7 @@ void CurveTreesUnitTest::log_last_chunks(const CurveTreesV1::LastChunks &last_ch
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c1_idx < c1_last_chunks.size(), "unexpected c1 layer");
|
||||
|
||||
const CurveTreesV1::LastChunkData<Helios> &last_chunk = c1_last_chunks[c1_idx];
|
||||
const fcmp::curve_trees::LastChunkData<Helios> &last_chunk = c1_last_chunks[c1_idx];
|
||||
|
||||
MDEBUG("child_offset: " << last_chunk.child_offset
|
||||
<< " , last_child: " << m_curve_trees.m_c1.to_string(last_chunk.last_child)
|
||||
@ -441,7 +441,7 @@ void CurveTreesUnitTest::log_tree_extension(const CurveTreesV1::TreeExtension &t
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c2_idx < c2_extensions.size(), "unexpected c2 layer");
|
||||
|
||||
const CurveTreesV1::LayerExtension<Selene> &c2_layer = c2_extensions[c2_idx];
|
||||
const fcmp::curve_trees::LayerExtension<Selene> &c2_layer = c2_extensions[c2_idx];
|
||||
MDEBUG("Selene tree extension start idx: " << c2_layer.start_idx);
|
||||
|
||||
for (std::size_t j = 0; j < c2_layer.hashes.size(); ++j)
|
||||
@ -454,7 +454,7 @@ void CurveTreesUnitTest::log_tree_extension(const CurveTreesV1::TreeExtension &t
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(c1_idx < c1_extensions.size(), "unexpected c1 layer");
|
||||
|
||||
const CurveTreesV1::LayerExtension<Helios> &c1_layer = c1_extensions[c1_idx];
|
||||
const fcmp::curve_trees::LayerExtension<Helios> &c1_layer = c1_extensions[c1_idx];
|
||||
MDEBUG("Helios tree extension start idx: " << c1_layer.start_idx);
|
||||
|
||||
for (std::size_t j = 0; j < c1_layer.hashes.size(); ++j)
|
||||
@ -582,7 +582,7 @@ static void grow_tree_test(Helios &helios,
|
||||
helios_width,
|
||||
selene_width);
|
||||
|
||||
CurveTreesUnitTest curve_trees_accesor{curve_trees};
|
||||
CurveTreesUnitTest curve_trees_accessor{curve_trees};
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(helios_width > 1, "helios width must be > 1");
|
||||
CHECK_AND_ASSERT_THROW_MES(selene_width > 1, "selene width must be > 1");
|
||||
@ -629,7 +629,7 @@ static void grow_tree_test(Helios &helios,
|
||||
MDEBUG("Adding " << init_leaves << " leaves to tree");
|
||||
|
||||
grow_tree(curve_trees,
|
||||
curve_trees_accesor,
|
||||
curve_trees_accessor,
|
||||
init_leaves,
|
||||
global_tree);
|
||||
|
||||
@ -639,7 +639,7 @@ static void grow_tree_test(Helios &helios,
|
||||
MDEBUG("Extending tree by " << ext_leaves << " leaves");
|
||||
|
||||
grow_tree(curve_trees,
|
||||
curve_trees_accesor,
|
||||
curve_trees_accessor,
|
||||
ext_leaves,
|
||||
global_tree);
|
||||
|
||||
|
@ -32,11 +32,11 @@
|
||||
#include "fcmp/tower_cycle.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
using Helios = fcmp::tower_cycle::Helios;
|
||||
using Selene = fcmp::tower_cycle::Selene;
|
||||
|
||||
using CurveTreesV1 = fcmp::CurveTrees<Helios, Selene>;
|
||||
using Helios = fcmp::curve_trees::Helios;
|
||||
using Selene = fcmp::curve_trees::Selene;
|
||||
using CurveTreesV1 = fcmp::curve_trees::CurveTreesV1;
|
||||
|
||||
// Helper class that can access the private members of the CurveTrees class
|
||||
class CurveTreesUnitTest
|
||||
{
|
||||
public:
|
||||
@ -71,14 +71,6 @@ public:
|
||||
void log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension);
|
||||
void log_tree(const CurveTreesUnitTest::Tree &tree);
|
||||
|
||||
//private member functions
|
||||
private:
|
||||
template<typename C_PARENT>
|
||||
bool validate_layer(const C_PARENT &c_parent,
|
||||
const Layer<C_PARENT> &parents,
|
||||
const std::vector<typename C_PARENT::Scalar> &child_scalars,
|
||||
const std::size_t max_chunk_size);
|
||||
|
||||
private:
|
||||
CurveTreesV1 &m_curve_trees;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user