Introduce hash context to support pluggable SHA256 compression

This is purely a mechanical change with no behavior change.

It introduces a secp256k1_hash_ctx struct inside secp256k1_context
and propagates it to all SHA256-related operations.

This sets up the ability to provide a hardware-optimized SHA256
compression function at runtime in a follow-up commit.
This commit is contained in:
furszy committed 2026-03-03 10:25:50 -03:00
1 parent 95e6815843
commit fdb6a91a5e
21 files changed
+313 -238

No files matched your search

+4 -4
View File
@@ -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]);
+14 -7
View File
@@ -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);
}
}
+3 -2
View File
@@ -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 */
+6 -6
View File
@@ -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. */
+15 -7
View File
@@ -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);
+64 -50
View File
@@ -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;
}
+8 -4
View File
@@ -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;
+2 -2
View File
@@ -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);
}
+34 -26
View File
@@ -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;
+4 -3
View File
@@ -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) {
+1 -1
View File
@@ -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
+9 -9
View File
@@ -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;
}
+28 -28
View File
@@ -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.
+22 -20
View File
@@ -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));
}
}
+19 -15
View File
@@ -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);
@@ -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;
+6 -3
View File
@@ -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);
}
+19 -8
View File
@@ -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;
}
+7 -4
View File
@@ -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 */
+4 -3
View File
@@ -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;
+42 -34
View File
@@ -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) {