Skip to content

Commit

Permalink
Move ECDH into its own module
Browse files Browse the repository at this point in the history
  • Loading branch information
apoelstra committed Jul 29, 2015
1 parent d51027a commit 0820126
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 278 deletions.
12 changes: 5 additions & 7 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
11 changes: 11 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand Down Expand Up @@ -315,13 +320,18 @@ 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])
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])
Expand All @@ -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"
Expand Down
16 changes: 0 additions & 16 deletions include/secp256k1.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 30 additions & 0 deletions include/secp256k1_ecdh.h
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions src/bench_ecdh.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <string.h>

#include "include/secp256k1.h"
#include "include/secp256k1_ecdh.h"
#include "util.h"
#include "bench.h"

Expand Down
9 changes: 7 additions & 2 deletions src/bench_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions src/modules/ecdh/Makefile.am.include
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions src/ecdh.h → src/modules/ecdh/ecdh.h
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
4 changes: 2 additions & 2 deletions src/ecdh_impl.h → src/modules/ecdh/ecdh_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
53 changes: 53 additions & 0 deletions src/modules/ecdh/main_impl.h
Original file line number Diff line number Diff line change
@@ -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
47 changes: 5 additions & 42 deletions src/secp256k1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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

Loading

0 comments on commit 0820126

Please sign in to comment.