Skip to content

Commit

Permalink
Allow signed numbers in modular adaptor. (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
martun authored May 16, 2024
1 parent f7b49f1 commit 643884f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ namespace boost {
cpp_int_modular_backend<Bits>& result,
const cpp_int_modular_backend<Bits>& a,
const cpp_int_modular_backend<Bits>& b) noexcept {
BOOST_ASSERT(!eval_lt(a, b));

//
// This is the generic, C++ only version of subtraction.
// It's also used for all BOOST_MP_CXX14_CONSTEXPR branches, hence the name.
Expand Down Expand Up @@ -178,6 +180,7 @@ namespace boost {
cpp_int_modular_backend<Bits>& result,
const cpp_int_modular_backend<Bits>& a,
const cpp_int_modular_backend<Bits>& b) noexcept {
BOOST_ASSERT(!eval_lt(a, b));

#ifndef TO3_MP_NO_CONSTEXPR_DETECTION
if (BOOST_MP_IS_CONST_EVALUATED(a.size())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <nil/crypto3/multiprecision/modular/modular_params_fixed.hpp>
#include <nil/crypto3/multiprecision/traits/is_backend.hpp>

namespace boost {
namespace boost {
namespace multiprecision {
namespace backends {
template<typename Backend, typename StorageType>
Expand Down Expand Up @@ -52,6 +52,15 @@ namespace boost {
}

typedef typename Backend::unsigned_types unsigned_types;
// We will allow signed types to be assigned to number<modular_adaptor<>> ...
#ifdef TVM
using signed_types = std::tuple<int, signed_limb_type, signed_double_limb_type>;
#else
using signed_types = typename std::conditional<
is_trivial_cpp_int_modular<Backend>::value,
std::tuple<signed char, short, int, long, boost::long_long_type, signed_double_limb_type>,
std::tuple<signed_limb_type, signed_double_limb_type>>::type;
#endif

BOOST_MP_CXX14_CONSTEXPR modular_adaptor() {
}
Expand Down Expand Up @@ -80,9 +89,15 @@ namespace boost {
template<typename SI,
typename std::enable_if_t<std::is_integral<SI>::value && std::is_signed<SI>::value> const * = nullptr>
BOOST_MP_CXX14_CONSTEXPR modular_adaptor(SI b)
: m_base(b >= 0 ?
static_cast<typename std::tuple_element<0, unsigned_types>::type>(b) :
this->mod_data().get_mod() - static_cast<typename std::tuple_element<0, unsigned_types>::type>(-b) ) {
: m_base(static_cast<typename std::tuple_element<0, unsigned_types>::type>(0)) {

if (b >= 0) {
m_base = static_cast<typename std::tuple_element<0, unsigned_types>::type>(b);
} else {
m_base = this->mod_data().get_mod();
eval_subtract(m_base, static_cast<typename std::tuple_element<0, unsigned_types>::type>(-b) );
}

// This method must be called only for compile time modular params.
// this->set_modular_params(m);
this->mod_data().adjust_modular(m_base);
Expand All @@ -97,6 +112,22 @@ namespace boost {
this->mod_data().adjust_modular(m_base);
}

template<typename SI,
typename std::enable_if_t<std::is_integral<SI>::value && std::is_signed<SI>::value> const * = nullptr>
BOOST_MP_CXX14_CONSTEXPR modular_adaptor(SI b, const modular_type &m)
: m_base(static_cast<typename std::tuple_element<0, unsigned_types>::type>(0)) {

if (b >= 0) {
m_base = static_cast<typename std::tuple_element<0, unsigned_types>::type>(b);
} else {
m_base = this->mod_data().get_mod();
eval_subtract(m_base, static_cast<typename std::tuple_element<0, unsigned_types>::type>(-b));
}

this->set_modular_params(m);
this->mod_data().adjust_modular(m_base);
}

template<typename UI,
typename std::enable_if_t<std::is_integral<UI>::value && std::is_unsigned<UI>::value> const * = nullptr>
BOOST_MP_CXX14_CONSTEXPR modular_adaptor(UI b, const modular_type &m)
Expand Down

0 comments on commit 643884f

Please sign in to comment.