BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& k) const { const size_t exp_nibbles = (k.bits() + m_window_bits - 1) / m_window_bits; BigInt x = m_R_mod; const size_t z_size = 2*(m_p_words + 1); BigInt z(BigInt::Positive, z_size); secure_vector<word> workspace(z.size()); secure_vector<word> e(m_p_words); for(size_t i = exp_nibbles; i > 0; --i) { for(size_t j = 0; j != m_window_bits; ++j) { bigint_monty_sqr(z, x, m_p.data(), m_p_words, m_mod_prime, workspace.data()); x = z; } const uint32_t nibble = k.get_substring(m_window_bits*(i-1), m_window_bits); BigInt::const_time_lookup(e, m_g, nibble); bigint_mul(z.mutable_data(), z.size(), x.data(), x.size(), x.sig_words(), e.data(), m_p_words, m_p_words, workspace.data()); bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_mod_prime, workspace.data()); x = z; } x.grow_to(2*m_p_words + 1); bigint_monty_redc(x.mutable_data(), m_p.data(), m_p_words, m_mod_prime, workspace.data()); return x; }
/* * Compute the result */ BigInt Montgomery_Exponentiator::execute() const { const size_t exp_nibbles = (m_exp_bits + m_window_bits - 1) / m_window_bits; BigInt x = m_R_mod; const size_t z_size = 2*(m_mod_words + 1); BigInt z(BigInt::Positive, z_size); secure_vector<word> workspace(z.size()); for(size_t i = exp_nibbles; i > 0; --i) { for(size_t k = 0; k != m_window_bits; ++k) { bigint_monty_sqr(z, x, m_modulus.data(), m_mod_words, m_mod_prime, workspace.data()); x = z; } const u32bit nibble = m_exp.get_substring(m_window_bits*(i-1), m_window_bits); const BigInt& y = m_g[nibble]; bigint_monty_mul(z, x, y, m_modulus.data(), m_mod_words, m_mod_prime, workspace.data()); x = z; } x.grow_to(2*m_mod_words + 1); bigint_monty_redc(x.mutable_data(), m_modulus.data(), m_mod_words, m_mod_prime, workspace.data()); return x; }
// Montgomery squaring void PointGFp::monty_sqr(BigInt& z, const BigInt& x) const { //assert(&z != &x); if(x.is_zero()) { z = 0; return; } const BigInt& p = curve.get_p(); const size_t p_size = curve.get_p_words(); const word p_dash = curve.get_p_dash(); SecureVector<word>& z_reg = z.get_reg(); z_reg.resize(2*p_size+1); zeroise(z_reg); bigint_monty_sqr(&z_reg[0], z_reg.size(), x.data(), x.size(), x.sig_words(), p.data(), p_size, p_dash, &ws[0]); }