Botan 2.19.1
Crypto and TLS for C&
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 202 of file point_mul.cpp.

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

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

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 }
#define BOTAN_DEBUG_ASSERT(expr)
Definition: assert.h:123
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:149
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:115
size_t round_up(size_t n, size_t align_to)
Definition: rounding.h:21

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

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


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