From c8fbc3c397b547bc64435a9bffb8f989cd23aba0 Mon Sep 17 00:00:00 2001 From: Kirill Fomichev Date: Thu, 17 May 2018 00:12:46 +0300 Subject: [PATCH] [ECDH API change] Allow pass arbitrary data to hash function --- include/secp256k1_ecdh.h | 8 ++++++-- src/bench_ecdh.c | 2 +- src/java/org_bitcoin_NativeSecp256k1.c | 1 + src/modules/ecdh/main_impl.h | 7 ++++--- src/modules/ecdh/tests_impl.h | 28 ++++++++++++++------------ 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/include/secp256k1_ecdh.h b/include/secp256k1_ecdh.h index 09a39e89c86d0..df5fde235c7b9 100644 --- a/include/secp256k1_ecdh.h +++ b/include/secp256k1_ecdh.h @@ -13,11 +13,13 @@ extern "C" { * Out: output: pointer to an array to be filled by the function * In: x: pointer to a 32-byte x coordinate * y: pointer to a 32-byte y coordinate + * data: Arbitrary data pointer that is passed through */ typedef int (*secp256k1_ecdh_hash_function)( unsigned char *output, const unsigned char *x, - const unsigned char *y + const unsigned char *y, + void *data ); /** An implementation of SHA256 hash function that applies to compressed public key. */ @@ -35,13 +37,15 @@ SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_func * initialized public key * privkey: a 32-byte scalar with which to multiply the point * hashfp: pointer to a hash function. If NULL, secp256k1_ecdh_hash_function_sha256 is used + * data: Arbitrary data pointer that is passed through */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( const secp256k1_context* ctx, unsigned char *output, const secp256k1_pubkey *pubkey, const unsigned char *privkey, - secp256k1_ecdh_hash_function hashfp + secp256k1_ecdh_hash_function hashfp, + void *data ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); #ifdef __cplusplus diff --git a/src/bench_ecdh.c b/src/bench_ecdh.c index 1c9c1a107776f..c1dd5a6ac93c8 100644 --- a/src/bench_ecdh.c +++ b/src/bench_ecdh.c @@ -42,7 +42,7 @@ static void bench_ecdh(void* arg) { bench_ecdh_data *data = (bench_ecdh_data*)arg; for (i = 0; i < 20000; i++) { - CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar, NULL) == 1); + CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar, NULL, NULL) == 1); } } diff --git a/src/java/org_bitcoin_NativeSecp256k1.c b/src/java/org_bitcoin_NativeSecp256k1.c index 5d3cde37cb604..b50970b4f24c8 100644 --- a/src/java/org_bitcoin_NativeSecp256k1.c +++ b/src/java/org_bitcoin_NativeSecp256k1.c @@ -354,6 +354,7 @@ SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1e nonce_res, &pubkey, secdata, + NULL, NULL ); } diff --git a/src/modules/ecdh/main_impl.h b/src/modules/ecdh/main_impl.h index 1cc9f26fb79a2..44cb68e750251 100644 --- a/src/modules/ecdh/main_impl.h +++ b/src/modules/ecdh/main_impl.h @@ -10,9 +10,10 @@ #include "include/secp256k1_ecdh.h" #include "ecmult_const_impl.h" -static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x, const unsigned char *y) { +static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) { unsigned char version = (y[31] & 0x01) | 0x02; secp256k1_sha256 sha; + (void)data; secp256k1_sha256_initialize(&sha); secp256k1_sha256_write(&sha, &version, 1); @@ -25,7 +26,7 @@ static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char 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; -int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pubkey *point, const unsigned char *scalar, secp256k1_ecdh_hash_function hashfp) { +int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pubkey *point, const unsigned char *scalar, secp256k1_ecdh_hash_function hashfp, void *data) { int ret = 0; int overflow = 0; secp256k1_gej res; @@ -56,7 +57,7 @@ int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *output, const se secp256k1_fe_get_b32(x, &pt.x); secp256k1_fe_get_b32(y, &pt.y); - ret = hashfp(output, x, y); + ret = hashfp(output, x, y, data); } secp256k1_scalar_clear(&s); diff --git a/src/modules/ecdh/tests_impl.h b/src/modules/ecdh/tests_impl.h index 63d45df17d56a..fe26e8fb6957d 100644 --- a/src/modules/ecdh/tests_impl.h +++ b/src/modules/ecdh/tests_impl.h @@ -7,14 +7,16 @@ #ifndef SECP256K1_MODULE_ECDH_TESTS_H #define SECP256K1_MODULE_ECDH_TESTS_H -int ecdh_hash_function_test_fail(unsigned char *output, const unsigned char *x, const unsigned char *y) { +int ecdh_hash_function_test_fail(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) { (void)output; (void)x; (void)y; + (void)data; return 0; } -int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y) { +int ecdh_hash_function_custom(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) { + (void)data; /* Save x and y as uncompressed public key */ output[0] = 0x04; memcpy(output + 1, x, 32); @@ -36,15 +38,15 @@ void test_ecdh_api(void) { CHECK(secp256k1_ec_pubkey_create(tctx, &point, s_one) == 1); /* Check all NULLs are detected */ - CHECK(secp256k1_ecdh(tctx, res, &point, s_one, NULL) == 1); + CHECK(secp256k1_ecdh(tctx, res, &point, s_one, NULL, NULL) == 1); CHECK(ecount == 0); - CHECK(secp256k1_ecdh(tctx, NULL, &point, s_one, NULL) == 0); + CHECK(secp256k1_ecdh(tctx, NULL, &point, s_one, NULL, NULL) == 0); CHECK(ecount == 1); - CHECK(secp256k1_ecdh(tctx, res, NULL, s_one, NULL) == 0); + CHECK(secp256k1_ecdh(tctx, res, NULL, s_one, NULL, NULL) == 0); CHECK(ecount == 2); - CHECK(secp256k1_ecdh(tctx, res, &point, NULL, NULL) == 0); + CHECK(secp256k1_ecdh(tctx, res, &point, NULL, NULL, NULL) == 0); CHECK(ecount == 3); - CHECK(secp256k1_ecdh(tctx, res, &point, s_one, NULL) == 1); + CHECK(secp256k1_ecdh(tctx, res, &point, s_one, NULL, NULL) == 1); CHECK(ecount == 3); /* Cleanup */ @@ -74,14 +76,14 @@ void test_ecdh_generator_basepoint(void) { CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); /* compute using ECDH function with custom hash function */ - CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32, ecdh_hash_function_custom) == 1); + CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32, ecdh_hash_function_custom, NULL) == 1); /* compute "explicitly" */ CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_UNCOMPRESSED) == 1); /* compare */ CHECK(memcmp(output_ecdh, point_ser, 65) == 0); /* compute using ECDH function with default hash function */ - CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32, NULL) == 1); + CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32, NULL, NULL) == 1); /* compute "explicitly" */ CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); secp256k1_sha256_initialize(&sha); @@ -111,14 +113,14 @@ void test_bad_scalar(void) { CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1); /* Try to multiply it by bad values */ - CHECK(secp256k1_ecdh(ctx, output, &point, s_zero, NULL) == 0); - CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow, NULL) == 0); + CHECK(secp256k1_ecdh(ctx, output, &point, s_zero, NULL, NULL) == 0); + CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow, NULL, NULL) == 0); /* ...and a good one */ s_overflow[31] -= 1; - CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow, NULL) == 1); + CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow, NULL, NULL) == 1); /* Hash function failure results in ecdh failure */ - CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow, ecdh_hash_function_test_fail) == 0); + CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow, ecdh_hash_function_test_fail, NULL) == 0); } void run_ecdh_tests(void) {