Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit

Permalink
Cleaned up a bit.
Browse files Browse the repository at this point in the history
  • Loading branch information
martun committed May 28, 2024
1 parent f6da84f commit 19e3323
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 163 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ namespace boost {
else {
limb_type mask = cpp_int_modular_backend<Bits>::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);
}
}
Expand Down Expand Up @@ -188,8 +188,8 @@ namespace boost {
else {
limb_type mask = cpp_int_modular_backend<Bits>::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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

/*
Expand Down Expand Up @@ -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<Backend>(r);
// Here we are intentionally throwing away half of the bits of r, it's correct.
m_montgomery_r2 = static_cast<Backend>(r);
}

// Compute 2^Bits - Modulus.
// Compute 2^Bits - Modulus, no matter if modulus is even or odd.
Backend_padded_limbs compliment = static_cast<limb_type>(1u), modulus = m_mod;
eval_left_shift(compliment, Bits);
eval_subtract(compliment, modulus);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,161 +35,15 @@ namespace boost {
*/
template<typename Backend>
class montgomery_params : virtual public base_params<Backend> {
protected:
template<typename Number>
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<Backend>& 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<limb_type>(0) - r) + 1;

return r;
}

template<typename T>
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<Backend> barrettParams(this->m_mod);
barrettParams.barrett_reduce(m_r2);
}

public:
montgomery_params() : base_params<Backend>() {
}

template<typename Number>
explicit montgomery_params(const Number& p) : base_params<Backend>(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<class V>
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<sizeof(limb_type) * CHAR_BIT * 3>
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<limb_type> z(
result.size(), 0); // container::vector<limb_type, alloc> 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;

};
Expand Down

0 comments on commit 19e3323

Please sign in to comment.