Botan  2.11.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 44 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 193 of file point_mul.cpp.

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

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 258 of file point_mul.cpp.

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

References BOTAN_DEBUG_ASSERT, Botan::clear_mem(), e, Botan::elem_size, Botan::CT::Mask< T >::is_equal(), Botan::rng, Botan::round_up(), scalar, and Botan::ws.


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