From 19e33239230a403ae9b94e40c1f77818be7bf96e Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Tue, 28 May 2024 17:49:21 +0400 Subject: [PATCH] Cleaned up a bit. --- .../cpp_int_modular/add_unsigned.hpp | 8 +- .../modular/modular_functions_fixed.hpp | 20 +-- .../multiprecision/modular/modular_params.hpp | 3 - .../modular/montgomery_params.hpp | 146 ------------------ 4 files changed, 14 insertions(+), 163 deletions(-) diff --git a/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular/add_unsigned.hpp b/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular/add_unsigned.hpp index 1264d3df65..c8c2296f92 100644 --- a/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular/add_unsigned.hpp +++ b/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular/add_unsigned.hpp @@ -60,8 +60,8 @@ namespace boost { else { limb_type mask = cpp_int_modular_backend::upper_limb_mask; // If we have set any bit above "Bits", then we have a carry. - if (pr[result.size() - 1] & ~mask) { - pr[result.size() - 1] &= mask; + if (result.limbs()[s - 1] & ~mask) { + result.limbs()[s - 1] &= mask; result.set_carry(true); } } @@ -188,8 +188,8 @@ namespace boost { else { limb_type mask = cpp_int_modular_backend::upper_limb_mask; // If we have set any bit above "Bits", then we have a carry. - if (pr[result.size() - 1] & ~mask) { - pr[result.size() - 1] &= mask; + if (result.limbs()[s - 1] & ~mask) { + result.limbs()[s - 1] &= mask; result.set_carry(true); } } diff --git a/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_functions_fixed.hpp b/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_functions_fixed.hpp index 9ead7bef8b..01cede1df4 100644 --- a/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_functions_fixed.hpp +++ b/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_functions_fixed.hpp @@ -194,9 +194,7 @@ namespace boost { } BOOST_MP_CXX14_CONSTEXPR void initialize_montgomery_params() { - if (check_montgomery_constraints(m_mod)) { - find_const_variables(); - } + find_const_variables(); } /* @@ -225,16 +223,18 @@ namespace boost { } BOOST_MP_CXX14_CONSTEXPR void find_const_variables() { - m_montgomery_p_dash = monty_inverse(m_mod.limbs()[0]); + if (check_montgomery_constraints(m_mod)) { + m_montgomery_p_dash = monty_inverse(m_mod.limbs()[0]); - Backend_doubled_padded_limbs r; - eval_bit_set(r, 2 * m_mod.size() * limb_bits); - barrett_reduce(r); + Backend_doubled_padded_limbs r; + eval_bit_set(r, 2 * m_mod.size() * limb_bits); + barrett_reduce(r); - // Here we are intentionally throwing away half of the bits of r, it's correct. - m_montgomery_r2 = static_cast(r); + // Here we are intentionally throwing away half of the bits of r, it's correct. + m_montgomery_r2 = static_cast(r); + } - // Compute 2^Bits - Modulus. + // Compute 2^Bits - Modulus, no matter if modulus is even or odd. Backend_padded_limbs compliment = static_cast(1u), modulus = m_mod; eval_left_shift(compliment, Bits); eval_subtract(compliment, modulus); diff --git a/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_params.hpp b/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_params.hpp index 9b8bc887ed..0445edcc9c 100644 --- a/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_params.hpp +++ b/libs/multiprecision/include/nil/crypto3/multiprecision/modular/modular_params.hpp @@ -59,9 +59,6 @@ namespace boost { } } - // Martun: This needs to be called when setting numbers to 0, which takes lots of time when creating - // empty vectors. - /* Conversion from the regular number A into Montgomery form r*A: Montgomery_reduce((A mod N)*(r^2 mod N)) = Montgomery_reduce(A*r^2 mod N) = A*r mod N, where result is A and get_mod() is N. diff --git a/libs/multiprecision/include/nil/crypto3/multiprecision/modular/montgomery_params.hpp b/libs/multiprecision/include/nil/crypto3/multiprecision/modular/montgomery_params.hpp index 0eaede34c2..bd05ae6aa6 100644 --- a/libs/multiprecision/include/nil/crypto3/multiprecision/modular/montgomery_params.hpp +++ b/libs/multiprecision/include/nil/crypto3/multiprecision/modular/montgomery_params.hpp @@ -35,161 +35,15 @@ namespace boost { */ template class montgomery_params : virtual public base_params { - protected: - template - inline void initialize_montgomery_params(const Number& p) { - this->initialize_base_params(p); - find_const_variables(p); - } - - inline void initialize_montgomery_params(const montgomery_params& p) { - this->initialize_base_params(p); - find_const_variables(p); - } - - /* - * Compute -input^-1 mod 2^limb_bits. Throws an exception if input - * is even. If input is odd, then input and 2^n are relatively prime - * and an inverse exists. - */ - limb_type monty_inverse(limb_type a) { - assert(a % 2 == 1); - - limb_type b = 1; - limb_type r = 0; - - for (size_t i = 0; i != sizeof(limb_type) * CHAR_BIT; ++i) { - const limb_type bi = b % 2; - r >>= 1; - r += bi << (sizeof(limb_type) * CHAR_BIT - 1); - - b -= a * bi; - b >>= 1; - } - - // Now invert in addition space - r = (~static_cast(0) - r) + 1; - - return r; - } - - template - void find_const_variables(const T& pp) { - Backend p = pp; - if (p <= 0 || !(p % 2)) { - return; - } - - m_p_words = this->m_mod.size(); - - m_p_dash = monty_inverse(this->m_mod.limbs()[0]); - - Backend r; - - boost::multiprecision::default_ops::eval_bit_set(r, m_p_words * sizeof(limb_type) * CHAR_BIT); - - m_r2 = r * r; - barrett_params barrettParams(this->m_mod); - barrettParams.barrett_reduce(m_r2); - } - public: montgomery_params() : base_params() { } template explicit montgomery_params(const Number& p) : base_params(p) { - initialize_montgomery_params(p); - } - - inline const Backend& r2() const { - return m_r2; - } - - inline limb_type p_dash() const { - return m_p_dash; - } - - inline size_t p_words() const { - return m_p_words; - } - - template - montgomery_params& operator=(const V& v) { - initialize_montgomery_params(v); - return *this; - } - - inline void montgomery_reduce(Backend& result) const { - using boost::multiprecision::default_ops::eval_multiply_add; - using boost::multiprecision::default_ops::eval_right_shift; - using boost::multiprecision::default_ops::eval_add; - - typedef cpp_int_modular_backend - cpp_three_int_backend; - - const size_t p_size = m_p_words; - const limb_type p_dash = m_p_dash; - const size_t z_size = 2 * (p_words() + 1); - - boost::container::vector z( - result.size(), 0); // container::vector z(result.size(), 0); - for (size_t i = 0; i < result.size(); ++i) { - z[i] = result.limbs()[i]; - } - - if (result.size() < z_size) { - result.resize(z_size, z_size); - z.resize(z_size, 0); - } - - cpp_three_int_backend w(z[0]); - - result.limbs()[0] = w.limbs()[0] * p_dash; - - eval_multiply_add(w, result.limbs()[0], this->m_mod.limbs()[0]); - eval_right_shift(w, sizeof(limb_type) * CHAR_BIT); - - for (size_t i = 1; i != p_size; ++i) { - for (size_t j = 0; j < i; ++j) { - eval_multiply_add(w, result.limbs()[j], this->m_mod.limbs()[i - j]); - } - - eval_add(w, z[i]); - - result.limbs()[i] = w.limbs()[0] * p_dash; - - eval_multiply_add(w, result.limbs()[i], this->m_mod.limbs()[0]); - - eval_right_shift(w, sizeof(limb_type) * CHAR_BIT); - } - - for (size_t i = 0; i != p_size; ++i) { - for (size_t j = i + 1; j != p_size; ++j) { - eval_multiply_add(w, result.limbs()[j], this->m_mod.limbs()[p_size + i - j]); - } - - eval_add(w, z[p_size + i]); - - result.limbs()[i] = w.limbs()[0]; - - eval_right_shift(w, sizeof(limb_type) * CHAR_BIT); - } - - eval_add(w, z[z_size - 1]); - - result.limbs()[p_size] = w.limbs()[0]; - result.limbs()[p_size + 1] = w.limbs()[1]; - -// TODO(mart we cannot resize any more. - if (result.size() != p_size + 1) { - result.resize(p_size + 1, p_size + 1); - } } protected: - Backend m_r2; - limb_type m_p_dash; size_t m_p_words; };