diff --git a/Makefile.am b/Makefile.am index 66f975bb22..4baff32715 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,8 +13,6 @@ noinst_HEADERS += src/group.h noinst_HEADERS += src/group_impl.h noinst_HEADERS += src/num_gmp.h noinst_HEADERS += src/num_gmp_impl.h -noinst_HEADERS += src/ecdh.h -noinst_HEADERS += src/ecdh_impl.h noinst_HEADERS += src/ecdsa.h noinst_HEADERS += src/ecdsa_impl.h noinst_HEADERS += src/eckey.h @@ -51,7 +49,7 @@ libsecp256k1_la_LIBADD = $(SECP_LIBS) noinst_PROGRAMS = if USE_BENCHMARK -noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal bench_ecdh +noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal bench_verify_SOURCES = src/bench_verify.c bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) bench_verify_LDFLAGS = -static @@ -65,10 +63,6 @@ bench_internal_SOURCES = src/bench_internal.c bench_internal_LDADD = $(SECP_LIBS) bench_internal_LDFLAGS = -static bench_internal_CPPFLAGS = $(SECP_INCLUDES) -bench_ecdh_SOURCES = src/bench_ecdh.c -bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) -bench_ecdh_LDFLAGS = -static -bench_ecdh_CPPFLAGS = $(SECP_INCLUDES) endif if USE_TESTS @@ -101,3 +95,7 @@ CLEANFILES = gen_context src/ecmult_static_context.h endif EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h + +if ENABLE_MODULE_ECDH +include src/modules/ecdh/Makefile.am.include +endif diff --git a/configure.ac b/configure.ac index 70c9e593f6..e3126dbe26 100644 --- a/configure.ac +++ b/configure.ac @@ -102,6 +102,11 @@ AC_ARG_ENABLE(ecmult_static_precomputation, [use_ecmult_static_precomputation=$enableval], [use_ecmult_static_precomputation=yes]) +AC_ARG_ENABLE(module_ecdh, + AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (default is no)]), + [enable_module_ecdh=$enableval], + [enable_module_ecdh=no]) + AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], [Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) @@ -315,6 +320,10 @@ if test x"$use_ecmult_static_precomputation" = x"yes"; then AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) fi +if test x"$enable_module_ecdh" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) +fi + AC_C_BIGENDIAN() AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) @@ -322,6 +331,7 @@ AC_MSG_NOTICE([Using field implementation: $set_field]) AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) +AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) AC_CONFIG_FILES([Makefile libsecp256k1.pc]) @@ -332,6 +342,7 @@ AC_SUBST(SECP_TEST_INCLUDES) AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$use_ecmult_static_precomputation" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"]) dnl make sure nothing new is exported so that we don't break the cache PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" diff --git a/include/secp256k1.h b/include/secp256k1.h index e496d9e8d8..411156ac1d 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -339,22 +339,6 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( secp256k1_pubkey_t *pubkey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** Compute an EC Diffie-Hellman secret in constant time - * Returns: 1: exponentiation was successful - * 0: scalar was invalid (zero or overflow) - * In: ctx: pointer to a context object (cannot be NULL) - * point: pointer to a public point - * scalar: a 32-byte scalar with which to multiply the point - * Out: result: a 32-byte array which will be populated by an ECDH - * secret computed from the point and scalar - */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( - const secp256k1_context_t* ctx, - unsigned char *result, - const secp256k1_pubkey_t *point, - const unsigned char *scalar -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - /** Verify an ECDSA secret key. * Returns: 1: secret key is valid * 0: secret key is invalid diff --git a/include/secp256k1_ecdh.h b/include/secp256k1_ecdh.h new file mode 100644 index 0000000000..671c393fae --- /dev/null +++ b/include/secp256k1_ecdh.h @@ -0,0 +1,30 @@ +#ifndef _SECP256K1_ECDH_ +# define _SECP256K1_ECDH_ + +# include "secp256k1.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/** Compute an EC Diffie-Hellman secret in constant time + * Returns: 1: exponentiation was successful + * 0: scalar was invalid (zero or overflow) + * In: ctx: pointer to a context object (cannot be NULL) + * point: pointer to a public point + * scalar: a 32-byte scalar with which to multiply the point + * Out: result: a 32-byte array which will be populated by an ECDH + * secret computed from the point and scalar + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( + const secp256k1_context_t* ctx, + unsigned char *result, + const secp256k1_pubkey_t *point, + const unsigned char *scalar +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/src/bench_ecdh.c b/src/bench_ecdh.c index 0c4d7bab95..5a52ecb66c 100644 --- a/src/bench_ecdh.c +++ b/src/bench_ecdh.c @@ -7,6 +7,7 @@ #include #include "include/secp256k1.h" +#include "include/secp256k1_ecdh.h" #include "util.h" #include "bench.h" diff --git a/src/bench_internal.c b/src/bench_internal.c index 856f8e1309..725f54d659 100644 --- a/src/bench_internal.c +++ b/src/bench_internal.c @@ -13,9 +13,11 @@ #include "field_impl.h" #include "group_impl.h" #include "scalar_impl.h" -#include "ecdh_impl.h" #include "ecmult_impl.h" #include "bench.h" +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/ecdh_impl.h" +#endif typedef struct { secp256k1_scalar_t scalar_x, scalar_y; @@ -236,6 +238,7 @@ void bench_ecmult_wnaf(void* arg) { } } +#ifdef ENABLE_MODULE_ECDH void bench_ecdh_wnaf(void* arg) { int i; bench_inv_t *data = (bench_inv_t*)arg; @@ -245,7 +248,7 @@ void bench_ecdh_wnaf(void* arg) { secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); } } - +#endif void bench_sha256(void* arg) { int i; @@ -321,7 +324,9 @@ int main(int argc, char **argv) { if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); +#ifdef ENABLE_MODULE_ECDH if (have_flag(argc, argv, "ecdh") || have_flag(argc, argv, "wnaf")) run_benchmark("ecdh_wnaf", bench_ecdh_wnaf, bench_setup, NULL, &data, 10, 20000); +#endif if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000); diff --git a/src/modules/ecdh/Makefile.am.include b/src/modules/ecdh/Makefile.am.include new file mode 100644 index 0000000000..69ffa99e25 --- /dev/null +++ b/src/modules/ecdh/Makefile.am.include @@ -0,0 +1,11 @@ +include_HEADERS += include/secp256k1_ecdh.h +noinst_HEADERS += src/modules/ecdh/main_impl.h +noinst_HEADERS += src/modules/ecdh/ecdh.h +noinst_HEADERS += src/modules/ecdh/ecdh_impl.h +noinst_HEADERS += src/modules/ecdh/tests_impl.h +if USE_BENCHMARK +noinst_PROGRAMS += bench_ecdh +bench_ecdh_SOURCES = src/bench_ecdh.c +bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_ecdh_LDFLAGS = -static +endif diff --git a/src/ecdh.h b/src/modules/ecdh/ecdh.h similarity index 78% rename from src/ecdh.h rename to src/modules/ecdh/ecdh.h index 7fbd9c9caf..f4ddca0ab1 100644 --- a/src/ecdh.h +++ b/src/modules/ecdh/ecdh.h @@ -1,11 +1,11 @@ /********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Copyright (c) 2015 Andrew Poelstra * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECDH_ -#define _SECP256K1_ECDH_ +#ifndef _SECP256K1_MODULE_ECDH_ +#define _SECP256K1_MODULE_ECDH_ #include "scalar.h" #include "group.h" diff --git a/src/ecdh_impl.h b/src/modules/ecdh/ecdh_impl.h similarity index 99% rename from src/ecdh_impl.h rename to src/modules/ecdh/ecdh_impl.h index 027b55b2d5..24e81df90c 100644 --- a/src/ecdh_impl.h +++ b/src/modules/ecdh/ecdh_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECDH_IMPL_ -#define _SECP256K1_ECDH_IMPL_ +#ifndef _SECP256K1_MODULE_ECDH_IMPL_ +#define _SECP256K1_MODULE_ECDH_IMPL_ #include "scalar.h" #include "group.h" diff --git a/src/modules/ecdh/main_impl.h b/src/modules/ecdh/main_impl.h new file mode 100644 index 0000000000..3d4bad1bed --- /dev/null +++ b/src/modules/ecdh/main_impl.h @@ -0,0 +1,53 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_MODULE_ECDH_MAIN_ +#define _SECP256K1_MODULE_ECDH_MAIN_ + +#include "modules/ecdh/ecdh_impl.h" + +int secp256k1_ecdh(const secp256k1_context_t* ctx, unsigned char *result, const secp256k1_pubkey_t *point, const unsigned char *scalar) { + int ret = 0; + int overflow = 0; + secp256k1_gej_t res; + secp256k1_ge_t pt; + secp256k1_scalar_t s; + ARG_CHECK(result != NULL); + ARG_CHECK(point != NULL); + ARG_CHECK(scalar != NULL); + (void)ctx; + + secp256k1_pubkey_load(ctx, &pt, point); + secp256k1_scalar_set_b32(&s, scalar, &overflow); + if (overflow || secp256k1_scalar_is_zero(&s)) { + ret = 0; + } else { + unsigned char x[32]; + unsigned char y[1]; + secp256k1_sha256_t sha; + + secp256k1_point_multiply(&res, &pt, &s); + secp256k1_ge_set_gej(&pt, &res); + /* Compute a hash of the point in compressed form + * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not + * expect its output to be secret and has a timing sidechannel. */ + secp256k1_fe_normalize(&pt.x); + secp256k1_fe_normalize(&pt.y); + secp256k1_fe_get_b32(x, &pt.x); + y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); + + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, y, sizeof(y)); + secp256k1_sha256_write(&sha, x, sizeof(x)); + secp256k1_sha256_finalize(&sha, result); + ret = 1; + } + + secp256k1_scalar_clear(&s); + return ret; +} + +#endif diff --git a/src/secp256k1.c b/src/secp256k1.c index 879cf77936..82c0b81e6d 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -13,7 +13,6 @@ #include "field_impl.h" #include "scalar_impl.h" #include "group_impl.h" -#include "ecdh_impl.h" #include "ecmult_impl.h" #include "ecmult_gen_impl.h" #include "ecdsa_impl.h" @@ -362,47 +361,6 @@ int secp256k1_ecdsa_recover(const secp256k1_context_t* ctx, const unsigned char } } -int secp256k1_ecdh(const secp256k1_context_t* ctx, unsigned char *result, const secp256k1_pubkey_t *point, const unsigned char *scalar) { - int ret = 0; - int overflow = 0; - secp256k1_gej_t res; - secp256k1_ge_t pt; - secp256k1_scalar_t s; - ARG_CHECK(result != NULL); - ARG_CHECK(point != NULL); - ARG_CHECK(scalar != NULL); - (void)ctx; - - secp256k1_pubkey_load(ctx, &pt, point); - secp256k1_scalar_set_b32(&s, scalar, &overflow); - if (overflow || secp256k1_scalar_is_zero(&s)) { - ret = 0; - } else { - unsigned char x[32]; - unsigned char y[1]; - secp256k1_sha256_t sha; - - secp256k1_point_multiply(&res, &pt, &s); - secp256k1_ge_set_gej(&pt, &res); - /* Compute a hash of the point in compressed form - * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not - * expect its output to be secret and has a timing sidechannel. */ - secp256k1_fe_normalize(&pt.x); - secp256k1_fe_normalize(&pt.y); - secp256k1_fe_get_b32(x, &pt.x); - y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); - - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, y, sizeof(y)); - secp256k1_sha256_write(&sha, x, sizeof(x)); - secp256k1_sha256_finalize(&sha, result); - ret = 1; - } - - secp256k1_scalar_clear(&s); - return ret; -} - int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned char *seckey) { secp256k1_scalar_t sec; int ret; @@ -567,3 +525,8 @@ int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *s secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); return 1; } + +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/main_impl.h" +#endif + diff --git a/src/tests.c b/src/tests.c index 8ecf10f419..119dda12ba 100644 --- a/src/tests.c +++ b/src/tests.c @@ -1271,149 +1271,6 @@ void run_ge(void) { test_add_neg_y_diff_x(); } -/***** ECDH TESTS *****/ - -void ecdh_random_mult(void) { - /* random starting point A (on the curve) */ - secp256k1_ge_t a = SECP256K1_GE_CONST( - 0x6d986544, 0x57ff52b8, 0xcf1b8126, 0x5b802a5b, - 0xa97f9263, 0xb1e88044, 0x93351325, 0x91bc450a, - 0x535c59f7, 0x325e5d2b, 0xc391fbe8, 0x3c12787c, - 0x337e4a98, 0xe82a9011, 0x0123ba37, 0xdd769c7d - ); - /* random initial factor xn */ - secp256k1_scalar_t xn = SECP256K1_SCALAR_CONST( - 0x649d4f77, 0xc4242df7, 0x7f2079c9, 0x14530327, - 0xa31b876a, 0xd2d8ce2a, 0x2236d5c6, 0xd7b2029b - ); - /* expected xn * A (from sage) */ - secp256k1_ge_t expected_b = SECP256K1_GE_CONST( - 0x23773684, 0x4d209dc7, 0x098a786f, 0x20d06fcd, - 0x070a38bf, 0xc11ac651, 0x03004319, 0x1e2a8786, - 0xed8c3b8e, 0xc06dd57b, 0xd06ea66e, 0x45492b0f, - 0xb84e4e1b, 0xfb77e21f, 0x96baae2a, 0x63dec956 - ); - secp256k1_gej_t b; - secp256k1_point_multiply(&b, &a, &xn); - - CHECK(secp256k1_ge_is_valid_var(&a)); - ge_equals_gej(&expected_b, &b); -} - -void ecdh_commutativity(void) { - secp256k1_scalar_t a; - secp256k1_scalar_t b; - secp256k1_gej_t res1; - secp256k1_gej_t res2; - secp256k1_ge_t mid1; - secp256k1_ge_t mid2; - random_scalar_order_test(&a); - random_scalar_order_test(&b); - - secp256k1_point_multiply(&res1, &secp256k1_ge_const_g, &a); - secp256k1_point_multiply(&res2, &secp256k1_ge_const_g, &b); - secp256k1_ge_set_gej(&mid1, &res1); - secp256k1_ge_set_gej(&mid2, &res2); - secp256k1_point_multiply(&res1, &mid1, &b); - secp256k1_point_multiply(&res2, &mid2, &a); - secp256k1_ge_set_gej(&mid1, &res1); - secp256k1_ge_set_gej(&mid2, &res2); - ge_equals_ge(&mid1, &mid2); -} - -void ecdh_mult_zero_one(void) { - secp256k1_scalar_t zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - secp256k1_scalar_t one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_scalar_t negone; - secp256k1_gej_t res1; - secp256k1_ge_t res2; - secp256k1_ge_t point; - secp256k1_scalar_negate(&negone, &one); - - random_group_element_test(&point); - secp256k1_point_multiply(&res1, &point, &zero); - secp256k1_ge_set_gej(&res2, &res1); - CHECK(secp256k1_ge_is_infinity(&res2)); - secp256k1_point_multiply(&res1, &point, &one); - secp256k1_ge_set_gej(&res2, &res1); - ge_equals_ge(&res2, &point); - secp256k1_point_multiply(&res1, &point, &negone); - secp256k1_gej_neg(&res1, &res1); - secp256k1_ge_set_gej(&res2, &res1); - ge_equals_ge(&res2, &point); -} - -void ecdh_chain_multiply(void) { - /* Check known result (randomly generated test problem from sage) */ - const secp256k1_scalar_t scalar = SECP256K1_SCALAR_CONST( - 0x4968d524, 0x2abf9b7a, 0x466abbcf, 0x34b11b6d, - 0xcd83d307, 0x827bed62, 0x05fad0ce, 0x18fae63b - ); - const secp256k1_gej_t expected_point = SECP256K1_GEJ_CONST( - 0x5494c15d, 0x32099706, 0xc2395f94, 0x348745fd, - 0x757ce30e, 0x4e8c90fb, 0xa2bad184, 0xf883c69f, - 0x5d195d20, 0xe191bf7f, 0x1be3e55f, 0x56a80196, - 0x6071ad01, 0xf1462f66, 0xc997fa94, 0xdb858435 - ); - secp256k1_gej_t point; - secp256k1_ge_t res; - int i; - - secp256k1_gej_set_ge(&point, &secp256k1_ge_const_g); - for (i = 0; i < 100; ++i) { - secp256k1_ge_t tmp; - secp256k1_ge_set_gej(&tmp, &point); - secp256k1_point_multiply(&point, &tmp, &scalar); - } - secp256k1_ge_set_gej(&res, &point); - ge_equals_gej(&res, &expected_point); -} - -void ecdh_generator_basepoint(void) { - unsigned char s_one[32] = { 0 }; - secp256k1_pubkey_t point[2]; - int i; - - s_one[31] = 1; - /* Check against pubkey creation when the basepoint is the generator */ - for (i = 0; i < 100; ++i) { - secp256k1_sha256_t sha; - unsigned char s_b32[32]; - unsigned char output_ecdh[32]; - unsigned char output_ser[32]; - unsigned char point_ser[33]; - int point_ser_len = sizeof(point_ser); - secp256k1_scalar_t s; - - random_scalar_order(&s); - secp256k1_scalar_get_b32(s_b32, &s); - - /* compute using ECDH function */ - CHECK(secp256k1_ec_pubkey_create(ctx, &point[0], s_one) == 1); - CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1); - /* compute "explicitly" */ - CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); - CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], 1) == 1); - CHECK(point_ser_len == sizeof(point_ser)); - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, point_ser, point_ser_len); - secp256k1_sha256_finalize(&sha, output_ser); - /* compare */ - CHECK(memcmp(output_ecdh, output_ser, sizeof(output_ser)) == 0); - } -} - -void run_ecdh_tests(void) { - ecdh_mult_zero_one(); - ecdh_random_mult(); - ecdh_commutativity(); - ecdh_chain_multiply(); -} - -void run_ecdh_api_tests(void) { - ecdh_generator_basepoint(); -} - /***** ECMULT TESTS *****/ void run_ecmult_chain(void) { @@ -1571,65 +1428,6 @@ void test_wnaf(const secp256k1_scalar_t *number, int w) { CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */ } -void test_constant_wnaf_negate(const secp256k1_scalar_t *number) { - secp256k1_scalar_t neg1 = *number; - secp256k1_scalar_t neg2 = *number; - int sign1 = 1; - int sign2 = 1; - - if (!secp256k1_scalar_get_bits(&neg1, 0, 1)) { - secp256k1_scalar_negate(&neg1, &neg1); - sign1 = -1; - } - sign2 = secp256k1_scalar_cond_negate(&neg2, secp256k1_scalar_is_even(&neg2)); - CHECK(sign1 == sign2); - CHECK(secp256k1_scalar_eq(&neg1, &neg2)); -} - -void test_constant_wnaf(const secp256k1_scalar_t *number, int w) { - secp256k1_scalar_t x, shift; - int wnaf[256] = {0}; - int i; -#ifdef USE_ENDOMORPHISM - int skew; -#endif - secp256k1_scalar_t num = *number; - - secp256k1_scalar_set_int(&x, 0); - secp256k1_scalar_set_int(&shift, 1 << w); - /* With USE_ENDOMORPHISM on we only consider 128-bit numbers */ -#ifdef USE_ENDOMORPHISM - for (i = 0; i < 16; ++i) - secp256k1_scalar_shr_int(&num, 8); - skew = secp256k1_ecdh_wnaf(wnaf, num, w); -#else - secp256k1_ecdh_wnaf(wnaf, num, w); -#endif - - for (i = WNAF_SIZE(w); i >= 0; --i) { - secp256k1_scalar_t t; - int v = wnaf[i]; - CHECK(v != 0); /* check nonzero */ - CHECK(v & 1); /* check parity */ - CHECK(v > -(1 << w)); /* check range above */ - CHECK(v < (1 << w)); /* check range below */ - - secp256k1_scalar_mul(&x, &x, &shift); - if (v >= 0) { - secp256k1_scalar_set_int(&t, v); - } else { - secp256k1_scalar_set_int(&t, -v); - secp256k1_scalar_negate(&t, &t); - } - secp256k1_scalar_add(&x, &x, &t); - } -#ifdef USE_ENDOMORPHISM - /* Skew num because when encoding 128-bit numbers as odd we use an offset */ - secp256k1_scalar_cadd_bit(&num, skew == 2, 1); -#endif - CHECK(secp256k1_scalar_eq(&x, &num)); -} - void run_wnaf(void) { int i; secp256k1_scalar_t n = {{0}}; @@ -1637,15 +1435,13 @@ void run_wnaf(void) { /* Sanity check: 1 and 2 are the smallest odd and even numbers and should * have easier-to-diagnose failure modes */ n.d[0] = 1; - test_constant_wnaf(&n, 4); + test_wnaf(&n, 4); n.d[0] = 2; - test_constant_wnaf(&n, 4); + test_wnaf(&n, 4); /* Random tests */ for (i = 0; i < count; i++) { random_scalar_order(&n); test_wnaf(&n, 4+(i%10)); - test_constant_wnaf_negate(&n); - test_constant_wnaf(&n, 4 + (i % 10)); } } @@ -2414,6 +2210,10 @@ void run_ecdsa_openssl(void) { } #endif +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/tests_impl.h" +#endif + int main(int argc, char **argv) { unsigned char seed16[16] = {0}; unsigned char run32[32] = {0}; @@ -2501,9 +2301,11 @@ int main(int argc, char **argv) { run_endomorphism_tests(); #endif +#ifdef ENABLE_MODULE_ECDH /* ecdh tests */ run_ecdh_tests(); run_ecdh_api_tests(); +#endif /* ecdsa tests */ run_random_pubkeys();