aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/ec_group/point_mul.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-06-20 19:34:45 -0400
committerJack Lloyd <[email protected]>2018-06-20 19:34:45 -0400
commitcae2d0f3b80483b4d1318afade42a466b63f33e0 (patch)
tree0b3cb302f340cbfcb163817dddd54f530a2d6ab2 /src/lib/pubkey/ec_group/point_mul.cpp
parent4288e3be60ed1af49f9295252a7ca086b1d7ef4a (diff)
Use masked table lookups for variable point scalar mult
Diffstat (limited to 'src/lib/pubkey/ec_group/point_mul.cpp')
-rw-r--r--src/lib/pubkey/ec_group/point_mul.cpp40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/lib/pubkey/ec_group/point_mul.cpp b/src/lib/pubkey/ec_group/point_mul.cpp
index d0c0e2034..d8086df7f 100644
--- a/src/lib/pubkey/ec_group/point_mul.cpp
+++ b/src/lib/pubkey/ec_group/point_mul.cpp
@@ -231,7 +231,7 @@ PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k,
std::vector<BigInt>& ws) const
{
if(k.is_negative())
- throw Invalid_Argument("PointGFp_Base_Point_Precompute scalar must be positive");
+ throw Invalid_Argument("PointGFp_Var_Point_Precompute scalar must be positive");
if(ws.size() < PointGFp::WORKSPACE_SIZE)
ws.resize(PointGFp::WORKSPACE_SIZE);
@@ -239,21 +239,32 @@ PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k,
const BigInt mask(rng, PointGFp_SCALAR_BLINDING_BITS, false);
const BigInt scalar = k + group_order * mask;
- const size_t scalar_bits = scalar.bits();
const size_t elem_size = 3*m_p_words;
+ const size_t window_elems = (1ULL << m_window_bits);
- size_t windows = round_up(scalar_bits, m_window_bits) / m_window_bits;
-
+ size_t windows = round_up(scalar.bits(), m_window_bits) / m_window_bits;
PointGFp R(m_curve);
+ secure_vector<word> e(elem_size);
if(windows > 0)
{
windows--;
// cache side channel here, we are relying on blinding...
- const uint32_t nibble = scalar.get_substring(windows*m_window_bits, m_window_bits);
- const word* w = &m_T[nibble * elem_size];
- R.add(w, m_p_words, w + m_p_words, m_p_words, w + 2*m_p_words, m_p_words, ws);
+ const uint32_t w = scalar.get_substring(windows*m_window_bits, m_window_bits);
+
+ clear_mem(e.data(), e.size());
+ for(size_t i = 1; i != window_elems; ++i)
+ {
+ const word mask = CT::is_equal<word>(w, i);
+
+ for(size_t j = 0; j != elem_size; ++j)
+ {
+ e[j] |= mask & m_T[i * elem_size + j];
+ }
+ }
+
+ R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws);
/*
Randomize after adding the first nibble as before the addition R
@@ -268,9 +279,18 @@ PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k,
R.mult2i(m_window_bits, ws);
// cache side channel here, we are relying on blinding...
- const uint32_t nibble = scalar.get_substring((windows-1)*m_window_bits, m_window_bits);
- const word* w = &m_T[nibble * elem_size];
- R.add(w, m_p_words, w + m_p_words, m_p_words, w + 2*m_p_words, m_p_words, ws);
+ const uint32_t w = scalar.get_substring((windows-1)*m_window_bits, m_window_bits);
+
+ clear_mem(e.data(), e.size());
+ for(size_t i = 1; i != window_elems; ++i)
+ {
+ const word mask = CT::is_equal<word>(w, i);
+
+ for(size_t j = 0; j != elem_size; ++j)
+ e[j] |= mask & m_T[i * elem_size + j];
+ }
+
+ R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws);
windows--;
}