Skip to content

Commit 0820126

Browse files
committed
Move ECDH into its own module
1 parent d51027a commit 0820126

12 files changed

+136
-278
lines changed

Makefile.am

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ noinst_HEADERS += src/group.h
1313
noinst_HEADERS += src/group_impl.h
1414
noinst_HEADERS += src/num_gmp.h
1515
noinst_HEADERS += src/num_gmp_impl.h
16-
noinst_HEADERS += src/ecdh.h
17-
noinst_HEADERS += src/ecdh_impl.h
1816
noinst_HEADERS += src/ecdsa.h
1917
noinst_HEADERS += src/ecdsa_impl.h
2018
noinst_HEADERS += src/eckey.h
@@ -51,7 +49,7 @@ libsecp256k1_la_LIBADD = $(SECP_LIBS)
5149

5250
noinst_PROGRAMS =
5351
if USE_BENCHMARK
54-
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal bench_ecdh
52+
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal
5553
bench_verify_SOURCES = src/bench_verify.c
5654
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS)
5755
bench_verify_LDFLAGS = -static
@@ -65,10 +63,6 @@ bench_internal_SOURCES = src/bench_internal.c
6563
bench_internal_LDADD = $(SECP_LIBS)
6664
bench_internal_LDFLAGS = -static
6765
bench_internal_CPPFLAGS = $(SECP_INCLUDES)
68-
bench_ecdh_SOURCES = src/bench_ecdh.c
69-
bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS)
70-
bench_ecdh_LDFLAGS = -static
71-
bench_ecdh_CPPFLAGS = $(SECP_INCLUDES)
7266
endif
7367

7468
if USE_TESTS
@@ -101,3 +95,7 @@ CLEANFILES = gen_context src/ecmult_static_context.h
10195
endif
10296

10397
EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h
98+
99+
if ENABLE_MODULE_ECDH
100+
include src/modules/ecdh/Makefile.am.include
101+
endif

configure.ac

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ AC_ARG_ENABLE(ecmult_static_precomputation,
102102
[use_ecmult_static_precomputation=$enableval],
103103
[use_ecmult_static_precomputation=yes])
104104

105+
AC_ARG_ENABLE(module_ecdh,
106+
AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (default is no)]),
107+
[enable_module_ecdh=$enableval],
108+
[enable_module_ecdh=no])
109+
105110
AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto],
106111
[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto])
107112

@@ -315,13 +320,18 @@ if test x"$use_ecmult_static_precomputation" = x"yes"; then
315320
AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table])
316321
fi
317322

323+
if test x"$enable_module_ecdh" = x"yes"; then
324+
AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module])
325+
fi
326+
318327
AC_C_BIGENDIAN()
319328

320329
AC_MSG_NOTICE([Using assembly optimizations: $set_asm])
321330
AC_MSG_NOTICE([Using field implementation: $set_field])
322331
AC_MSG_NOTICE([Using bignum implementation: $set_bignum])
323332
AC_MSG_NOTICE([Using scalar implementation: $set_scalar])
324333
AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism])
334+
AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh])
325335

326336
AC_CONFIG_HEADERS([src/libsecp256k1-config.h])
327337
AC_CONFIG_FILES([Makefile libsecp256k1.pc])
@@ -332,6 +342,7 @@ AC_SUBST(SECP_TEST_INCLUDES)
332342
AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
333343
AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"])
334344
AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$use_ecmult_static_precomputation" = x"yes"])
345+
AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
335346

336347
dnl make sure nothing new is exported so that we don't break the cache
337348
PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"

include/secp256k1.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -339,22 +339,6 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
339339
secp256k1_pubkey_t *pubkey
340340
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
341341

342-
/** Compute an EC Diffie-Hellman secret in constant time
343-
* Returns: 1: exponentiation was successful
344-
* 0: scalar was invalid (zero or overflow)
345-
* In: ctx: pointer to a context object (cannot be NULL)
346-
* point: pointer to a public point
347-
* scalar: a 32-byte scalar with which to multiply the point
348-
* Out: result: a 32-byte array which will be populated by an ECDH
349-
* secret computed from the point and scalar
350-
*/
351-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
352-
const secp256k1_context_t* ctx,
353-
unsigned char *result,
354-
const secp256k1_pubkey_t *point,
355-
const unsigned char *scalar
356-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
357-
358342
/** Verify an ECDSA secret key.
359343
* Returns: 1: secret key is valid
360344
* 0: secret key is invalid

include/secp256k1_ecdh.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef _SECP256K1_ECDH_
2+
# define _SECP256K1_ECDH_
3+
4+
# include "secp256k1.h"
5+
6+
# ifdef __cplusplus
7+
extern "C" {
8+
# endif
9+
10+
/** Compute an EC Diffie-Hellman secret in constant time
11+
* Returns: 1: exponentiation was successful
12+
* 0: scalar was invalid (zero or overflow)
13+
* In: ctx: pointer to a context object (cannot be NULL)
14+
* point: pointer to a public point
15+
* scalar: a 32-byte scalar with which to multiply the point
16+
* Out: result: a 32-byte array which will be populated by an ECDH
17+
* secret computed from the point and scalar
18+
*/
19+
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
20+
const secp256k1_context_t* ctx,
21+
unsigned char *result,
22+
const secp256k1_pubkey_t *point,
23+
const unsigned char *scalar
24+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
25+
26+
# ifdef __cplusplus
27+
}
28+
# endif
29+
30+
#endif

src/bench_ecdh.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <string.h>
88

99
#include "include/secp256k1.h"
10+
#include "include/secp256k1_ecdh.h"
1011
#include "util.h"
1112
#include "bench.h"
1213

src/bench_internal.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
#include "field_impl.h"
1414
#include "group_impl.h"
1515
#include "scalar_impl.h"
16-
#include "ecdh_impl.h"
1716
#include "ecmult_impl.h"
1817
#include "bench.h"
18+
#ifdef ENABLE_MODULE_ECDH
19+
# include "modules/ecdh/ecdh_impl.h"
20+
#endif
1921

2022
typedef struct {
2123
secp256k1_scalar_t scalar_x, scalar_y;
@@ -236,6 +238,7 @@ void bench_ecmult_wnaf(void* arg) {
236238
}
237239
}
238240

241+
#ifdef ENABLE_MODULE_ECDH
239242
void bench_ecdh_wnaf(void* arg) {
240243
int i;
241244
bench_inv_t *data = (bench_inv_t*)arg;
@@ -245,7 +248,7 @@ void bench_ecdh_wnaf(void* arg) {
245248
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
246249
}
247250
}
248-
251+
#endif
249252

250253
void bench_sha256(void* arg) {
251254
int i;
@@ -321,7 +324,9 @@ int main(int argc, char **argv) {
321324
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);
322325
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);
323326

327+
#ifdef ENABLE_MODULE_ECDH
324328
if (have_flag(argc, argv, "ecdh") || have_flag(argc, argv, "wnaf")) run_benchmark("ecdh_wnaf", bench_ecdh_wnaf, bench_setup, NULL, &data, 10, 20000);
329+
#endif
325330
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000);
326331

327332
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000);

src/modules/ecdh/Makefile.am.include

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
include_HEADERS += include/secp256k1_ecdh.h
2+
noinst_HEADERS += src/modules/ecdh/main_impl.h
3+
noinst_HEADERS += src/modules/ecdh/ecdh.h
4+
noinst_HEADERS += src/modules/ecdh/ecdh_impl.h
5+
noinst_HEADERS += src/modules/ecdh/tests_impl.h
6+
if USE_BENCHMARK
7+
noinst_PROGRAMS += bench_ecdh
8+
bench_ecdh_SOURCES = src/bench_ecdh.c
9+
bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS)
10+
bench_ecdh_LDFLAGS = -static
11+
endif

src/ecdh.h renamed to src/modules/ecdh/ecdh.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/**********************************************************************
2-
* Copyright (c) 2015 Pieter Wuille, Andrew Poelstra *
2+
* Copyright (c) 2015 Andrew Poelstra *
33
* Distributed under the MIT software license, see the accompanying *
44
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
55
**********************************************************************/
66

7-
#ifndef _SECP256K1_ECDH_
8-
#define _SECP256K1_ECDH_
7+
#ifndef _SECP256K1_MODULE_ECDH_
8+
#define _SECP256K1_MODULE_ECDH_
99

1010
#include "scalar.h"
1111
#include "group.h"

src/ecdh_impl.h renamed to src/modules/ecdh/ecdh_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
55
**********************************************************************/
66

7-
#ifndef _SECP256K1_ECDH_IMPL_
8-
#define _SECP256K1_ECDH_IMPL_
7+
#ifndef _SECP256K1_MODULE_ECDH_IMPL_
8+
#define _SECP256K1_MODULE_ECDH_IMPL_
99

1010
#include "scalar.h"
1111
#include "group.h"

src/modules/ecdh/main_impl.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**********************************************************************
2+
* Copyright (c) 2015 Andrew Poelstra *
3+
* Distributed under the MIT software license, see the accompanying *
4+
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5+
**********************************************************************/
6+
7+
#ifndef _SECP256K1_MODULE_ECDH_MAIN_
8+
#define _SECP256K1_MODULE_ECDH_MAIN_
9+
10+
#include "modules/ecdh/ecdh_impl.h"
11+
12+
int secp256k1_ecdh(const secp256k1_context_t* ctx, unsigned char *result, const secp256k1_pubkey_t *point, const unsigned char *scalar) {
13+
int ret = 0;
14+
int overflow = 0;
15+
secp256k1_gej_t res;
16+
secp256k1_ge_t pt;
17+
secp256k1_scalar_t s;
18+
ARG_CHECK(result != NULL);
19+
ARG_CHECK(point != NULL);
20+
ARG_CHECK(scalar != NULL);
21+
(void)ctx;
22+
23+
secp256k1_pubkey_load(ctx, &pt, point);
24+
secp256k1_scalar_set_b32(&s, scalar, &overflow);
25+
if (overflow || secp256k1_scalar_is_zero(&s)) {
26+
ret = 0;
27+
} else {
28+
unsigned char x[32];
29+
unsigned char y[1];
30+
secp256k1_sha256_t sha;
31+
32+
secp256k1_point_multiply(&res, &pt, &s);
33+
secp256k1_ge_set_gej(&pt, &res);
34+
/* Compute a hash of the point in compressed form
35+
* Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not
36+
* expect its output to be secret and has a timing sidechannel. */
37+
secp256k1_fe_normalize(&pt.x);
38+
secp256k1_fe_normalize(&pt.y);
39+
secp256k1_fe_get_b32(x, &pt.x);
40+
y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y);
41+
42+
secp256k1_sha256_initialize(&sha);
43+
secp256k1_sha256_write(&sha, y, sizeof(y));
44+
secp256k1_sha256_write(&sha, x, sizeof(x));
45+
secp256k1_sha256_finalize(&sha, result);
46+
ret = 1;
47+
}
48+
49+
secp256k1_scalar_clear(&s);
50+
return ret;
51+
}
52+
53+
#endif

src/secp256k1.c

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "field_impl.h"
1414
#include "scalar_impl.h"
1515
#include "group_impl.h"
16-
#include "ecdh_impl.h"
1716
#include "ecmult_impl.h"
1817
#include "ecmult_gen_impl.h"
1918
#include "ecdsa_impl.h"
@@ -362,47 +361,6 @@ int secp256k1_ecdsa_recover(const secp256k1_context_t* ctx, const unsigned char
362361
}
363362
}
364363

365-
int secp256k1_ecdh(const secp256k1_context_t* ctx, unsigned char *result, const secp256k1_pubkey_t *point, const unsigned char *scalar) {
366-
int ret = 0;
367-
int overflow = 0;
368-
secp256k1_gej_t res;
369-
secp256k1_ge_t pt;
370-
secp256k1_scalar_t s;
371-
ARG_CHECK(result != NULL);
372-
ARG_CHECK(point != NULL);
373-
ARG_CHECK(scalar != NULL);
374-
(void)ctx;
375-
376-
secp256k1_pubkey_load(ctx, &pt, point);
377-
secp256k1_scalar_set_b32(&s, scalar, &overflow);
378-
if (overflow || secp256k1_scalar_is_zero(&s)) {
379-
ret = 0;
380-
} else {
381-
unsigned char x[32];
382-
unsigned char y[1];
383-
secp256k1_sha256_t sha;
384-
385-
secp256k1_point_multiply(&res, &pt, &s);
386-
secp256k1_ge_set_gej(&pt, &res);
387-
/* Compute a hash of the point in compressed form
388-
* Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not
389-
* expect its output to be secret and has a timing sidechannel. */
390-
secp256k1_fe_normalize(&pt.x);
391-
secp256k1_fe_normalize(&pt.y);
392-
secp256k1_fe_get_b32(x, &pt.x);
393-
y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y);
394-
395-
secp256k1_sha256_initialize(&sha);
396-
secp256k1_sha256_write(&sha, y, sizeof(y));
397-
secp256k1_sha256_write(&sha, x, sizeof(x));
398-
secp256k1_sha256_finalize(&sha, result);
399-
ret = 1;
400-
}
401-
402-
secp256k1_scalar_clear(&s);
403-
return ret;
404-
}
405-
406364
int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned char *seckey) {
407365
secp256k1_scalar_t sec;
408366
int ret;
@@ -567,3 +525,8 @@ int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *s
567525
secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32);
568526
return 1;
569527
}
528+
529+
#ifdef ENABLE_MODULE_ECDH
530+
# include "modules/ecdh/main_impl.h"
531+
#endif
532+

0 commit comments

Comments
 (0)