Botan 3.4.0
Crypto and TLS for C&
Public Member Functions | List of all members
Botan::EC_Point_Var_Point_Precompute Class Referencefinal

#include <point_mul.h>

Public Member Functions

 EC_Point_Var_Point_Precompute (const EC_Point &point, RandomNumberGenerator &rng, std::vector< BigInt > &ws)
 
EC_Point mul (const BigInt &k, RandomNumberGenerator &rng, const BigInt &group_order, std::vector< BigInt > &ws) const
 

Detailed Description

Definition at line 41 of file point_mul.h.

Constructor & Destructor Documentation

◆ EC_Point_Var_Point_Precompute()

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

Definition at line 166 of file point_mul.cpp.

168 :
169 m_curve(point.get_curve()), m_p_words(m_curve.get_p().sig_words()), m_window_bits(4) {
170 if(ws.size() < EC_Point::WORKSPACE_SIZE) {
171 ws.resize(EC_Point::WORKSPACE_SIZE);
172 }
173
174 std::vector<EC_Point> U(static_cast<size_t>(1) << m_window_bits);
175 U[0] = point.zero();
176 U[1] = point;
177
178 for(size_t i = 2; i < U.size(); i += 2) {
179 U[i] = U[i / 2].double_of(ws);
180 U[i + 1] = U[i].plus(point, ws);
181 }
182
183 // Hack to handle Blinded_Point_Multiply
184 if(rng.is_seeded()) {
185 BigInt& mask = ws[0];
186 BigInt& mask2 = ws[1];
187 BigInt& mask3 = ws[2];
188 BigInt& new_x = ws[3];
189 BigInt& new_y = ws[4];
190 BigInt& new_z = ws[5];
191 secure_vector<word>& tmp = ws[6].get_word_vector();
192
193 const CurveGFp& curve = U[0].get_curve();
194
195 const size_t p_bits = curve.get_p().bits();
196
197 // Skipping zero point since it can't be randomized
198 for(size_t i = 1; i != U.size(); ++i) {
199 mask.randomize(rng, p_bits - 1, false);
200 // Easy way of ensuring mask != 0
201 mask.set_bit(0);
202
203 curve.sqr(mask2, mask, tmp);
204 curve.mul(mask3, mask, mask2, tmp);
205
206 curve.mul(new_x, U[i].get_x(), mask2, tmp);
207 curve.mul(new_y, U[i].get_y(), mask3, tmp);
208 curve.mul(new_z, U[i].get_z(), mask, tmp);
209
210 U[i].swap_coords(new_x, new_y, new_z);
211 }
212 }
213
214 m_T.resize(U.size() * 3 * m_p_words);
215
216 word* p = &m_T[0];
217 for(size_t i = 0; i != U.size(); ++i) {
218 U[i].get_x().encode_words(p, m_p_words);
219 U[i].get_y().encode_words(p + m_p_words, m_p_words);
220 U[i].get_z().encode_words(p + 2 * m_p_words, m_p_words);
221 p += 3 * m_p_words;
222 }
223}
size_t sig_words() const
Definition bigint.h:584
const BigInt & get_p() const
Definition curve_gfp.h:118

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

Member Function Documentation

◆ mul()

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

Definition at line 225 of file point_mul.cpp.

228 {
229 if(k.is_negative()) {
230 throw Invalid_Argument("EC_Point_Var_Point_Precompute scalar must be positive");
231 }
232 if(ws.size() < EC_Point::WORKSPACE_SIZE) {
233 ws.resize(EC_Point::WORKSPACE_SIZE);
234 }
235
236 // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure)
237 const BigInt mask(rng, blinding_size(group_order), false);
238 const BigInt scalar = k + group_order * mask;
239
240 const size_t elem_size = 3 * m_p_words;
241 const size_t window_elems = static_cast<size_t>(1) << m_window_bits;
242
243 size_t windows = round_up(scalar.bits(), m_window_bits) / m_window_bits;
244 EC_Point R(m_curve);
245 secure_vector<word> e(elem_size);
246
247 if(windows > 0) {
248 windows--;
249
250 const uint32_t w = scalar.get_substring(windows * m_window_bits, m_window_bits);
251
252 clear_mem(e.data(), e.size());
253 for(size_t i = 1; i != window_elems; ++i) {
254 const auto wmask = CT::Mask<word>::is_equal(w, i);
255
256 for(size_t j = 0; j != elem_size; ++j) {
257 e[j] |= wmask.if_set_return(m_T[i * elem_size + j]);
258 }
259 }
260
261 R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2 * m_p_words], m_p_words, ws);
262
263 /*
264 Randomize after adding the first nibble as before the addition R
265 is zero, and we cannot effectively randomize the point
266 representation of the zero point.
267 */
268 R.randomize_repr(rng, ws[0].get_word_vector());
269 }
270
271 while(windows) {
272 R.mult2i(m_window_bits, ws);
273
274 const uint32_t w = scalar.get_substring((windows - 1) * m_window_bits, m_window_bits);
275
276 clear_mem(e.data(), e.size());
277 for(size_t i = 1; i != window_elems; ++i) {
278 const auto wmask = CT::Mask<word>::is_equal(w, i);
279
280 for(size_t j = 0; j != elem_size; ++j) {
281 e[j] |= wmask.if_set_return(m_T[i * elem_size + j]);
282 }
283 }
284
285 R.add(&e[0], m_p_words, &e[m_p_words], m_p_words, &e[2 * m_p_words], m_p_words, ws);
286
287 windows--;
288 }
289
290 BOTAN_DEBUG_ASSERT(R.on_the_curve());
291
292 return R;
293}
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
static constexpr Mask< T > is_equal(T x, T y)
Definition ct_utils.h:134
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:120
size_t round_up(size_t n, size_t align_to)
Definition rounding.h:21

References Botan::EC_Point::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::EC_Point::mult2i(), Botan::EC_Point::on_the_curve(), Botan::EC_Point::randomize_repr(), Botan::round_up(), and Botan::EC_Point::WORKSPACE_SIZE.

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


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