Botan  2.13.0
Crypto and TLS for C++11
Public Member Functions | List of all members
Botan::PointGFp_Var_Point_Precompute Class Referencefinal

#include <point_mul.h>

Public Member Functions

PointGFp mul (const BigInt &k, RandomNumberGenerator &rng, const BigInt &group_order, std::vector< BigInt > &ws) const
 
 PointGFp_Var_Point_Precompute (const PointGFp &point, RandomNumberGenerator &rng, std::vector< BigInt > &ws)
 

Detailed Description

Definition at line 42 of file point_mul.h.

Constructor & Destructor Documentation

◆ PointGFp_Var_Point_Precompute()

Botan::PointGFp_Var_Point_Precompute::PointGFp_Var_Point_Precompute ( const PointGFp point,
RandomNumberGenerator rng,
std::vector< BigInt > &  ws 
)

Definition at line 199 of file point_mul.cpp.

201  :
202  m_curve(point.get_curve()),
203  m_p_words(m_curve.get_p().sig_words()),
204  m_window_bits(4)
205  {
206  if(ws.size() < PointGFp::WORKSPACE_SIZE)
207  ws.resize(PointGFp::WORKSPACE_SIZE);
208 
209  std::vector<PointGFp> U(static_cast<size_t>(1) << m_window_bits);
210  U[0] = point.zero();
211  U[1] = point;
212 
213  for(size_t i = 2; i < U.size(); i += 2)
214  {
215  U[i] = U[i/2].double_of(ws);
216  U[i+1] = U[i].plus(point, ws);
217  }
218 
219  // Hack to handle Blinded_Point_Multiply
220  if(rng.is_seeded())
221  {
222  BigInt& mask = ws[0];
223  BigInt& mask2 = ws[1];
224  BigInt& mask3 = ws[2];
225  BigInt& new_x = ws[3];
226  BigInt& new_y = ws[4];
227  BigInt& new_z = ws[5];
228  secure_vector<word>& tmp = ws[6].get_word_vector();
229 
230  const CurveGFp& curve = U[0].get_curve();
231 
232  const size_t p_bits = curve.get_p().bits();
233 
234  // Skipping zero point since it can't be randomized
235  for(size_t i = 1; i != U.size(); ++i)
236  {
237  mask.randomize(rng, p_bits - 1, false);
238  // Easy way of ensuring mask != 0
239  mask.set_bit(0);
240 
241  curve.sqr(mask2, mask, tmp);
242  curve.mul(mask3, mask, mask2, tmp);
243 
244  curve.mul(new_x, U[i].get_x(), mask2, tmp);
245  curve.mul(new_y, U[i].get_y(), mask3, tmp);
246  curve.mul(new_z, U[i].get_z(), mask, tmp);
247 
248  U[i].swap_coords(new_x, new_y, new_z);
249  }
250  }
251 
252  m_T.resize(U.size() * 3 * m_p_words);
253 
254  word* p = &m_T[0];
255  for(size_t i = 0; i != U.size(); ++i)
256  {
257  U[i].get_x().encode_words(p , m_p_words);
258  U[i].get_y().encode_words(p + m_p_words, m_p_words);
259  U[i].get_z().encode_words(p + 2*m_p_words, m_p_words);
260  p += 3*m_p_words;
261  }
262  }
size_t sig_words() const
Definition: bigint.h:584
const BigInt & get_p() const
Definition: curve_gfp.h:134

Member Function Documentation

◆ mul()

PointGFp Botan::PointGFp_Var_Point_Precompute::mul ( const BigInt k,
RandomNumberGenerator rng,
const BigInt group_order,
std::vector< BigInt > &  ws 
) const

Definition at line 264 of file point_mul.cpp.

References Botan::BigInt::bits(), BOTAN_DEBUG_ASSERT, Botan::clear_mem(), Botan::BigInt::get_substring(), Botan::CT::Mask< T >::is_equal(), Botan::BigInt::is_negative(), Botan::round_up(), and Botan::PointGFp::WORKSPACE_SIZE.

Referenced by Botan::EC_Group::blinded_var_point_multiply().

268  {
269  if(k.is_negative())
270  throw Invalid_Argument("PointGFp_Var_Point_Precompute scalar must be positive");
271  if(ws.size() < PointGFp::WORKSPACE_SIZE)
272  ws.resize(PointGFp::WORKSPACE_SIZE);
273 
274  // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure)
275  const BigInt mask(rng, PointGFp_SCALAR_BLINDING_BITS, false);
276  const BigInt scalar = k + group_order * mask;
277 
278  const size_t elem_size = 3*m_p_words;
279  const size_t window_elems = (1ULL << m_window_bits);
280 
281  size_t windows = round_up(scalar.bits(), m_window_bits) / m_window_bits;
282  PointGFp R(m_curve);
283  secure_vector<word> e(elem_size);
284 
285  if(windows > 0)
286  {
287  windows--;
288 
289  const uint32_t w = scalar.get_substring(windows*m_window_bits, m_window_bits);
290 
291  clear_mem(e.data(), e.size());
292  for(size_t i = 1; i != window_elems; ++i)
293  {
294  const auto wmask = CT::Mask<word>::is_equal(w, i);
295 
296  for(size_t j = 0; j != elem_size; ++j)
297  {
298  e[j] |= wmask.if_set_return(m_T[i * elem_size + j]);
299  }
300  }
301 
302  R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws);
303 
304  /*
305  Randomize after adding the first nibble as before the addition R
306  is zero, and we cannot effectively randomize the point
307  representation of the zero point.
308  */
309  R.randomize_repr(rng, ws[0].get_word_vector());
310  }
311 
312  while(windows)
313  {
314  R.mult2i(m_window_bits, ws);
315 
316  const uint32_t w = scalar.get_substring((windows-1)*m_window_bits, m_window_bits);
317 
318  clear_mem(e.data(), e.size());
319  for(size_t i = 1; i != window_elems; ++i)
320  {
321  const auto wmask = CT::Mask<word>::is_equal(w, i);
322 
323  for(size_t j = 0; j != elem_size; ++j)
324  {
325  e[j] |= wmask.if_set_return(m_T[i * elem_size + j]);
326  }
327  }
328 
329  R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws);
330 
331  windows--;
332  }
333 
334  BOTAN_DEBUG_ASSERT(R.on_the_curve());
335 
336  return R;
337  }
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:112
#define BOTAN_DEBUG_ASSERT(expr)
Definition: assert.h:123
size_t round_up(size_t n, size_t align_to)
Definition: rounding.h:21
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:149

The documentation for this class was generated from the following files: