Introduce hash context to support pluggable SHA256 compression
What changed, and why it matters
This commit is a large but purely structural refactor of the libsecp256k1 cryptographic library. It threads a new 'hash context' through every SHA-256, HMAC-SHA-256, and RFC 6979 operation so that a different SHA-256 compression implementation (for example a faster hardware version) can be plugged in later. The commit message explicitly calls it a 'mechanical change with no behavior change,' and the code keeps the existing software compression function as the default everywhere. There is no security bug or vulnerability visible in this patch.
No security action required. Treat as a normal code-quality/performance-preparation refactor. Review the follow-up commit that actually supplies an alternative SHA-256 compression function, as that is where security-relevant behavior could change.
Security signals we found
No security-relevant signals: refactor only
Default SHA-256 compression function unchanged
No new externally controllable function pointers introduced in this commit
No changes to cryptographic algorithms or their inputs/outputs
Evidence from the diff
The change introduces secp256k1_hash_ctx, which currently holds a single function pointer fn_sha256_compression defaulting to the existing secp256k1_sha256_transform. It stores this context inside secp256k1_context, initializes it in context creation, and propagates it as an extra argument to secp256k1_sha256_write/finalize, HMAC-SHA-256, RFC 6979, Schnorr challenge/nonce, MuSig nonce/keyagg, ElligatorSwift, ECDH, and test helpers. The default compression function is unchanged, and all existing test vectors and self-tests are preserved. No new externally supplied callback is exposed, no behavior changes, and no memory-safety or cryptographic flaws are introduced by the diff itself.
Changed components
src/hash.hsrc/hash_impl.hsrc/secp256k1.csrc/ecmult_gen.hsrc/ecmult_gen_impl.hsrc/modules/ecdh/main_impl.hsrc/modules/ellswift/main_impl.hsrc/modules/musig/keyagg_impl.hsrc/modules/musig/session_impl.hsrc/modules/schnorrsig/main_impl.hbenchmark and test filesInspect captured patch +313 / −238
diff --git a/src/bench_ecmult.c b/src/bench_ecmult.c
index bcf8b43..c7c6ade 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 001bd25..44f8d2c 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 43dd10c..8bc4f14 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 2159eed..5a95497 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 43cdd60..35825ea 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -10,6 +10,14 @@
#include <stdlib.h>
#include <stdint.h>
+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 da3b466..d5f16cd 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 9f2dfdd..3ee3ca7 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 cb1d953..e6c1bab 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 f9ef0ac..29c0a53 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 e309041..c9a7500 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 a0b3725..30e77aa 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 4eb48dd..f67245d 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 42fcd81..6a37bfd 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 de09c5e..cbeb1e2 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 21c1f41..3fe645b 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 601b549..a8298f6 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 9a1b15f..009bb3e 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 218ceaf..b91b3bc 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 d083ac9..de0e059 100644
--- a/src/selftest.h
+++ b/src/selftest.h
@@ -11,7 +11,8 @@
#include <string.h>
-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 b84f573..e1e5d85 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 fa580cc..9c2ab89 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) {
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.