Optimization: move (2^COMB_BITS-1)/2 term into ctx->scalar_offset
It is unnecessary to recompute this term needed by the SDMC algorithm for every multiplication; move it into the context scalar_offset value instead.
This commit is contained in:
@@ -103,7 +103,7 @@ typedef struct {
|
||||
|
||||
/* Values chosen such that
|
||||
*
|
||||
* n*G == comb(n + (2^COMB_BITS-1)/2 + scalar_offset, G/2) + ge_offset.
|
||||
* n*G == comb(n + scalar_offset, G/2) + ge_offset.
|
||||
*
|
||||
* This expression lets us use scalar blinding and optimize the comb precomputation. See
|
||||
* ecmult_gen_impl.h for more details. */
|
||||
|
||||
@@ -91,19 +91,17 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
|
||||
*
|
||||
* Adding precomputation, our final equations become:
|
||||
*
|
||||
* ctx->scalar_offset = -b
|
||||
* ctx->scalar_offset = (2^COMB_BITS - 1)/2 - b (mod order)
|
||||
* ctx->ge_offset = b*G
|
||||
* d = gn + ctx->scalar_offset + (2^COMB_BITS - 1)/2 (mod order)
|
||||
* d = gn + ctx->scalar_offset (mod order)
|
||||
* R = comb(d, G/2) + ctx->ge_offset
|
||||
*
|
||||
* comb(d, G/2) function is then computed by summing + or - 2^(i-1)*G, for i=0..COMB_BITS-1,
|
||||
* depending on the value of the bits d[i] of the binary representation of scalar d.
|
||||
*/
|
||||
|
||||
/* Compute the scalar d = (gn + ctx->scalar_offset + (2^COMB_BITS - 1)/2). */
|
||||
secp256k1_ecmult_gen_scalar_diff(&d);
|
||||
secp256k1_scalar_add(&d, &d, &ctx->scalar_offset);
|
||||
secp256k1_scalar_add(&d, &d, gn);
|
||||
/* Compute the scalar d = (gn + ctx->scalar_offset). */
|
||||
secp256k1_scalar_add(&d, &ctx->scalar_offset, gn);
|
||||
|
||||
/* In secp256k1_ecmult_gen_prec_table we have precomputed sums of the
|
||||
* (2*d[i]-1) * 2^(i-1) * G points, for various combinations of i positions.
|
||||
@@ -245,14 +243,19 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
|
||||
/* Setup blinding values for secp256k1_ecmult_gen. */
|
||||
static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) {
|
||||
secp256k1_scalar b;
|
||||
secp256k1_scalar diff;
|
||||
secp256k1_gej gb;
|
||||
unsigned char nonce32[32];
|
||||
secp256k1_rfc6979_hmac_sha256 rng;
|
||||
unsigned char keydata[64];
|
||||
|
||||
/* Compute the (2^COMB_BITS - 1)/2 term once. */
|
||||
secp256k1_ecmult_gen_scalar_diff(&diff);
|
||||
|
||||
if (seed32 == NULL) {
|
||||
/* When seed is NULL, reset the final point and blinding value. */
|
||||
secp256k1_ge_neg(&ctx->ge_offset, &secp256k1_ge_const_g);
|
||||
ctx->scalar_offset = secp256k1_scalar_one;
|
||||
secp256k1_scalar_add(&ctx->scalar_offset, &secp256k1_scalar_one, &diff);
|
||||
return;
|
||||
}
|
||||
/* The prior blinding value (if not reset) is chained forward by including it in the hash. */
|
||||
@@ -268,7 +271,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const
|
||||
|
||||
/* TODO: reintroduce projective blinding. */
|
||||
|
||||
/* For a random blinding value b, set ctx->scalar_offset=-b, ctx->ge_offset=bG. */
|
||||
/* For a random blinding value b, set scalar_offset=diff-b, ge_offset=bG */
|
||||
secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
|
||||
secp256k1_scalar_set_b32(&b, nonce32, NULL);
|
||||
/* The blinding value cannot be zero, as that would mean ge_offset = infinity,
|
||||
@@ -278,7 +281,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const
|
||||
memset(nonce32, 0, 32);
|
||||
secp256k1_ecmult_gen(ctx, &gb, &b);
|
||||
secp256k1_scalar_negate(&b, &b);
|
||||
ctx->scalar_offset = b;
|
||||
secp256k1_scalar_add(&ctx->scalar_offset, &b, &diff);
|
||||
secp256k1_ge_set_gej(&ctx->ge_offset, &gb);
|
||||
|
||||
/* Clean up. */
|
||||
|
||||
Reference in New Issue
Block a user