Botan  2.15.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 41 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 201 of file point_mul.cpp.

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

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