Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [[alloc] init] C++ Cryptography Suite
# [[alloc] init] C++ Cryptography Suite

[![Twitter](https://img.shields.io/twitter/follow/alloc_init_)](https://twitter.com/alloc_init_)
[![Telegram](https://img.shields.io/badge/Telegram-2CA5E0?style=flat-square&logo=telegram&logoColor=dark)](https://t.me/alloc_init)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,20 @@ namespace nil {
return res;
}

template<typename CurveElementType>
std::enable_if_t<is_curve_element<CurveElementType>::value, CurveElementType> constexpr
operator*(const CurveElementType &point, const std::size_t &multiplier) {
template<CurveElement CurveElementType>
constexpr CurveElementType operator*(const CurveElementType &point, const std::size_t &multiplier) {
typename CurveElementType::params_type::scalar_field_type::value_type scalar(multiplier);
return point * scalar;
}

template<typename CurveElementType>
std::enable_if_t<is_curve_element<CurveElementType>::value, CurveElementType> constexpr
operator*(const std::size_t &multiplier, const CurveElementType &point) {
template<CurveElement CurveElementType>
constexpr CurveElementType operator*(const std::size_t &multiplier, const CurveElementType &point) {
typename CurveElementType::params_type::scalar_field_type::value_type scalar(multiplier);
return point * scalar;
}

template<typename CurveElementType>
std::enable_if_t<is_curve_element<CurveElementType>::value, bool>
subgroup_check(CurveElementType point) {
template<CurveElement CurveElementType>
bool subgroup_check(CurveElementType point) {
auto scalar_modulus = CurveElementType::group_type::curve_type::scalar_field_type::modulus;
scalar_mul_inplace(point, scalar_modulus);
return point.is_zero();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ namespace nil {
namespace algebra {
namespace curves {
namespace detail {
// TODO: temporary implementation due to absence of GroupValueType type_trait
// Should be implemented as class method
template<typename GroupValueType, typename = typename std::enable_if<is_curve_group<
typename GroupValueType::group_type>::value>::type>
template<CurveElement GroupValueType>
requires CurveGroup<typename GroupValueType::group_type>
bool subgroup_check(const GroupValueType &p) {
return (p * GroupValueType::group_type::curve_type::q).is_zero();
}
Expand Down
6 changes: 3 additions & 3 deletions libs/algebra/include/nil/crypto3/algebra/random_element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ namespace nil {
return typename field_type::value_type(data);
}

template<typename CurveGroupType,
template<CurveGroup CurveGroupType,
typename DistributionType =
boost::random::uniform_int_distribution<typename CurveGroupType::field_type::integral_type>,
typename UniformRandomBitGenerator = boost::random::random_device>
typename std::enable_if<is_curve_group<CurveGroupType>::value, typename CurveGroupType::value_type>::
type constexpr random_element(UniformRandomBitGenerator &&rng = UniformRandomBitGenerator()) {
constexpr typename CurveGroupType::value_type
random_element(UniformRandomBitGenerator &&rng = UniformRandomBitGenerator()) {

using curve_type = typename CurveGroupType::curve_type;
using field_type = typename curve_type::scalar_field_type;
Expand Down
123 changes: 30 additions & 93 deletions libs/algebra/include/nil/crypto3/algebra/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,96 +31,12 @@
#include <cstddef>
#include <type_traits>

#include <boost/type_traits.hpp>
#include <boost/tti/tti.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/multiprecision/cpp_int.hpp>

namespace nil {
namespace crypto3 {
namespace algebra {

using namespace boost::mpl::placeholders;

BOOST_TTI_HAS_TYPE(iterator)
BOOST_TTI_HAS_TYPE(const_iterator)

BOOST_TTI_HAS_TYPE(params_type)
BOOST_TTI_HAS_TYPE(curve_type)
BOOST_TTI_HAS_TYPE(field_type)
BOOST_TTI_HAS_TYPE(value_type)
BOOST_TTI_HAS_TYPE(base_field_type)
BOOST_TTI_HAS_TYPE(scalar_field_type)
BOOST_TTI_HAS_TYPE(gt_type)

// BOOST_TTI_HAS_TYPE(g1_type) does not work properly on g1_type since it is a template
template<typename, typename = std::void_t<>>
struct has_type_g1_type : std::false_type { };
template<typename T>
struct has_type_g1_type<T, std::void_t<typename T::template g1_type<>>> : std::true_type { };

// BOOST_TTI_HAS_TYPE(g2_type) does not work properly on g2_type since it is a template
template<typename, typename = std::void_t<>>
struct has_type_g2_type : std::false_type { };
template<typename T>
struct has_type_g2_type<T, std::void_t<typename T::template g2_type<>>> : std::true_type { };

BOOST_TTI_HAS_TYPE(group_type)

BOOST_TTI_HAS_STATIC_MEMBER_DATA(base_field_modulus)

BOOST_TTI_HAS_STATIC_MEMBER_DATA(scalar_field_modulus)

BOOST_TTI_HAS_STATIC_MEMBER_DATA(p)

BOOST_TTI_HAS_STATIC_MEMBER_DATA(q)

BOOST_TTI_HAS_FUNCTION(to_affine)

BOOST_TTI_HAS_FUNCTION(to_special)

BOOST_TTI_HAS_FUNCTION(is_special)
BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(zero)

BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(one)

BOOST_TTI_HAS_FUNCTION(is_zero)

BOOST_TTI_HAS_FUNCTION(is_well_formed)

BOOST_TTI_HAS_FUNCTION(double_inplace)

BOOST_TTI_HAS_FUNCTION(mixed_add)

template<typename T>
struct is_curve {
static constexpr bool value = has_type_base_field_type<T>::value &&
has_type_scalar_field_type<T>::value && has_type_g1_type<T>::value;
};

/** @brief is typename T either g1 or g2 group */
template<typename T>
struct is_curve_group {
static constexpr bool value = has_type_params_type<T>::value &&
has_type_curve_type<T, is_curve<_1>>::value &&
has_type_field_type<T>::value && has_type_value_type<T>::value;
};

template<typename T>
struct is_curve_element {
static const bool value =
has_type_field_type<T>::value && has_type_group_type<T>::value &&
has_static_member_function_zero<T, T>::value && has_static_member_function_one<T, T>::value &&
has_function_is_zero<const T, bool>::value && has_function_is_well_formed<const T, bool>::value &&
has_function_double_inplace<T, void>::value;
};

template<typename T>
struct has_mixed_add {
static const bool value = has_function_mixed_add<T, void, boost::mpl::vector<T const &>>::value;
};

template<typename T>
concept FieldValue = requires(const T &a, const T &b, const boost::multiprecision::cpp_int &exponent) {
typename T::field_type;
Expand Down Expand Up @@ -168,22 +84,43 @@ namespace nil {
};

template<typename T>
struct is_complex : std::false_type { };
concept Curve = requires {
typename T::base_field_type;
typename T::scalar_field_type;
typename T::template g1_type<>;
requires Field<typename T::base_field_type>;
requires Field<typename T::scalar_field_type>;
};

template<typename T>
struct is_complex<std::complex<T>> : std::true_type { };
concept CurveWithG2 = Curve<T> && requires { typename T::template g2_type<>; };

template<typename T>
constexpr bool is_complex_v = is_complex<T>::value;
concept CurveWithTargetGroup = Curve<T> && requires { typename T::gt_type; };

template<typename T>
struct remove_complex {
using type = T;
concept CurveElement = requires(T &value, const T &const_value) {
typename T::field_type;
typename T::group_type;
{ T::zero() } -> std::convertible_to<T>;
{ T::one() } -> std::convertible_to<T>;
{ const_value.is_zero() } -> std::convertible_to<bool>;
{ const_value.is_well_formed() } -> std::convertible_to<bool>;
{ value.double_inplace() } -> std::same_as<void>;
};

template<typename T>
struct remove_complex<std::complex<T>> {
using type = T;
concept CurveGroup = requires {
typename T::params_type;
typename T::curve_type;
typename T::field_type;
typename T::value_type;
requires Curve<typename T::curve_type>;
requires Field<typename T::field_type>;
requires CurveElement<typename T::value_type>;
requires std::same_as<typename T::value_type::group_type, T>;
};
template<typename T>
using remove_complex_t = typename remove_complex<T>::type;

} // namespace algebra
} // namespace crypto3
} // namespace nil
Expand Down
55 changes: 0 additions & 55 deletions libs/algebra/include/nil/crypto3/detail/assert.hpp

This file was deleted.

4 changes: 2 additions & 2 deletions libs/algebra/test/bench_test/curves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void benchmark_curve_operations(std::string const& curve_name) {
bench_name("G1 scalar multiplication"),
[](typename g1_type::value_type& A, typename scalar_field::value_type const& B) { return A *= B; });

if constexpr (has_type_g2_type<curve_type>::value) {
if constexpr (CurveWithG2<curve_type>) {
using g2_type = typename curve_type::template g2_type<>;

using g2_field = typename g2_type::field_type;
Expand Down Expand Up @@ -131,7 +131,7 @@ void benchmark_curve_operations(std::string const& curve_name) {
std::cout << "Curve " << curve_name << " does not have G2, skipping benchmarks" << std::endl;
}

if constexpr (has_type_gt_type<curve_type>::value) {
if constexpr (CurveWithTargetGroup<curve_type>) {
using gt_type = typename curve_type::gt_type;

run_benchmark<gt_type, gt_type>(
Expand Down
41 changes: 9 additions & 32 deletions libs/algebra/test/type_traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,12 @@ template<typename value_type>
void test_field_value_types() {
static_assert(FieldElementWithCoordinates<value_type>);

BOOST_ASSERT(has_type_field_type<value_type>::value);
BOOST_ASSERT((has_function_is_zero<const value_type, bool>::value));
BOOST_ASSERT((has_static_member_function_zero<value_type, const value_type &>::value));
BOOST_ASSERT((has_static_member_function_one<value_type, const value_type &>::value));

BOOST_ASSERT(FieldValue<value_type>);
static_assert(FieldValue<value_type>);
}

template<typename field_type>
void test_field_types() {
BOOST_ASSERT(has_type_value_type<field_type>::value);

BOOST_ASSERT(Field<field_type>);
static_assert(Field<field_type>);

test_field_value_types<typename field_type::value_type>();
}
Expand All @@ -85,58 +78,42 @@ template<typename field_type>
void test_extended_field_types() {
test_field_types<field_type>();

BOOST_ASSERT(ExtendedField<field_type>);

BOOST_ASSERT(ExtendedFieldValue<typename field_type::value_type>);
static_assert(ExtendedField<field_type>);
static_assert(ExtendedFieldValue<typename field_type::value_type>);

test_field_value_types<typename field_type::value_type>();
}

template<typename curve_group_type>
void test_curve_group_types() {
BOOST_ASSERT(is_curve_group<curve_group_type>::value);
BOOST_ASSERT(has_type_curve_type<curve_group_type>::value);

BOOST_ASSERT(has_type_value_type<curve_group_type>::value);
static_assert(CurveGroup<curve_group_type>);
using value_type = typename curve_group_type::value_type;

BOOST_ASSERT(has_type_field_type<value_type>::value);
BOOST_ASSERT(has_type_group_type<value_type>::value);

BOOST_ASSERT((has_static_member_function_zero<value_type, value_type>::value));
BOOST_ASSERT((has_static_member_function_one<value_type, value_type>::value));
BOOST_ASSERT((has_function_is_zero<const value_type, bool>::value));
BOOST_ASSERT((has_function_is_well_formed<const value_type, bool>::value));
BOOST_ASSERT((has_function_double_inplace<value_type, void>::value));

BOOST_ASSERT(is_curve_element<value_type>::value);
static_assert(CurveElement<value_type>);
}

template<typename curve_type>
void test_ordinary_curve_types() {
BOOST_ASSERT(has_type_base_field_type<curve_type>::value);
test_field_types<typename curve_type::base_field_type>();

BOOST_ASSERT(has_type_scalar_field_type<curve_type>::value);
test_field_types<typename curve_type::scalar_field_type>();

BOOST_ASSERT(has_type_g1_type<curve_type>::value);
test_curve_group_types<typename curve_type::template g1_type<>>();

BOOST_ASSERT(is_curve<curve_type>::value);
static_assert(Curve<curve_type>);
}

template<typename curve_type>
void test_pairing_friendly_curve_types() {
test_ordinary_curve_types<curve_type>();

BOOST_ASSERT(has_type_g2_type<curve_type>::value);
static_assert(CurveWithG2<curve_type>);
test_curve_group_types<typename curve_type::template g2_type<>>();

using g2_base_field = typename curve_type::template g2_type<>::params_type::field_type;
test_extended_field_types<g2_base_field>();

BOOST_ASSERT(has_type_gt_type<curve_type>::value);
static_assert(CurveWithTargetGroup<curve_type>);
test_extended_field_types<typename curve_type::gt_type>();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ namespace nil {
template<typename T, typename Enabled>
class is_compatible;

template<typename T>
class is_compatible<T, typename std::enable_if<nil::crypto3::algebra::is_curve_element<T>::value>::type> {
template<nil::crypto3::algebra::CurveElement T>
class is_compatible<T, void> {
using default_endianness = option::big_endian;

public:
Expand Down
Loading
Loading