Botan  2.19.1
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 41 of file point_mul.h.

Constructor & Destructor Documentation

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

Definition at line 202 of file point_mul.cpp.

References Botan::BigInt::bits(), Botan::PointGFp::double_of(), Botan::CurveGFp::get_p(), Botan::BigInt::get_word_vector(), Botan::RandomNumberGenerator::is_seeded(), Botan::CurveGFp::mul(), Botan::PointGFp::plus(), Botan::BigInt::randomize(), Botan::BigInt::set_bit(), Botan::CurveGFp::sqr(), Botan::PointGFp::WORKSPACE_SIZE, and Botan::PointGFp::zero().

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

Member Function Documentation

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

Definition at line 267 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().

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