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:
21 files changed
+313
-238
No files matched your search
+4
-4
@@ -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
@@ -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
@@ -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 */
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user