diff --git a/src/bench_ecmult.c b/src/bench_ecmult.c index bcf8b431..c7c6aded 100644 --- a/src/bench_ecmult.c +++ b/src/bench_ecmult.c @@ -259,7 +259,7 @@ static void bench_ecmult_multi_teardown(void* arg, int iters) { } } -static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) { +static void generate_scalar(const secp256k1_context *ctx, uint32_t num, secp256k1_scalar* scalar) { secp256k1_sha256 sha256; unsigned char c[10] = {'e', 'c', 'm', 'u', 'l', 't', 0, 0, 0, 0}; unsigned char buf[32]; @@ -269,8 +269,8 @@ static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) { c[8] = num >> 16; c[9] = num >> 24; secp256k1_sha256_initialize(&sha256); - secp256k1_sha256_write(&sha256, c, sizeof(c)); - secp256k1_sha256_finalize(&sha256, buf); + secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &sha256, c, sizeof(c)); + secp256k1_sha256_finalize(secp256k1_get_hash_context(ctx), &sha256, buf); secp256k1_scalar_set_b32(scalar, buf, &overflow); CHECK(!overflow); } @@ -362,7 +362,7 @@ int main(int argc, char **argv) { secp256k1_gej_set_ge(&data.pubkeys_gej[0], &secp256k1_ge_const_g); secp256k1_scalar_set_int(&data.seckeys[0], 1); for (i = 0; i < POINTS; ++i) { - generate_scalar(i, &data.scalars[i]); + generate_scalar(data.ctx, i, &data.scalars[i]); if (i) { secp256k1_gej_double_var(&data.pubkeys_gej[i], &data.pubkeys_gej[i - 1], NULL); secp256k1_scalar_add(&data.seckeys[i], &data.seckeys[i - 1], &data.seckeys[i - 1]); diff --git a/src/bench_internal.c b/src/bench_internal.c index 001bd25e..44f8d2cb 100644 --- a/src/bench_internal.c +++ b/src/bench_internal.c @@ -38,6 +38,7 @@ static void help(int default_iters) { } typedef struct { + const secp256k1_context* ctx; secp256k1_scalar scalar[2]; secp256k1_fe fe[4]; secp256k1_ge ge[2]; @@ -82,6 +83,9 @@ static void bench_setup(void* arg) { } }; + /* Customize context if needed */ + data->ctx = secp256k1_context_static; + secp256k1_scalar_set_b32(&data->scalar[0], init[0], NULL); secp256k1_scalar_set_b32(&data->scalar[1], init[1], NULL); secp256k1_fe_set_b32_limit(&data->fe[0], init[0]); @@ -344,11 +348,12 @@ static void bench_sha256(void* arg, int iters) { int i; bench_inv *data = (bench_inv*)arg; secp256k1_sha256 sha; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(data->ctx); for (i = 0; i < iters; i++) { secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, data->data, 32); - secp256k1_sha256_finalize(&sha, data->data); + secp256k1_sha256_write(hash_ctx, &sha, data->data, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, data->data); } } @@ -356,11 +361,12 @@ static void bench_hmac_sha256(void* arg, int iters) { int i; bench_inv *data = (bench_inv*)arg; secp256k1_hmac_sha256 hmac; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(data->ctx); for (i = 0; i < iters; i++) { - secp256k1_hmac_sha256_initialize(&hmac, data->data, 32); - secp256k1_hmac_sha256_write(&hmac, data->data, 32); - secp256k1_hmac_sha256_finalize(&hmac, data->data); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, data->data, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, data->data, 32); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, data->data); } } @@ -368,10 +374,11 @@ static void bench_rfc6979_hmac_sha256(void* arg, int iters) { int i; bench_inv *data = (bench_inv*)arg; secp256k1_rfc6979_hmac_sha256 rng; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(data->ctx); for (i = 0; i < iters; i++) { - secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 64); - secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32); + secp256k1_rfc6979_hmac_sha256_initialize(hash_ctx, &rng, data->data, 64); + secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, data->data, 32); } } diff --git a/src/ecmult_gen.h b/src/ecmult_gen.h index 43dd10c3..8bc4f14c 100644 --- a/src/ecmult_gen.h +++ b/src/ecmult_gen.h @@ -7,6 +7,7 @@ #ifndef SECP256K1_ECMULT_GEN_H #define SECP256K1_ECMULT_GEN_H +#include "hash.h" #include "scalar.h" #include "group.h" @@ -132,12 +133,12 @@ typedef struct { secp256k1_fe proj_blind; } secp256k1_ecmult_gen_context; -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_hash_ctx *hash_ctx); static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); /** Multiply with the generator: R = a*G */ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const secp256k1_hash_ctx *hash_ctx, const unsigned char *seed32); #endif /* SECP256K1_ECMULT_GEN_H */ diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 2159eed5..5a954977 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -14,8 +14,8 @@ #include "hash_impl.h" #include "precomputed_ecmult_gen.h" -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx) { - secp256k1_ecmult_gen_blind(ctx, NULL); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, const secp256k1_hash_ctx *hash_ctx) { + secp256k1_ecmult_gen_blind(ctx, hash_ctx, NULL); ctx->built = 1; } @@ -282,7 +282,7 @@ 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) { +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const secp256k1_hash_ctx *hash_ctx, const unsigned char *seed32) { secp256k1_scalar b; secp256k1_scalar diff; secp256k1_gej gb; @@ -309,17 +309,17 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const */ VERIFY_CHECK(seed32 != NULL); memcpy(keydata + 32, seed32, 32); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, 64); + secp256k1_rfc6979_hmac_sha256_initialize(hash_ctx, &rng, keydata, 64); secp256k1_memclear_explicit(keydata, sizeof(keydata)); /* Compute projective blinding factor (cannot be 0). */ - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, nonce32, 32); secp256k1_fe_set_b32_mod(&f, nonce32); secp256k1_fe_cmov(&f, &secp256k1_fe_one, secp256k1_fe_normalizes_to_zero(&f)); ctx->proj_blind = f; /* For a random blinding value b, set scalar_offset=diff-b, ge_offset=bG */ - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, nonce32, 32); secp256k1_scalar_set_b32(&b, nonce32, NULL); /* The blinding value cannot be zero, as that would mean ge_offset = infinity, * which secp256k1_gej_add_ge cannot handle. */ diff --git a/src/hash.h b/src/hash.h index 43cdd60c..35825eae 100644 --- a/src/hash.h +++ b/src/hash.h @@ -10,6 +10,14 @@ #include #include +typedef void (*secp256k1_sha256_compression_function)(uint32_t *state, const unsigned char *blocks64, size_t n_blocks); + +typedef struct { + secp256k1_sha256_compression_function fn_sha256_compression; +} secp256k1_hash_ctx; + +static void secp256k1_hash_ctx_init(secp256k1_hash_ctx *hash_ctx); + typedef struct { uint32_t s[8]; unsigned char buf[64]; @@ -21,17 +29,17 @@ static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); * The byte counter must be a multiple of 64, i.e., there must be no unwritten * bytes in the buffer. */ static void secp256k1_sha256_initialize_midstate(secp256k1_sha256 *hash, uint64_t bytes, const uint32_t state[8]); -static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); -static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); +static void secp256k1_sha256_write(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, unsigned char *out32); static void secp256k1_sha256_clear(secp256k1_sha256 *hash); typedef struct { secp256k1_sha256 inner, outer; } secp256k1_hmac_sha256; -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); +static void secp256k1_hmac_sha256_initialize(const secp256k1_hash_ctx *hash_ctx, secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); +static void secp256k1_hmac_sha256_write(const secp256k1_hash_ctx *hash_ctx, secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_hmac_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp256k1_hmac_sha256 *hash, unsigned char *out32); static void secp256k1_hmac_sha256_clear(secp256k1_hmac_sha256 *hash); typedef struct { @@ -40,8 +48,8 @@ typedef struct { int retry; } secp256k1_rfc6979_hmac_sha256; -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); +static void secp256k1_rfc6979_hmac_sha256_initialize(const secp256k1_hash_ctx *hash_ctx, secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); +static void secp256k1_rfc6979_hmac_sha256_generate(const secp256k1_hash_ctx *hash_ctx, secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); static void secp256k1_rfc6979_hmac_sha256_clear(secp256k1_rfc6979_hmac_sha256 *rng); diff --git a/src/hash_impl.h b/src/hash_impl.h index da3b4660..d5f16cd1 100644 --- a/src/hash_impl.h +++ b/src/hash_impl.h @@ -48,7 +48,7 @@ static void secp256k1_sha256_initialize_midstate(secp256k1_sha256 *hash, uint64_ } /** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */ -static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* buf) { +static void secp256k1_sha256_transform_impl(uint32_t* s, const unsigned char* buf) { uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; @@ -130,17 +130,31 @@ static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* buf) { s[7] += h; } -static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t len) { +static void secp256k1_sha256_transform(uint32_t *state, const unsigned char *blocks64, size_t n_blocks) { + while (n_blocks--) { + secp256k1_sha256_transform_impl(state, blocks64); + blocks64 += 64; + } +} + +static void secp256k1_hash_ctx_init(secp256k1_hash_ctx *hash_ctx) { + VERIFY_CHECK(hash_ctx != NULL); + hash_ctx->fn_sha256_compression = secp256k1_sha256_transform; +} + +static void secp256k1_sha256_write(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *data, size_t len) { size_t bufsize = hash->bytes & 0x3F; hash->bytes += len; VERIFY_CHECK(hash->bytes >= len); + VERIFY_CHECK(hash_ctx != NULL); + VERIFY_CHECK(hash_ctx->fn_sha256_compression != NULL); while (len >= 64 - bufsize) { /* Fill the buffer, and process it. */ size_t chunk_len = 64 - bufsize; memcpy(hash->buf + bufsize, data, chunk_len); data += chunk_len; len -= chunk_len; - secp256k1_sha256_transform(hash->s, hash->buf); + hash_ctx->fn_sha256_compression(hash->s, hash->buf, 1); bufsize = 0; } if (len) { @@ -149,7 +163,7 @@ static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char * } } -static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32) { +static void secp256k1_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, unsigned char *out32) { static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; int i; @@ -157,8 +171,8 @@ static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out VERIFY_CHECK(hash->bytes < ((uint64_t)1 << 61)); secp256k1_write_be32(&sizedesc[0], hash->bytes >> 29); secp256k1_write_be32(&sizedesc[4], hash->bytes << 3); - secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); - secp256k1_sha256_write(hash, sizedesc, 8); + secp256k1_sha256_write(hash_ctx, hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); + secp256k1_sha256_write(hash_ctx, hash, sizedesc, 8); for (i = 0; i < 8; i++) { secp256k1_write_be32(&out32[4*i], hash->s[i]); hash->s[i] = 0; @@ -167,22 +181,22 @@ static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out /* Initializes a sha256 struct and writes the 64 byte string * SHA256(tag)||SHA256(tag) into it. */ -static void secp256k1_sha256_initialize_tagged(secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen) { +static void secp256k1_sha256_initialize_tagged(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen) { unsigned char buf[32]; secp256k1_sha256_initialize(hash); - secp256k1_sha256_write(hash, tag, taglen); - secp256k1_sha256_finalize(hash, buf); + secp256k1_sha256_write(hash_ctx, hash, tag, taglen); + secp256k1_sha256_finalize(hash_ctx, hash, buf); secp256k1_sha256_initialize(hash); - secp256k1_sha256_write(hash, buf, 32); - secp256k1_sha256_write(hash, buf, 32); + secp256k1_sha256_write(hash_ctx, hash, buf, 32); + secp256k1_sha256_write(hash_ctx, hash, buf, 32); } static void secp256k1_sha256_clear(secp256k1_sha256 *hash) { secp256k1_memclear_explicit(hash, sizeof(*hash)); } -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { +static void secp256k1_hmac_sha256_initialize(const secp256k1_hash_ctx *hash_ctx, secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { size_t n; unsigned char rkey[64]; if (keylen <= sizeof(rkey)) { @@ -191,8 +205,8 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const } else { secp256k1_sha256 sha256; secp256k1_sha256_initialize(&sha256); - secp256k1_sha256_write(&sha256, key, keylen); - secp256k1_sha256_finalize(&sha256, rkey); + secp256k1_sha256_write(hash_ctx, &sha256, key, keylen); + secp256k1_sha256_finalize(hash_ctx, &sha256, rkey); memset(rkey + 32, 0, 32); } @@ -200,33 +214,33 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const for (n = 0; n < sizeof(rkey); n++) { rkey[n] ^= 0x5c; } - secp256k1_sha256_write(&hash->outer, rkey, sizeof(rkey)); + secp256k1_sha256_write(hash_ctx, &hash->outer, rkey, sizeof(rkey)); secp256k1_sha256_initialize(&hash->inner); for (n = 0; n < sizeof(rkey); n++) { rkey[n] ^= 0x5c ^ 0x36; } - secp256k1_sha256_write(&hash->inner, rkey, sizeof(rkey)); + secp256k1_sha256_write(hash_ctx, &hash->inner, rkey, sizeof(rkey)); secp256k1_memclear_explicit(rkey, sizeof(rkey)); } -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) { - secp256k1_sha256_write(&hash->inner, data, size); +static void secp256k1_hmac_sha256_write(const secp256k1_hash_ctx *hash_ctx, secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) { + secp256k1_sha256_write(hash_ctx, &hash->inner, data, size); } -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32) { +static void secp256k1_hmac_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp256k1_hmac_sha256 *hash, unsigned char *out32) { unsigned char temp[32]; - secp256k1_sha256_finalize(&hash->inner, temp); - secp256k1_sha256_write(&hash->outer, temp, 32); + secp256k1_sha256_finalize(hash_ctx, &hash->inner, temp); + secp256k1_sha256_write(hash_ctx, &hash->outer, temp, 32); secp256k1_memclear_explicit(temp, sizeof(temp)); - secp256k1_sha256_finalize(&hash->outer, out32); + secp256k1_sha256_finalize(hash_ctx, &hash->outer, out32); } static void secp256k1_hmac_sha256_clear(secp256k1_hmac_sha256 *hash) { secp256k1_memclear_explicit(hash, sizeof(*hash)); } -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { +static void secp256k1_rfc6979_hmac_sha256_initialize(const secp256k1_hash_ctx *hash_ctx, secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { secp256k1_hmac_sha256 hmac; static const unsigned char zero[1] = {0x00}; static const unsigned char one[1] = {0x01}; @@ -235,47 +249,47 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */ /* RFC6979 3.2.d. */ - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, zero, 1); - secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, zero, 1); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, key, keylen); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->k); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v); /* RFC6979 3.2.f. */ - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, one, 1); - secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, one, 1); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, key, keylen); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->k); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v); rng->retry = 0; } -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) { +static void secp256k1_rfc6979_hmac_sha256_generate(const secp256k1_hash_ctx *hash_ctx, secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) { /* RFC6979 3.2.h. */ static const unsigned char zero[1] = {0x00}; if (rng->retry) { secp256k1_hmac_sha256 hmac; - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, zero, 1); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, zero, 1); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->k); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v); } while (outlen > 0) { secp256k1_hmac_sha256 hmac; size_t now = outlen; - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); + secp256k1_hmac_sha256_initialize(hash_ctx, &hmac, rng->k, 32); + secp256k1_hmac_sha256_write(hash_ctx, &hmac, rng->v, 32); + secp256k1_hmac_sha256_finalize(hash_ctx, &hmac, rng->v); if (now > 32) { now = 32; } diff --git a/src/modules/ecdh/main_impl.h b/src/modules/ecdh/main_impl.h index 9f2dfdd5..3ee3ca7b 100644 --- a/src/modules/ecdh/main_impl.h +++ b/src/modules/ecdh/main_impl.h @@ -10,20 +10,24 @@ #include "../../../include/secp256k1_ecdh.h" #include "../../ecmult_const_impl.h" -static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { +static int ecdh_hash_function_sha256_impl(const secp256k1_hash_ctx *hash_ctx, unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { unsigned char version = (y32[31] & 0x01) | 0x02; secp256k1_sha256 sha; (void)data; secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, &version, 1); - secp256k1_sha256_write(&sha, x32, 32); - secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_write(hash_ctx, &sha, &version, 1); + secp256k1_sha256_write(hash_ctx, &sha, x32, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, output); secp256k1_sha256_clear(&sha); return 1; } +static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { + return ecdh_hash_function_sha256_impl(secp256k1_get_hash_context(secp256k1_context_static), output, x32, y32, data); +} + const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default = ecdh_hash_function_sha256; diff --git a/src/modules/ecdh/tests_impl.h b/src/modules/ecdh/tests_impl.h index cb1d953d..e6c1bab9 100644 --- a/src/modules/ecdh/tests_impl.h +++ b/src/modules/ecdh/tests_impl.h @@ -83,8 +83,8 @@ static void test_ecdh_generator_basepoint(void) { /* compute "explicitly" */ CHECK(secp256k1_ec_pubkey_serialize(CTX, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, point_ser, point_ser_len); - secp256k1_sha256_finalize(&sha, output_ser); + secp256k1_sha256_write(secp256k1_get_hash_context(CTX), &sha, point_ser, point_ser_len); + secp256k1_sha256_finalize(secp256k1_get_hash_context(CTX), &sha, output_ser); /* compare */ CHECK(secp256k1_memcmp_var(output_ecdh, output_ser, 32) == 0); } diff --git a/src/modules/ellswift/main_impl.h b/src/modules/ellswift/main_impl.h index f9ef0ac8..29c0a536 100644 --- a/src/modules/ellswift/main_impl.h +++ b/src/modules/ellswift/main_impl.h @@ -307,7 +307,7 @@ static int secp256k1_ellswift_xswiftec_inv_var(secp256k1_fe *t, const secp256k1_ * hasher is a SHA256 object to which an incrementing 4-byte counter is written to generate randomness. * Writing 13 bytes (4 bytes for counter, plus 9 bytes for the SHA256 padding) cannot cross a * 64-byte block size boundary (to make sure it only triggers a single SHA256 compression). */ -static void secp256k1_ellswift_prng(unsigned char* out32, const secp256k1_sha256 *hasher, uint32_t cnt) { +static void secp256k1_ellswift_prng(const secp256k1_hash_ctx *hash_ctx, unsigned char* out32, const secp256k1_sha256 *hasher, uint32_t cnt) { secp256k1_sha256 hash = *hasher; unsigned char buf4[4]; #ifdef VERIFY @@ -317,8 +317,8 @@ static void secp256k1_ellswift_prng(unsigned char* out32, const secp256k1_sha256 buf4[1] = cnt >> 8; buf4[2] = cnt >> 16; buf4[3] = cnt >> 24; - secp256k1_sha256_write(&hash, buf4, 4); - secp256k1_sha256_finalize(&hash, out32); + secp256k1_sha256_write(hash_ctx, &hash, buf4, 4); + secp256k1_sha256_finalize(hash_ctx, &hash, out32); /* Writing and finalizing together should trigger exactly one SHA256 compression. */ VERIFY_CHECK(((hash.bytes) >> 6) == (blocks + 1)); @@ -330,7 +330,7 @@ static void secp256k1_ellswift_prng(unsigned char* out32, const secp256k1_sha256 * needs encoding. * * hasher is a hasher in the secp256k1_ellswift_prng sense, with the same restrictions. */ -static void secp256k1_ellswift_xelligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_fe *x, const secp256k1_sha256 *hasher) { +static void secp256k1_ellswift_xelligatorswift_var(const secp256k1_context *ctx, unsigned char *u32, secp256k1_fe *t, const secp256k1_fe *x, const secp256k1_sha256 *hasher) { /* Pool of 3-bit branch values. */ unsigned char branch_hash[32]; /* Number of 3-bit values in branch_hash left. */ @@ -346,14 +346,14 @@ static void secp256k1_ellswift_xelligatorswift_var(unsigned char *u32, secp256k1 secp256k1_fe u; /* If the pool of branch values is empty, populate it. */ if (branches_left == 0) { - secp256k1_ellswift_prng(branch_hash, hasher, cnt++); + secp256k1_ellswift_prng(secp256k1_get_hash_context(ctx), branch_hash, hasher, cnt++); branches_left = 64; } /* Take a 3-bit branch value from the branch pool (top bit is discarded). */ --branches_left; branch = (branch_hash[branches_left >> 1] >> ((branches_left & 1) << 2)) & 7; /* Compute a new u value by hashing. */ - secp256k1_ellswift_prng(u32, hasher, cnt++); + secp256k1_ellswift_prng(secp256k1_get_hash_context(ctx), u32, hasher, cnt++); /* overflow is not a problem (we prefer uniform u32 over uniform u). */ secp256k1_fe_set_b32_mod(&u, u32); /* Since u is the output of a hash, it should practically never be 0. We could apply the @@ -372,8 +372,8 @@ static void secp256k1_ellswift_xelligatorswift_var(unsigned char *u32, secp256k1 * as input, and returns an encoding that matches the provided Y coordinate rather than a random * one. */ -static void secp256k1_ellswift_elligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_ge *p, const secp256k1_sha256 *hasher) { - secp256k1_ellswift_xelligatorswift_var(u32, t, &p->x, hasher); +static void secp256k1_ellswift_elligatorswift_var(const secp256k1_context *ctx, unsigned char *u32, secp256k1_fe *t, const secp256k1_ge *p, const secp256k1_sha256 *hasher) { + secp256k1_ellswift_xelligatorswift_var(ctx, u32, t, &p->x, hasher); secp256k1_fe_normalize_var(t); if (secp256k1_fe_is_odd(t) != secp256k1_fe_is_odd(&p->y)) { secp256k1_fe_negate(t, t, 1); @@ -406,11 +406,11 @@ int secp256k1_ellswift_encode(const secp256k1_context *ctx, unsigned char *ell64 * BIP340 tagged hash with tag "secp256k1_ellswift_encode". */ secp256k1_ellswift_sha256_init_encode(&hash); secp256k1_eckey_pubkey_serialize33(&p, p64); - secp256k1_sha256_write(&hash, p64, sizeof(p64)); - secp256k1_sha256_write(&hash, rnd32, 32); + secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &hash, p64, sizeof(p64)); + secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &hash, rnd32, 32); /* Compute ElligatorSwift encoding and construct output. */ - secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */ + secp256k1_ellswift_elligatorswift_var(ctx, ell64, &t, &p, &hash); /* puts u in ell64[0..32] */ secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */ return 1; } @@ -452,13 +452,13 @@ int secp256k1_ellswift_create(const secp256k1_context *ctx, unsigned char *ell64 /* Set up hasher state. The used RNG is H(privkey || "\x00"*32 [|| auxrnd32] || cnt++), * using BIP340 tagged hash with tag "secp256k1_ellswift_create". */ secp256k1_ellswift_sha256_init_create(&hash); - secp256k1_sha256_write(&hash, seckey32, 32); - secp256k1_sha256_write(&hash, zero32, sizeof(zero32)); + secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &hash, seckey32, 32); + secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &hash, zero32, sizeof(zero32)); secp256k1_declassify(ctx, &hash, sizeof(hash)); /* private key is hashed now */ - if (auxrnd32) secp256k1_sha256_write(&hash, auxrnd32, 32); + if (auxrnd32) secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &hash, auxrnd32, 32); /* Compute ElligatorSwift encoding and construct output. */ - secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */ + secp256k1_ellswift_elligatorswift_var(ctx, ell64, &t, &p, &hash); /* puts u in ell64[0..32] */ secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */ secp256k1_memczero(ell64, 64, !ret); @@ -482,20 +482,24 @@ int secp256k1_ellswift_decode(const secp256k1_context *ctx, secp256k1_pubkey *pu return 1; } -static int ellswift_xdh_hash_function_prefix(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { +static int ellswift_xdh_hash_function_prefix_impl(const secp256k1_hash_ctx *hash_ctx, unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { secp256k1_sha256 sha; secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, data, 64); - secp256k1_sha256_write(&sha, ell_a64, 64); - secp256k1_sha256_write(&sha, ell_b64, 64); - secp256k1_sha256_write(&sha, x32, 32); - secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_write(hash_ctx, &sha, data, 64); + secp256k1_sha256_write(hash_ctx, &sha, ell_a64, 64); + secp256k1_sha256_write(hash_ctx, &sha, ell_b64, 64); + secp256k1_sha256_write(hash_ctx, &sha, x32, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, output); secp256k1_sha256_clear(&sha); return 1; } +static int ellswift_xdh_hash_function_prefix(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { + return ellswift_xdh_hash_function_prefix_impl(secp256k1_get_hash_context(secp256k1_context_static), output, x32, ell_a64, ell_b64, data); +} + /** Set hash state to the BIP340 tagged hash midstate for "bip324_ellswift_xonly_ecdh". */ static void secp256k1_ellswift_sha256_init_bip324(secp256k1_sha256* hash) { static const uint32_t midstate[8] = { @@ -505,21 +509,25 @@ static void secp256k1_ellswift_sha256_init_bip324(secp256k1_sha256* hash) { secp256k1_sha256_initialize_midstate(hash, 64, midstate); } -static int ellswift_xdh_hash_function_bip324(unsigned char* output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { +static int ellswift_xdh_hash_function_bip324_impl(const secp256k1_hash_ctx *hash_ctx, unsigned char* output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { secp256k1_sha256 sha; (void)data; secp256k1_ellswift_sha256_init_bip324(&sha); - secp256k1_sha256_write(&sha, ell_a64, 64); - secp256k1_sha256_write(&sha, ell_b64, 64); - secp256k1_sha256_write(&sha, x32, 32); - secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_write(hash_ctx, &sha, ell_a64, 64); + secp256k1_sha256_write(hash_ctx, &sha, ell_b64, 64); + secp256k1_sha256_write(hash_ctx, &sha, x32, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, output); secp256k1_sha256_clear(&sha); return 1; } +static int ellswift_xdh_hash_function_bip324(unsigned char* output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) { + return ellswift_xdh_hash_function_bip324_impl(secp256k1_get_hash_context(secp256k1_context_static), output, x32, ell_a64, ell_b64, data); +} + const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix = ellswift_xdh_hash_function_prefix; const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324 = ellswift_xdh_hash_function_bip324; diff --git a/src/modules/ellswift/tests_impl.h b/src/modules/ellswift/tests_impl.h index e3090411..c9a7500f 100644 --- a/src/modules/ellswift/tests_impl.h +++ b/src/modules/ellswift/tests_impl.h @@ -434,6 +434,7 @@ void ellswift_xdh_correctness_tests(void) { /* Test hash initializers */ void ellswift_hash_init_tests(void) { secp256k1_sha256 sha_optimized; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); /* "secp256k1_ellswift_encode" */ static const unsigned char encode_tag[] = {'s', 'e', 'c', 'p', '2', '5', '6', 'k', '1', '_', 'e', 'l', 'l', 's', 'w', 'i', 'f', 't', '_', 'e', 'n', 'c', 'o', 'd', 'e'}; /* "secp256k1_ellswift_create" */ @@ -445,19 +446,19 @@ void ellswift_hash_init_tests(void) { * secp256k1_ellswift_sha256_init_encode has the expected * state. */ secp256k1_ellswift_sha256_init_encode(&sha_optimized); - test_sha256_tag_midstate(&sha_optimized, encode_tag, sizeof(encode_tag)); + test_sha256_tag_midstate(hash_ctx, &sha_optimized, encode_tag, sizeof(encode_tag)); /* Check that hash initialized by * secp256k1_ellswift_sha256_init_create has the expected * state. */ secp256k1_ellswift_sha256_init_create(&sha_optimized); - test_sha256_tag_midstate(&sha_optimized, create_tag, sizeof(create_tag)); + test_sha256_tag_midstate(hash_ctx, &sha_optimized, create_tag, sizeof(create_tag)); /* Check that hash initialized by * secp256k1_ellswift_sha256_init_bip324 has the expected * state. */ secp256k1_ellswift_sha256_init_bip324(&sha_optimized); - test_sha256_tag_midstate(&sha_optimized, bip324_tag, sizeof(bip324_tag)); + test_sha256_tag_midstate(hash_ctx, &sha_optimized, bip324_tag, sizeof(bip324_tag)); } void ellswift_xdh_bad_scalar_tests(void) { diff --git a/src/modules/musig/keyagg.h b/src/modules/musig/keyagg.h index a0b37252..30e77aa9 100644 --- a/src/modules/musig/keyagg.h +++ b/src/modules/musig/keyagg.h @@ -27,6 +27,6 @@ typedef struct { static int secp256k1_keyagg_cache_load(const secp256k1_context* ctx, secp256k1_keyagg_cache_internal *cache_i, const secp256k1_musig_keyagg_cache *cache); -static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk); +static void secp256k1_musig_keyaggcoef(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk); #endif diff --git a/src/modules/musig/keyagg_impl.h b/src/modules/musig/keyagg_impl.h index 4eb48ddc..f67245d5 100644 --- a/src/modules/musig/keyagg_impl.h +++ b/src/modules/musig/keyagg_impl.h @@ -82,9 +82,9 @@ static int secp256k1_musig_compute_pks_hash(const secp256k1_context *ctx, unsign return 0; } VERIFY_CHECK(ser_len == sizeof(ser)); - secp256k1_sha256_write(&sha, ser, sizeof(ser)); + secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &sha, ser, sizeof(ser)); } - secp256k1_sha256_finalize(&sha, pks_hash); + secp256k1_sha256_finalize(secp256k1_get_hash_context(ctx), &sha, pks_hash); return 1; } @@ -103,7 +103,7 @@ static void secp256k1_musig_keyaggcoef_sha256(secp256k1_sha256 *sha) { * second_pk is the point at infinity in case there is no second_pk. Assumes * that pk is not the point at infinity and that the Y-coordinates of pk and * second_pk are normalized. */ -static void secp256k1_musig_keyaggcoef_internal(secp256k1_scalar *r, const unsigned char *pks_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk) { +static void secp256k1_musig_keyaggcoef_internal(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *r, const unsigned char *pks_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk) { VERIFY_CHECK(!secp256k1_ge_is_infinity(pk)); if (!secp256k1_ge_is_infinity(second_pk) @@ -113,20 +113,20 @@ static void secp256k1_musig_keyaggcoef_internal(secp256k1_scalar *r, const unsig secp256k1_sha256 sha; unsigned char buf[33]; secp256k1_musig_keyaggcoef_sha256(&sha); - secp256k1_sha256_write(&sha, pks_hash, 32); + secp256k1_sha256_write(hash_ctx, &sha, pks_hash, 32); /* Serialization does not fail since the pk is not the point at infinity * (according to this function's precondition). */ secp256k1_eckey_pubkey_serialize33(pk, buf); - secp256k1_sha256_write(&sha, buf, sizeof(buf)); - secp256k1_sha256_finalize(&sha, buf); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); + secp256k1_sha256_finalize(hash_ctx, &sha, buf); secp256k1_scalar_set_b32(r, buf, NULL); } } /* Assumes that pk is not the point at infinity and that the Y-coordinates of pk * and cache_i->second_pk are normalized. */ -static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk) { - secp256k1_musig_keyaggcoef_internal(r, cache_i->pks_hash, pk, &cache_i->second_pk); +static void secp256k1_musig_keyaggcoef(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk) { + secp256k1_musig_keyaggcoef_internal(hash_ctx, r, cache_i->pks_hash, pk, &cache_i->second_pk); } typedef struct { @@ -149,7 +149,7 @@ static int secp256k1_musig_pubkey_agg_callback(secp256k1_scalar *sc, secp256k1_g #else (void) ret; #endif - secp256k1_musig_keyaggcoef_internal(sc, ctx->pks_hash, pt, &ctx->second_pk); + secp256k1_musig_keyaggcoef_internal(secp256k1_get_hash_context(ctx->ctx), sc, ctx->pks_hash, pt, &ctx->second_pk); return 1; } diff --git a/src/modules/musig/session_impl.h b/src/modules/musig/session_impl.h index 42fcd81e..6a37bfdf 100644 --- a/src/modules/musig/session_impl.h +++ b/src/modules/musig/session_impl.h @@ -289,20 +289,20 @@ int secp256k1_musig_partial_sig_serialize(const secp256k1_context* ctx, unsigned } /* Write optional inputs into the hash */ -static void secp256k1_nonce_function_musig_helper(secp256k1_sha256 *sha, unsigned int prefix_size, const unsigned char *data, unsigned char len) { +static void secp256k1_nonce_function_musig_helper(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha, unsigned int prefix_size, const unsigned char *data, unsigned char len) { unsigned char zero[7] = { 0 }; /* The spec requires length prefixes to be between 1 and 8 bytes * (inclusive) */ VERIFY_CHECK(prefix_size >= 1 && prefix_size <= 8); /* Since the length of all input data fits in a byte, we can always pad the * length prefix with prefix_size - 1 zero bytes. */ - secp256k1_sha256_write(sha, zero, prefix_size - 1); + secp256k1_sha256_write(hash_ctx, sha, zero, prefix_size - 1); if (data != NULL) { - secp256k1_sha256_write(sha, &len, 1); - secp256k1_sha256_write(sha, data, len); + secp256k1_sha256_write(hash_ctx, sha, &len, 1); + secp256k1_sha256_write(hash_ctx, sha, data, len); } else { len = 0; - secp256k1_sha256_write(sha, &len, 1); + secp256k1_sha256_write(hash_ctx, sha, &len, 1); } } @@ -326,7 +326,7 @@ static void secp256k1_nonce_function_musig_sha256_tagged(secp256k1_sha256 *sha) secp256k1_sha256_initialize_midstate(sha, 64, midstate); } -static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned char *session_secrand, const unsigned char *msg32, const unsigned char *seckey32, const unsigned char *pk33, const unsigned char *agg_pk32, const unsigned char *extra_input32) { +static void secp256k1_nonce_function_musig(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *k, const unsigned char *session_secrand, const unsigned char *msg32, const unsigned char *seckey32, const unsigned char *pk33, const unsigned char *agg_pk32, const unsigned char *extra_input32) { secp256k1_sha256 sha; unsigned char rand[32]; unsigned char i; @@ -334,8 +334,8 @@ static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned c if (seckey32 != NULL) { secp256k1_nonce_function_musig_sha256_tagged_aux(&sha); - secp256k1_sha256_write(&sha, session_secrand, 32); - secp256k1_sha256_finalize(&sha, rand); + secp256k1_sha256_write(hash_ctx, &sha, session_secrand, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, rand); for (i = 0; i < 32; i++) { rand[i] ^= seckey32[i]; } @@ -344,21 +344,21 @@ static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned c } secp256k1_nonce_function_musig_sha256_tagged(&sha); - secp256k1_sha256_write(&sha, rand, sizeof(rand)); - secp256k1_nonce_function_musig_helper(&sha, 1, pk33, 33); - secp256k1_nonce_function_musig_helper(&sha, 1, agg_pk32, 32); + secp256k1_sha256_write(hash_ctx, &sha, rand, sizeof(rand)); + secp256k1_nonce_function_musig_helper(hash_ctx, &sha, 1, pk33, 33); + secp256k1_nonce_function_musig_helper(hash_ctx, &sha, 1, agg_pk32, 32); msg_present = msg32 != NULL; - secp256k1_sha256_write(&sha, &msg_present, 1); + secp256k1_sha256_write(hash_ctx, &sha, &msg_present, 1); if (msg_present) { - secp256k1_nonce_function_musig_helper(&sha, 8, msg32, 32); + secp256k1_nonce_function_musig_helper(hash_ctx, &sha, 8, msg32, 32); } - secp256k1_nonce_function_musig_helper(&sha, 4, extra_input32, 32); + secp256k1_nonce_function_musig_helper(hash_ctx, &sha, 4, extra_input32, 32); for (i = 0; i < 2; i++) { unsigned char buf[32]; secp256k1_sha256 sha_tmp = sha; - secp256k1_sha256_write(&sha_tmp, &i, 1); - secp256k1_sha256_finalize(&sha_tmp, buf); + secp256k1_sha256_write(hash_ctx, &sha_tmp, &i, 1); + secp256k1_sha256_finalize(hash_ctx, &sha_tmp, buf); secp256k1_scalar_set_b32(&k[i], buf, NULL); /* Attempt to erase secret data */ @@ -407,7 +407,7 @@ static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp /* A pubkey cannot be the point at infinity */ secp256k1_eckey_pubkey_serialize33(&pk, pk_ser); - secp256k1_nonce_function_musig(k, input_nonce, msg32, seckey, pk_ser, aggpk_ser_ptr, extra_input32); + secp256k1_nonce_function_musig(secp256k1_get_hash_context(ctx), k, input_nonce, msg32, seckey, pk_ser, aggpk_ser_ptr, extra_input32); VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[0])); VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[1])); secp256k1_musig_secnonce_save(secnonce, k, &pk); @@ -541,7 +541,7 @@ static void secp256k1_musig_compute_noncehash_sha256_tagged(secp256k1_sha256 *sh } /* tagged_hash(aggnonce[0], aggnonce[1], agg_pk, msg) */ -static void secp256k1_musig_compute_noncehash(unsigned char *noncehash, secp256k1_ge *aggnonce, const unsigned char *agg_pk32, const unsigned char *msg) { +static void secp256k1_musig_compute_noncehash(const secp256k1_hash_ctx *hash_ctx, unsigned char *noncehash, secp256k1_ge *aggnonce, const unsigned char *agg_pk32, const unsigned char *msg) { unsigned char buf[33]; secp256k1_sha256 sha; int i; @@ -549,11 +549,11 @@ static void secp256k1_musig_compute_noncehash(unsigned char *noncehash, secp256k secp256k1_musig_compute_noncehash_sha256_tagged(&sha); for (i = 0; i < 2; i++) { secp256k1_musig_ge_serialize_ext(buf, &aggnonce[i]); - secp256k1_sha256_write(&sha, buf, sizeof(buf)); + secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf)); } - secp256k1_sha256_write(&sha, agg_pk32, 32); - secp256k1_sha256_write(&sha, msg, 32); - secp256k1_sha256_finalize(&sha, noncehash); + secp256k1_sha256_write(hash_ctx, &sha, agg_pk32, 32); + secp256k1_sha256_write(hash_ctx, &sha, msg, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, noncehash); } /* out_nonce = nonce_pts[0] + b*nonce_pts[1] */ @@ -565,12 +565,12 @@ static void secp256k1_effective_nonce(secp256k1_gej *out_nonce, const secp256k1_ secp256k1_gej_add_ge_var(out_nonce, out_nonce, &nonce_pts[0], NULL); } -static void secp256k1_musig_nonce_process_internal(int *fin_nonce_parity, unsigned char *fin_nonce, secp256k1_scalar *b, secp256k1_ge *aggnonce_pts, const unsigned char *agg_pk32, const unsigned char *msg) { +static void secp256k1_musig_nonce_process_internal(const secp256k1_context *ctx, int *fin_nonce_parity, unsigned char *fin_nonce, secp256k1_scalar *b, secp256k1_ge *aggnonce_pts, const unsigned char *agg_pk32, const unsigned char *msg) { unsigned char noncehash[32]; secp256k1_ge fin_nonce_pt; secp256k1_gej fin_nonce_ptj; - secp256k1_musig_compute_noncehash(noncehash, aggnonce_pts, agg_pk32, msg); + secp256k1_musig_compute_noncehash(secp256k1_get_hash_context(ctx), noncehash, aggnonce_pts, agg_pk32, msg); secp256k1_scalar_set_b32(b, noncehash, NULL); /* fin_nonce = aggnonce_pts[0] + b*aggnonce_pts[1] */ secp256k1_effective_nonce(&fin_nonce_ptj, aggnonce_pts, b); @@ -607,8 +607,8 @@ int secp256k1_musig_nonce_process(const secp256k1_context* ctx, secp256k1_musig_ return 0; } - secp256k1_musig_nonce_process_internal(&session_i.fin_nonce_parity, fin_nonce, &session_i.noncecoef, aggnonce_pts, agg_pk32, msg32); - secp256k1_schnorrsig_challenge(&session_i.challenge, fin_nonce, msg32, 32, agg_pk32); + secp256k1_musig_nonce_process_internal(ctx, &session_i.fin_nonce_parity, fin_nonce, &session_i.noncecoef, aggnonce_pts, agg_pk32, msg32); + secp256k1_schnorrsig_challenge(secp256k1_get_hash_context(ctx), &session_i.challenge, fin_nonce, msg32, 32, agg_pk32); /* If there is a tweak then set `challenge` times `tweak` to the `s`-part.*/ secp256k1_scalar_set_int(&session_i.s_part, 0); @@ -678,7 +678,7 @@ int secp256k1_musig_partial_sign(const secp256k1_context* ctx, secp256k1_musig_p } /* Multiply KeyAgg coefficient */ - secp256k1_musig_keyaggcoef(&mu, &cache_i, &pk); + secp256k1_musig_keyaggcoef(secp256k1_get_hash_context(ctx), &mu, &cache_i, &pk); secp256k1_scalar_mul(&sk, &sk, &mu); if (!secp256k1_musig_session_load(ctx, &session_i, session)) { @@ -738,7 +738,7 @@ int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp2 /* Multiplying the challenge by the KeyAgg coefficient is equivalent * to multiplying the signer's public key by the coefficient, except * much easier to do. */ - secp256k1_musig_keyaggcoef(&mu, &cache_i, &pkp); + secp256k1_musig_keyaggcoef(secp256k1_get_hash_context(ctx), &mu, &cache_i, &pkp); secp256k1_scalar_mul(&e, &session_i.challenge, &mu); /* Negate e if secp256k1_fe_is_odd(&cache_i.pk.y)) XOR cache_i.parity_acc. diff --git a/src/modules/musig/tests_impl.h b/src/modules/musig/tests_impl.h index de09c5e2..cbeb1e28 100644 --- a/src/modules/musig/tests_impl.h +++ b/src/modules/musig/tests_impl.h @@ -505,12 +505,12 @@ static void musig_api_tests(void) { CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 2) == 1); } -static void musig_nonce_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes) { +static void musig_nonce_bitflip(const secp256k1_hash_ctx *hash_ctx, unsigned char **args, size_t n_flip, size_t n_bytes) { secp256k1_scalar k1[2], k2[2]; - secp256k1_nonce_function_musig(k1, args[0], args[1], args[2], args[3], args[4], args[5]); + secp256k1_nonce_function_musig(hash_ctx, k1, args[0], args[1], args[2], args[3], args[4], args[5]); testrand_flip(args[n_flip], n_bytes); - secp256k1_nonce_function_musig(k2, args[0], args[1], args[2], args[3], args[4], args[5]); + secp256k1_nonce_function_musig(hash_ctx, k2, args[0], args[1], args[2], args[3], args[4], args[5]); CHECK(secp256k1_scalar_eq(&k1[0], &k2[0]) == 0); CHECK(secp256k1_scalar_eq(&k1[1], &k2[1]) == 0); } @@ -526,6 +526,7 @@ static void musig_nonce_test(void) { int i, j; secp256k1_scalar k[6][2]; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); testrand_bytes_test(session_secrand, sizeof(session_secrand)); testrand_bytes_test(sk, sizeof(sk)); testrand_bytes_test(pk, sizeof(pk)); @@ -541,12 +542,12 @@ static void musig_nonce_test(void) { args[4] = agg_pk; args[5] = extra_input; for (i = 0; i < COUNT; i++) { - musig_nonce_bitflip(args, 0, sizeof(session_secrand)); - musig_nonce_bitflip(args, 1, sizeof(msg)); - musig_nonce_bitflip(args, 2, sizeof(sk)); - musig_nonce_bitflip(args, 3, sizeof(pk)); - musig_nonce_bitflip(args, 4, sizeof(agg_pk)); - musig_nonce_bitflip(args, 5, sizeof(extra_input)); + musig_nonce_bitflip(hash_ctx, args, 0, sizeof(session_secrand)); + musig_nonce_bitflip(hash_ctx, args, 1, sizeof(msg)); + musig_nonce_bitflip(hash_ctx, args, 2, sizeof(sk)); + musig_nonce_bitflip(hash_ctx, args, 3, sizeof(pk)); + musig_nonce_bitflip(hash_ctx, args, 4, sizeof(agg_pk)); + musig_nonce_bitflip(hash_ctx, args, 5, sizeof(extra_input)); } /* Check that if any argument is NULL, a different nonce is produced than if * any other argument is NULL. */ @@ -555,12 +556,12 @@ static void musig_nonce_test(void) { memcpy(pk, session_secrand, sizeof(session_secrand)); memcpy(agg_pk, session_secrand, sizeof(agg_pk)); memcpy(extra_input, session_secrand, sizeof(extra_input)); - secp256k1_nonce_function_musig(k[0], args[0], args[1], args[2], args[3], args[4], args[5]); - secp256k1_nonce_function_musig(k[1], args[0], NULL, args[2], args[3], args[4], args[5]); - secp256k1_nonce_function_musig(k[2], args[0], args[1], NULL, args[3], args[4], args[5]); - secp256k1_nonce_function_musig(k[3], args[0], args[1], args[2], NULL, args[4], args[5]); - secp256k1_nonce_function_musig(k[4], args[0], args[1], args[2], args[3], NULL, args[5]); - secp256k1_nonce_function_musig(k[5], args[0], args[1], args[2], args[3], args[4], NULL); + secp256k1_nonce_function_musig(hash_ctx, k[0], args[0], args[1], args[2], args[3], args[4], args[5]); + secp256k1_nonce_function_musig(hash_ctx, k[1], args[0], NULL, args[2], args[3], args[4], args[5]); + secp256k1_nonce_function_musig(hash_ctx, k[2], args[0], args[1], NULL, args[3], args[4], args[5]); + secp256k1_nonce_function_musig(hash_ctx, k[3], args[0], args[1], args[2], NULL, args[4], args[5]); + secp256k1_nonce_function_musig(hash_ctx, k[4], args[0], args[1], args[2], args[3], NULL, args[5]); + secp256k1_nonce_function_musig(hash_ctx, k[5], args[0], args[1], args[2], args[3], args[4], NULL); for (i = 0; i < 6; i++) { CHECK(!secp256k1_scalar_eq(&k[i][0], &k[i][1])); for (j = i+1; j < 6; j++) { @@ -574,35 +575,36 @@ static void musig_nonce_test(void) { * state. */ static void sha256_tag_test(void) { secp256k1_sha256 sha; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); { /* "KeyAgg list" */ static const unsigned char tag[] = {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'l', 'i', 's', 't'}; secp256k1_musig_keyagglist_sha256(&sha); - test_sha256_tag_midstate(&sha, tag, sizeof(tag)); + test_sha256_tag_midstate(hash_ctx, &sha, tag, sizeof(tag)); } { /* "KeyAgg coefficient" */ static const unsigned char tag[] = {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'c', 'o', 'e', 'f', 'f', 'i', 'c', 'i', 'e', 'n', 't'}; secp256k1_musig_keyaggcoef_sha256(&sha); - test_sha256_tag_midstate(&sha, tag, sizeof(tag)); + test_sha256_tag_midstate(hash_ctx, &sha, tag, sizeof(tag)); } { /* "MuSig/aux" */ static const unsigned char tag[] = { 'M', 'u', 'S', 'i', 'g', '/', 'a', 'u', 'x' }; secp256k1_nonce_function_musig_sha256_tagged_aux(&sha); - test_sha256_tag_midstate(&sha, tag, sizeof(tag)); + test_sha256_tag_midstate(hash_ctx, &sha, tag, sizeof(tag)); } { /* "MuSig/nonce" */ static const unsigned char tag[] = { 'M', 'u', 'S', 'i', 'g', '/', 'n', 'o', 'n', 'c', 'e' }; secp256k1_nonce_function_musig_sha256_tagged(&sha); - test_sha256_tag_midstate(&sha, tag, sizeof(tag)); + test_sha256_tag_midstate(hash_ctx, &sha, tag, sizeof(tag)); } { /* "MuSig/noncecoef" */ static const unsigned char tag[] = { 'M', 'u', 'S', 'i', 'g', '/', 'n', 'o', 'n', 'c', 'e', 'c', 'o', 'e', 'f' }; secp256k1_musig_compute_noncehash_sha256_tagged(&sha); - test_sha256_tag_midstate(&sha, tag, sizeof(tag)); + test_sha256_tag_midstate(hash_ctx, &sha, tag, sizeof(tag)); } } diff --git a/src/modules/schnorrsig/main_impl.h b/src/modules/schnorrsig/main_impl.h index 21c1f412..3fe645b4 100644 --- a/src/modules/schnorrsig/main_impl.h +++ b/src/modules/schnorrsig/main_impl.h @@ -37,7 +37,7 @@ static const unsigned char bip340_algo[] = {'B', 'I', 'P', '0', '3', '4', '0', ' static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC; -static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { +static int nonce_function_bip340_impl(const secp256k1_hash_ctx *hash_ctx, unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { secp256k1_sha256 sha; unsigned char masked_key[32]; int i; @@ -48,8 +48,8 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms if (data != NULL) { secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha); - secp256k1_sha256_write(&sha, data, 32); - secp256k1_sha256_finalize(&sha, masked_key); + secp256k1_sha256_write(hash_ctx, &sha, data, 32); + secp256k1_sha256_finalize(hash_ctx, &sha, masked_key); for (i = 0; i < 32; i++) { masked_key[i] ^= key32[i]; } @@ -73,20 +73,24 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms && secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) { secp256k1_nonce_function_bip340_sha256_tagged(&sha); } else { - secp256k1_sha256_initialize_tagged(&sha, algo, algolen); + secp256k1_sha256_initialize_tagged(hash_ctx, &sha, algo, algolen); } /* Hash masked-key||pk||msg using the tagged hash as per the spec */ - secp256k1_sha256_write(&sha, masked_key, 32); - secp256k1_sha256_write(&sha, xonly_pk32, 32); - secp256k1_sha256_write(&sha, msg, msglen); - secp256k1_sha256_finalize(&sha, nonce32); + secp256k1_sha256_write(hash_ctx, &sha, masked_key, 32); + secp256k1_sha256_write(hash_ctx, &sha, xonly_pk32, 32); + secp256k1_sha256_write(hash_ctx, &sha, msg, msglen); + secp256k1_sha256_finalize(hash_ctx, &sha, nonce32); secp256k1_sha256_clear(&sha); secp256k1_memclear_explicit(masked_key, sizeof(masked_key)); return 1; } +static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) { + return nonce_function_bip340_impl(secp256k1_get_hash_context(secp256k1_context_static), nonce32, msg, msglen, key32, xonly_pk32, algo, algolen, data); +} + const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340 = nonce_function_bip340; /* Initializes SHA256 with fixed midstate. This midstate was computed by applying @@ -99,17 +103,17 @@ static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha) { secp256k1_sha256_initialize_midstate(sha, 64, midstate); } -static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32) +static void secp256k1_schnorrsig_challenge(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32) { unsigned char buf[32]; secp256k1_sha256 sha; /* tagged hash(r.x, pk.x, msg) */ secp256k1_schnorrsig_sha256_tagged(&sha); - secp256k1_sha256_write(&sha, r32, 32); - secp256k1_sha256_write(&sha, pubkey32, 32); - secp256k1_sha256_write(&sha, msg, msglen); - secp256k1_sha256_finalize(&sha, buf); + secp256k1_sha256_write(hash_ctx, &sha, r32, 32); + secp256k1_sha256_write(hash_ctx, &sha, pubkey32, 32); + secp256k1_sha256_write(hash_ctx, &sha, msg, msglen); + secp256k1_sha256_finalize(hash_ctx, &sha, buf); /* Set scalar e to the challenge hash modulo the curve order as per * BIP340. */ secp256k1_scalar_set_b32(e, buf, NULL); @@ -165,7 +169,7 @@ static int secp256k1_schnorrsig_sign_internal(const secp256k1_context* ctx, unsi secp256k1_fe_normalize_var(&r.x); secp256k1_fe_get_b32(&sig64[0], &r.x); - secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, pk_buf); + secp256k1_schnorrsig_challenge(secp256k1_get_hash_context(ctx), &e, &sig64[0], msg, msglen, pk_buf); secp256k1_scalar_mul(&e, &e, &sk); secp256k1_scalar_add(&e, &e, &k); secp256k1_scalar_get_b32(&sig64[32], &e); @@ -235,7 +239,7 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned cha /* Compute e. */ secp256k1_fe_get_b32(buf, &pk.x); - secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf); + secp256k1_schnorrsig_challenge(secp256k1_get_hash_context(ctx), &e, &sig64[0], msg, msglen, buf); /* Compute rj = s*G + (-e)*pkj */ secp256k1_scalar_negate(&e, &e); diff --git a/src/modules/schnorrsig/tests_exhaustive_impl.h b/src/modules/schnorrsig/tests_exhaustive_impl.h index 601b5497..a8298f65 100644 --- a/src/modules/schnorrsig/tests_exhaustive_impl.h +++ b/src/modules/schnorrsig/tests_exhaustive_impl.h @@ -105,7 +105,7 @@ static void test_exhaustive_schnorrsig_verify(const secp256k1_context *ctx, cons secp256k1_scalar e; unsigned char msg32[32]; testrand256(msg32); - secp256k1_schnorrsig_challenge(&e, sig64, msg32, sizeof(msg32), pk32); + secp256k1_schnorrsig_challenge(secp256k1_get_hash_context(ctx), &e, sig64, msg32, sizeof(msg32), pk32); /* Only do work if we hit a challenge we haven't tried before. */ if (!e_done[e]) { /* Iterate over the possible valid last 32 bytes in the signature. @@ -162,7 +162,7 @@ static void test_exhaustive_schnorrsig_sign(const secp256k1_context *ctx, unsign while (e_count_done < EXHAUSTIVE_TEST_ORDER) { secp256k1_scalar e; testrand256(msg32); - secp256k1_schnorrsig_challenge(&e, xonly_pubkey_bytes[k - 1], msg32, sizeof(msg32), xonly_pubkey_bytes[d - 1]); + secp256k1_schnorrsig_challenge(secp256k1_get_hash_context(ctx), &e, xonly_pubkey_bytes[k - 1], msg32, sizeof(msg32), xonly_pubkey_bytes[d - 1]); /* Only do work if we hit a challenge we haven't tried before. */ if (!e_done[e]) { secp256k1_scalar expected_s = (actual_k + e * actual_d) % EXHAUSTIVE_TEST_ORDER; diff --git a/src/modules/schnorrsig/tests_impl.h b/src/modules/schnorrsig/tests_impl.h index 9a1b15f0..009bb3e1 100644 --- a/src/modules/schnorrsig/tests_impl.h +++ b/src/modules/schnorrsig/tests_impl.h @@ -38,18 +38,20 @@ static void run_nonce_function_bip340_tests(void) { unsigned char *args[5]; int i; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); + /* Check that hash initialized by * secp256k1_nonce_function_bip340_sha256_tagged has the expected * state. */ secp256k1_nonce_function_bip340_sha256_tagged(&sha_optimized); - test_sha256_tag_midstate(&sha_optimized, tag, sizeof(tag)); + test_sha256_tag_midstate(hash_ctx, &sha_optimized, tag, sizeof(tag)); /* Check that hash initialized by * secp256k1_nonce_function_bip340_sha256_tagged_aux has the expected * state. */ secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha_optimized); - test_sha256_tag_midstate(&sha_optimized, aux_tag, sizeof(aux_tag)); + test_sha256_tag_midstate(hash_ctx, &sha_optimized, aux_tag, sizeof(aux_tag)); testrand256(msg); testrand256(key); @@ -162,8 +164,9 @@ static void test_schnorrsig_sha256_tagged(void) { unsigned char tag[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'c', 'h', 'a', 'l', 'l', 'e', 'n', 'g', 'e'}; secp256k1_sha256 sha; secp256k1_sha256 sha_optimized; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); - secp256k1_sha256_initialize_tagged(&sha, (unsigned char *) tag, sizeof(tag)); + secp256k1_sha256_initialize_tagged(hash_ctx, &sha, (unsigned char *) tag, sizeof(tag)); secp256k1_schnorrsig_sha256_tagged(&sha_optimized); test_sha256_eq(&sha, &sha_optimized); } diff --git a/src/secp256k1.c b/src/secp256k1.c index 218ceafb..b91b3bc6 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -60,6 +60,7 @@ * context_eq function. */ struct secp256k1_context_struct { secp256k1_ecmult_gen_context ecmult_gen_ctx; + secp256k1_hash_ctx hash_ctx; secp256k1_callback illegal_callback; secp256k1_callback error_callback; int declassify; @@ -67,6 +68,7 @@ struct secp256k1_context_struct { static const secp256k1_context secp256k1_context_static_ = { { 0 }, + { secp256k1_sha256_transform }, { secp256k1_default_illegal_callback_fn, 0 }, { secp256k1_default_error_callback_fn, 0 }, 0 @@ -129,10 +131,11 @@ secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigne ret = (secp256k1_context*)prealloc; ret->illegal_callback = default_illegal_callback; ret->error_callback = default_error_callback; + secp256k1_hash_ctx_init(&ret->hash_ctx); /* Flags have been checked by secp256k1_context_preallocated_size. */ VERIFY_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_CONTEXT); - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx); + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->hash_ctx); ret->declassify = !!(flags & SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY); return ret; @@ -220,6 +223,10 @@ void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(co ctx->error_callback.data = data; } +static SECP256K1_INLINE const secp256k1_hash_ctx* secp256k1_get_hash_context(const secp256k1_context *ctx) { + return &ctx->hash_ctx; +} + static secp256k1_scratch_space* secp256k1_scratch_space_create(const secp256k1_context* ctx, size_t max_size) { VERIFY_CHECK(ctx != NULL); return secp256k1_scratch_create(&ctx->error_callback, max_size); @@ -476,7 +483,7 @@ static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *off *offset += len; } -static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { +static int nonce_function_rfc6979_impl(const secp256k1_hash_ctx *hash_ctx, unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { unsigned char keydata[112]; unsigned int offset = 0; secp256k1_rfc6979_hmac_sha256 rng; @@ -501,9 +508,9 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m if (algo16 != NULL) { buffer_append(keydata, &offset, algo16, 16); } - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, offset); + secp256k1_rfc6979_hmac_sha256_initialize(hash_ctx, &rng, keydata, offset); for (i = 0; i <= counter; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, nonce32, 32); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); @@ -512,6 +519,10 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m return 1; } +static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { + return nonce_function_rfc6979_impl(secp256k1_get_hash_context(secp256k1_context_static), nonce32, msg32, key32, algo16, data, counter); +} + const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; @@ -757,7 +768,7 @@ int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *see ARG_CHECK(secp256k1_context_is_proper(ctx)); if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, secp256k1_get_hash_context(ctx), seed32); } return 1; } @@ -795,9 +806,9 @@ int secp256k1_tagged_sha256(const secp256k1_context* ctx, unsigned char *hash32, ARG_CHECK(tag != NULL); ARG_CHECK(msg != NULL); - secp256k1_sha256_initialize_tagged(&sha, tag, taglen); - secp256k1_sha256_write(&sha, msg, msglen); - secp256k1_sha256_finalize(&sha, hash32); + secp256k1_sha256_initialize_tagged(secp256k1_get_hash_context(ctx), &sha, tag, taglen); + secp256k1_sha256_write(secp256k1_get_hash_context(ctx), &sha, msg, msglen); + secp256k1_sha256_finalize(secp256k1_get_hash_context(ctx), &sha, hash32); secp256k1_sha256_clear(&sha); return 1; } diff --git a/src/selftest.h b/src/selftest.h index d083ac95..de0e0597 100644 --- a/src/selftest.h +++ b/src/selftest.h @@ -11,7 +11,8 @@ #include -static int secp256k1_selftest_sha256(void) { +static int secp256k1_selftest_sha256(secp256k1_sha256_compression_function fn_compression) { + secp256k1_hash_ctx hash_ctx; static const char *input63 = "For this sample, this 63-byte string will be used as input data"; static const unsigned char output32[32] = { 0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, @@ -20,13 +21,15 @@ static int secp256k1_selftest_sha256(void) { unsigned char out[32]; secp256k1_sha256 hasher; secp256k1_sha256_initialize(&hasher); - secp256k1_sha256_write(&hasher, (const unsigned char*)input63, 63); - secp256k1_sha256_finalize(&hasher, out); + hash_ctx.fn_sha256_compression = fn_compression; + secp256k1_sha256_write(&hash_ctx, &hasher, (const unsigned char*)input63, 63); + secp256k1_sha256_finalize(&hash_ctx, &hasher, out); return secp256k1_memcmp_var(out, output32, 32) == 0; } static int secp256k1_selftest_passes(void) { - return secp256k1_selftest_sha256(); + /* Use default sha256 compression */ + return secp256k1_selftest_sha256(secp256k1_sha256_transform); } #endif /* SECP256K1_SELFTEST_H */ diff --git a/src/testrand_impl.h b/src/testrand_impl.h index b84f5730..e1e5d858 100644 --- a/src/testrand_impl.h +++ b/src/testrand_impl.h @@ -22,12 +22,13 @@ SECP256K1_INLINE static void testrand_seed(const unsigned char *seed16) { unsigned char out32[32]; secp256k1_sha256 hash; int i; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(secp256k1_context_static); /* Use SHA256(PREFIX || seed16) as initial state. */ secp256k1_sha256_initialize(&hash); - secp256k1_sha256_write(&hash, PREFIX, sizeof(PREFIX)); - secp256k1_sha256_write(&hash, seed16, 16); - secp256k1_sha256_finalize(&hash, out32); + secp256k1_sha256_write(hash_ctx, &hash, PREFIX, sizeof(PREFIX)); + secp256k1_sha256_write(hash_ctx, &hash, seed16, 16); + secp256k1_sha256_finalize(hash_ctx, &hash, out32); for (i = 0; i < 4; ++i) { uint64_t s = 0; int j; diff --git a/src/tests.c b/src/tests.c index fa580cc9..9c2ab89c 100644 --- a/src/tests.c +++ b/src/tests.c @@ -132,6 +132,7 @@ static int ecmult_gen_context_eq(const secp256k1_ecmult_gen_context *a, const se static int context_eq(const secp256k1_context *a, const secp256k1_context *b) { return a->declassify == b->declassify && ecmult_gen_context_eq(&a->ecmult_gen_ctx, &b->ecmult_gen_ctx) + && a->hash_ctx.fn_sha256_compression == b->hash_ctx.fn_sha256_compression && a->illegal_callback.fn == b->illegal_callback.fn && a->illegal_callback.data == b->illegal_callback.data && a->error_callback.fn == b->error_callback.fn @@ -454,6 +455,7 @@ static void run_ctz_tests(void) { /***** HASH TESTS *****/ static void run_sha256_known_output_tests(void) { + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); static const char *inputs[] = { "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", @@ -489,10 +491,10 @@ static void run_sha256_known_output_tests(void) { j = repeat[i]; secp256k1_sha256_initialize(&hasher); while (j > 0) { - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); + secp256k1_sha256_write(hash_ctx, &hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); j--; } - secp256k1_sha256_finalize(&hasher, out); + secp256k1_sha256_finalize(hash_ctx, &hasher, out); CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); /* 2. Run: split the input bytestrings randomly before writing */ if (strlen(inputs[i]) > 0) { @@ -500,11 +502,11 @@ static void run_sha256_known_output_tests(void) { secp256k1_sha256_initialize(&hasher); j = repeat[i]; while (j > 0) { - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); + secp256k1_sha256_write(hash_ctx, &hasher, (const unsigned char*)(inputs[i]), split); + secp256k1_sha256_write(hash_ctx, &hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); j--; } - secp256k1_sha256_finalize(&hasher, out); + secp256k1_sha256_finalize(hash_ctx, &hasher, out); CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); } } @@ -602,12 +604,13 @@ static void run_sha256_counter_tests(void) { {0x2c, 0xf3, 0xa9, 0xf6, 0x15, 0x25, 0x80, 0x70, 0x76, 0x99, 0x7d, 0xf1, 0xc3, 0x2f, 0xa3, 0x31, 0xff, 0x92, 0x35, 0x2e, 0x8d, 0x04, 0x13, 0x33, 0xd8, 0x0d, 0xdb, 0x4a, 0xf6, 0x8c, 0x03, 0x34}, {0xec, 0x12, 0x24, 0x9f, 0x35, 0xa4, 0x29, 0x8b, 0x9e, 0x4a, 0x95, 0xf8, 0x61, 0xaf, 0x61, 0xc5, 0x66, 0x55, 0x3e, 0x3f, 0x2a, 0x98, 0xea, 0x71, 0x16, 0x6b, 0x1c, 0xd9, 0xe4, 0x09, 0xd2, 0x8e}, }; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); unsigned int i; for (i = 0; i < sizeof(midstates)/sizeof(midstates[0]); i++) { unsigned char out[32]; secp256k1_sha256 hasher = midstates[i]; - secp256k1_sha256_write(&hasher, (const unsigned char*)input, strlen(input)); - secp256k1_sha256_finalize(&hasher, out); + secp256k1_sha256_write(hash_ctx, &hasher, (const unsigned char*)input, strlen(input)); + secp256k1_sha256_finalize(hash_ctx, &hasher, out); CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); } } @@ -624,9 +627,9 @@ static void test_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 } /* Convenience function for using test_sha256_eq to verify the correctness of a * tagged hash midstate. This function is used by some module tests. */ -static void test_sha256_tag_midstate(secp256k1_sha256 *sha_tagged, const unsigned char *tag, size_t taglen) { +static void test_sha256_tag_midstate(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha_tagged, const unsigned char *tag, size_t taglen) { secp256k1_sha256 sha; - secp256k1_sha256_initialize_tagged(&sha, tag, taglen); + secp256k1_sha256_initialize_tagged(hash_ctx, &sha, tag, taglen); test_sha256_eq(&sha, sha_tagged); } @@ -656,19 +659,20 @@ static void run_hmac_sha256_tests(void) { {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2} }; int i; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); for (i = 0; i < 6; i++) { secp256k1_hmac_sha256 hasher; unsigned char out[32]; - secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); - secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); - secp256k1_hmac_sha256_finalize(&hasher, out); + secp256k1_hmac_sha256_initialize(hash_ctx, &hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); + secp256k1_hmac_sha256_write(hash_ctx, &hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); + secp256k1_hmac_sha256_finalize(hash_ctx, &hasher, out); CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { int split = testrand_int(strlen(inputs[i])); - secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); - secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); - secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); - secp256k1_hmac_sha256_finalize(&hasher, out); + secp256k1_hmac_sha256_initialize(hash_ctx, &hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); + secp256k1_hmac_sha256_write(hash_ctx, &hasher, (const unsigned char*)(inputs[i]), split); + secp256k1_hmac_sha256_write(hash_ctx, &hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); + secp256k1_hmac_sha256_finalize(hash_ctx, &hasher, out); CHECK(secp256k1_memcmp_var(out, outputs[i], 32) == 0); } } @@ -689,27 +693,28 @@ static void run_rfc6979_hmac_sha256_tests(void) { {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94} }; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); secp256k1_rfc6979_hmac_sha256 rng; unsigned char out[32]; int i; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 64); + secp256k1_rfc6979_hmac_sha256_initialize(hash_ctx, &rng, key1, 64); for (i = 0; i < 3; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); + secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, out, 32); CHECK(secp256k1_memcmp_var(out, out1[i], 32) == 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 65); + secp256k1_rfc6979_hmac_sha256_initialize(hash_ctx, &rng, key1, 65); for (i = 0; i < 3; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); + secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, out, 32); CHECK(secp256k1_memcmp_var(out, out1[i], 32) != 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 64); + secp256k1_rfc6979_hmac_sha256_initialize(hash_ctx, &rng, key2, 64); for (i = 0; i < 3; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); + secp256k1_rfc6979_hmac_sha256_generate(hash_ctx, &rng, out, 32); CHECK(secp256k1_memcmp_var(out, out2[i], 32) == 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); @@ -746,10 +751,11 @@ static void run_sha256_initialize_midstate_tests(void) { 0xa9ec59eaul, 0x9b4c2ffful, 0x400821e2ul, 0x0dcf3847ul, 0xbe7ea179ul, 0xa5772bdcul, 0x7d29bfe3ul, 0xa486b855ul }; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); secp256k1_sha256 sha; secp256k1_sha256_initialize_midstate(&sha, 64, midstate); - test_sha256_tag_midstate(&sha, tag, sizeof(tag) - 1); + test_sha256_tag_midstate(hash_ctx, &sha, tag, sizeof(tag) - 1); } /***** MODINV TESTS *****/ @@ -5501,11 +5507,11 @@ static void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar if (secp256k1_ge_is_infinity(&r)) { /* Store infinity as 0x00 */ const unsigned char zerobyte[1] = {0}; - secp256k1_sha256_write(acc, zerobyte, 1); + secp256k1_sha256_write(secp256k1_get_hash_context(CTX), acc, zerobyte, 1); } else { /* Store other points using their uncompressed serialization. */ secp256k1_eckey_pubkey_serialize65(&r, bytes); - secp256k1_sha256_write(acc, bytes, sizeof(bytes)); + secp256k1_sha256_write(secp256k1_get_hash_context(CTX), acc, bytes, sizeof(bytes)); } } @@ -5547,7 +5553,7 @@ static void test_ecmult_constants_2bit(void) { test_ecmult_accumulate(&acc, &x, scratch); } } - secp256k1_sha256_finalize(&acc, b32); + secp256k1_sha256_finalize(secp256k1_get_hash_context(CTX), &acc, b32); CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0); secp256k1_scratch_space_destroy(CTX, scratch); @@ -5566,6 +5572,7 @@ static void test_ecmult_constants_sha(uint32_t prefix, size_t iter, const unsign unsigned char b32[32]; unsigned char inp[6]; size_t i; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(CTX, 65536); inp[0] = prefix & 0xFF; @@ -5585,12 +5592,12 @@ static void test_ecmult_constants_sha(uint32_t prefix, size_t iter, const unsign inp[4] = i & 0xff; inp[5] = (i >> 8) & 0xff; secp256k1_sha256_initialize(&gen); - secp256k1_sha256_write(&gen, inp, sizeof(inp)); - secp256k1_sha256_finalize(&gen, b32); + secp256k1_sha256_write(hash_ctx, &gen, inp, sizeof(inp)); + secp256k1_sha256_finalize(hash_ctx, &gen, b32); secp256k1_scalar_set_b32(&x, b32, NULL); test_ecmult_accumulate(&acc, &x, scratch); } - secp256k1_sha256_finalize(&acc, b32); + secp256k1_sha256_finalize(hash_ctx, &acc, b32); CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0); secp256k1_scratch_space_destroy(CTX, scratch); @@ -5644,7 +5651,7 @@ static void test_ecmult_gen_blind(void) { testrand256(seed32); b = CTX->ecmult_gen_ctx.scalar_offset; p = CTX->ecmult_gen_ctx.ge_offset; - secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, seed32); + secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, secp256k1_get_hash_context(CTX), seed32); CHECK(!secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.scalar_offset)); secp256k1_ecmult_gen(&CTX->ecmult_gen_ctx, &pgej2, &key); CHECK(!gej_xyz_equals_gej(&pgej, &pgej2)); @@ -5657,10 +5664,10 @@ static void test_ecmult_gen_blind_reset(void) { /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */ secp256k1_scalar b; secp256k1_ge p1, p2; - secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, 0); + secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, secp256k1_get_hash_context(CTX), 0); b = CTX->ecmult_gen_ctx.scalar_offset; p1 = CTX->ecmult_gen_ctx.ge_offset; - secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, 0); + secp256k1_ecmult_gen_blind(&CTX->ecmult_gen_ctx, secp256k1_get_hash_context(CTX), 0); CHECK(secp256k1_scalar_eq(&b, &CTX->ecmult_gen_ctx.scalar_offset)); p2 = CTX->ecmult_gen_ctx.ge_offset; CHECK(secp256k1_ge_eq_var(&p1, &p2)); @@ -7467,6 +7474,7 @@ static void test_ecdsa_wycheproof(void) { #include "wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h" int t; + const secp256k1_hash_ctx *hash_ctx = secp256k1_get_hash_context(CTX); for (t = 0; t < SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS; t++) { secp256k1_ecdsa_signature signature; secp256k1_sha256 hasher; @@ -7481,8 +7489,8 @@ static void test_ecdsa_wycheproof(void) { secp256k1_sha256_initialize(&hasher); msg = &wycheproof_ecdsa_messages[testvectors[t].msg_offset]; - secp256k1_sha256_write(&hasher, msg, testvectors[t].msg_len); - secp256k1_sha256_finalize(&hasher, out); + secp256k1_sha256_write(hash_ctx, &hasher, msg, testvectors[t].msg_len); + secp256k1_sha256_finalize(hash_ctx, &hasher, out); sig = &wycheproof_ecdsa_signatures[testvectors[t].sig_offset]; if (secp256k1_ecdsa_signature_parse_der(CTX, &signature, sig, testvectors[t].sig_len) == 1) {