Montgomery_Exponentation_State::Montgomery_Exponentation_State(const BigInt& g, const BigInt& p, const Modular_Reducer& mod_p, size_t window_bits) : m_p(p), m_p_words(p.sig_words()), m_window_bits(window_bits) { if(p.is_positive() == false || p.is_even()) throw Invalid_Argument("Cannot use Montgomery reduction on even or negative integer"); if(window_bits > 12) // really even 8 is too large ... throw Invalid_Argument("Montgomery window bits too large"); m_mod_prime = monty_inverse(m_p.word_at(0)); const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); m_R_mod = mod_p.reduce(r); m_R2_mod = mod_p.square(m_R_mod); m_g.resize(1U << m_window_bits); BigInt z(BigInt::Positive, 2 * (m_p_words + 1)); secure_vector<word> workspace(z.size()); m_g[0] = 1; bigint_monty_mul(z, m_g[0], m_R2_mod, m_p.data(), m_p_words, m_mod_prime, workspace.data()); m_g[0] = z; m_g[1] = mod_p.reduce(g); bigint_monty_mul(z, m_g[1], m_R2_mod, m_p.data(), m_p_words, m_mod_prime, workspace.data()); m_g[1] = z; const BigInt& x = m_g[1]; for(size_t i = 2; i != m_g.size(); ++i) { const BigInt& y = m_g[i-1]; bigint_monty_mul(z, x, y, m_p.data(), m_p_words, m_mod_prime, workspace.data()); m_g[i] = z; m_g[i].shrink_to_fit(); m_g[i].grow_to(m_p_words); } }
Montgomery_Params::Montgomery_Params(const BigInt& p, const Modular_Reducer& mod_p) { if(p.is_even() || p < 3) throw Invalid_Argument("Montgomery_Params invalid modulus"); m_p = p; m_p_words = m_p.sig_words(); m_p_dash = monty_inverse(m_p.word_at(0)); const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS); m_r1 = mod_p.reduce(r); m_r2 = mod_p.square(m_r1); m_r3 = mod_p.multiply(m_r1, m_r2); }