@@ -27,6 +27,7 @@ static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx
27
27
ctx -> built = 0 ;
28
28
secp256k1_scalar_clear (& ctx -> scalar_offset );
29
29
secp256k1_ge_clear (& ctx -> ge_offset );
30
+ secp256k1_fe_clear (& ctx -> proj_blind );
30
31
}
31
32
32
33
/* Compute the scalar (2^COMB_BITS - 1) / 2, the difference between the gn argument to
@@ -256,6 +257,8 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
256
257
if (EXPECT (first , 0 )) {
257
258
/* If this is the first table lookup, we can skip addition. */
258
259
secp256k1_gej_set_ge (r , & add );
260
+ /* Give the entry a random Z coordinate to blind intermediary results. */
261
+ secp256k1_gej_rescale (r , & ctx -> proj_blind );
259
262
first = 0 ;
260
263
} else {
261
264
secp256k1_gej_add_ge (r , r , & add );
@@ -283,6 +286,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const
283
286
secp256k1_scalar b ;
284
287
secp256k1_scalar diff ;
285
288
secp256k1_gej gb ;
289
+ secp256k1_fe f ;
286
290
unsigned char nonce32 [32 ];
287
291
secp256k1_rfc6979_hmac_sha256 rng ;
288
292
unsigned char keydata [64 ];
@@ -294,6 +298,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const
294
298
/* When seed is NULL, reset the final point and blinding value. */
295
299
secp256k1_ge_neg (& ctx -> ge_offset , & secp256k1_ge_const_g );
296
300
secp256k1_scalar_add (& ctx -> scalar_offset , & secp256k1_scalar_one , & diff );
301
+ ctx -> proj_blind = secp256k1_fe_one ;
297
302
return ;
298
303
}
299
304
/* The prior blinding value (if not reset) is chained forward by including it in the hash. */
@@ -307,7 +312,11 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const
307
312
secp256k1_rfc6979_hmac_sha256_initialize (& rng , keydata , 64 );
308
313
memset (keydata , 0 , sizeof (keydata ));
309
314
310
- /* TODO: reintroduce projective blinding. */
315
+ /* Compute projective blinding factor (cannot be 0). */
316
+ secp256k1_rfc6979_hmac_sha256_generate (& rng , nonce32 , 32 );
317
+ secp256k1_fe_set_b32_mod (& f , nonce32 );
318
+ secp256k1_fe_cmov (& f , & secp256k1_fe_one , secp256k1_fe_normalizes_to_zero (& f ));
319
+ ctx -> proj_blind = f ;
311
320
312
321
/* For a random blinding value b, set scalar_offset=diff-b, ge_offset=bG */
313
322
secp256k1_rfc6979_hmac_sha256_generate (& rng , nonce32 , 32 );
@@ -325,6 +334,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const
325
334
/* Clean up. */
326
335
secp256k1_scalar_clear (& b );
327
336
secp256k1_gej_clear (& gb );
337
+ secp256k1_fe_clear (& f );
328
338
}
329
339
330
340
#endif /* SECP256K1_ECMULT_GEN_IMPL_H */
0 commit comments