Botan 3.0.0-alpha0
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 179 of file point_mul.cpp.

181 :
182 m_curve(point.get_curve()),
183 m_p_words(m_curve.get_p().sig_words()),
184 m_window_bits(4)
185 {
186 if(ws.size() < PointGFp::WORKSPACE_SIZE)
187 ws.resize(PointGFp::WORKSPACE_SIZE);
188
189 std::vector<PointGFp> U(static_cast<size_t>(1) << m_window_bits);
190 U[0] = point.zero();
191 U[1] = point;
192
193 for(size_t i = 2; i < U.size(); i += 2)
194 {
195 U[i] = U[i/2].double_of(ws);
196 U[i+1] = U[i].plus(point, ws);
197 }
198
199 // Hack to handle Blinded_Point_Multiply
200 if(rng.is_seeded())
201 {
202 BigInt& mask = ws[0];
203 BigInt& mask2 = ws[1];
204 BigInt& mask3 = ws[2];
205 BigInt& new_x = ws[3];
206 BigInt& new_y = ws[4];
207 BigInt& new_z = ws[5];
208 secure_vector<word>& tmp = ws[6].get_word_vector();
209
210 const CurveGFp& curve = U[0].get_curve();
211
212 const size_t p_bits = curve.get_p().bits();
213
214 // Skipping zero point since it can't be randomized
215 for(size_t i = 1; i != U.size(); ++i)
216 {
217 mask.randomize(rng, p_bits - 1, false);
218 // Easy way of ensuring mask != 0
219 mask.set_bit(0);
220
221 curve.sqr(mask2, mask, tmp);
222 curve.mul(mask3, mask, mask2, tmp);
223
224 curve.mul(new_x, U[i].get_x(), mask2, tmp);
225 curve.mul(new_y, U[i].get_y(), mask3, tmp);
226 curve.mul(new_z, U[i].get_z(), mask, tmp);
227
228 U[i].swap_coords(new_x, new_y, new_z);
229 }
230 }
231
232 m_T.resize(U.size() * 3 * m_p_words);
233
234 word* p = &m_T[0];
235 for(size_t i = 0; i != U.size(); ++i)
236 {
237 U[i].get_x().encode_words(p , m_p_words);
238 U[i].get_y().encode_words(p + m_p_words, m_p_words);
239 U[i].get_z().encode_words(p + 2*m_p_words, m_p_words);
240 p += 3*m_p_words;
241 }
242 }
size_t sig_words() const
Definition: bigint.h:600
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 244 of file point_mul.cpp.

248 {
249 if(k.is_negative())
250 throw Invalid_Argument("PointGFp_Var_Point_Precompute scalar must be positive");
251 if(ws.size() < PointGFp::WORKSPACE_SIZE)
252 ws.resize(PointGFp::WORKSPACE_SIZE);
253
254 // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure)
255 const BigInt mask(rng, blinding_size(group_order), false);
256 const BigInt scalar = k + group_order * mask;
257
258 const size_t elem_size = 3*m_p_words;
259 const size_t window_elems = static_cast<size_t>(1) << m_window_bits;
260
261 size_t windows = round_up(scalar.bits(), m_window_bits) / m_window_bits;
262 PointGFp R(m_curve);
263 secure_vector<word> e(elem_size);
264
265 if(windows > 0)
266 {
267 windows--;
268
269 const uint32_t w = scalar.get_substring(windows*m_window_bits, m_window_bits);
270
271 clear_mem(e.data(), e.size());
272 for(size_t i = 1; i != window_elems; ++i)
273 {
274 const auto wmask = CT::Mask<word>::is_equal(w, i);
275
276 for(size_t j = 0; j != elem_size; ++j)
277 {
278 e[j] |= wmask.if_set_return(m_T[i * elem_size + j]);
279 }
280 }
281
282 R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws);
283
284 /*
285 Randomize after adding the first nibble as before the addition R
286 is zero, and we cannot effectively randomize the point
287 representation of the zero point.
288 */
289 R.randomize_repr(rng, ws[0].get_word_vector());
290 }
291
292 while(windows)
293 {
294 R.mult2i(m_window_bits, ws);
295
296 const uint32_t w = scalar.get_substring((windows-1)*m_window_bits, m_window_bits);
297
298 clear_mem(e.data(), e.size());
299 for(size_t i = 1; i != window_elems; ++i)
300 {
301 const auto wmask = CT::Mask<word>::is_equal(w, i);
302
303 for(size_t j = 0; j != elem_size; ++j)
304 {
305 e[j] |= wmask.if_set_return(m_T[i * elem_size + j]);
306 }
307 }
308
309 R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2*m_p_words], m_p_words, ws);
310
311 windows--;
312 }
313
314 BOTAN_DEBUG_ASSERT(R.on_the_curve());
315
316 return R;
317 }
#define BOTAN_DEBUG_ASSERT(expr)
Definition: assert.h:122
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:147
constexpr 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: