void Montgomery_Params::square_this(BigInt& x, secure_vector<word>& ws) const { const size_t output_size = 2*m_p_words + 2; if(ws.size() < 2*output_size) ws.resize(2*output_size); word* z_data = &ws[0]; word* ws_data = &ws[output_size]; BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); bigint_sqr(z_data, output_size, x.data(), x.size(), std::min(m_p_words, x.size()), ws_data, output_size); bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size); if(x.size() < output_size) x.grow_to(output_size); copy_mem(x.mutable_data(), z_data, output_size); }
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; }
void bigint_monty_sqr(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, const word p[], size_t p_size, word p_dash, word ws[]) { bigint_sqr(&z[0], z_size, &ws[0], &x[0], x_size, x_sw); bigint_monty_redc(&z[0], &p[0], p_size, p_dash, &ws[0]); }
BigInt Montgomery_Params::redc(const BigInt& x, secure_vector<word>& ws) const { const size_t output_size = 2*m_p_words + 2; if(ws.size() < output_size) ws.resize(output_size); BigInt z = x; z.grow_to(output_size); bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size()); return z; }
BigInt Montgomery_Params::sqr(const BigInt& x, secure_vector<word>& ws) const { const size_t output_size = 2*m_p_words + 2; if(ws.size() < output_size) ws.resize(output_size); BigInt z(BigInt::Positive, output_size); BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); bigint_sqr(z.mutable_data(), z.size(), x.data(), x.size(), std::min(m_p_words, x.size()), ws.data(), ws.size()); bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size()); return z; }
/* * 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; }