diff --git a/src/ecmult_gen.h b/src/ecmult_gen.h index edac5a8b..ba0c818a 100644 --- a/src/ecmult_gen.h +++ b/src/ecmult_gen.h @@ -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. */ diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index b8b40038..9995c877 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -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. */