Skip to content

Commit e0e7987

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

File tree

13 files changed

+292
-227
lines changed

13 files changed

+292
-227
lines changed

Makefile.am

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ 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
2119
noinst_HEADERS += src/eckey_impl.h
2220
noinst_HEADERS += src/ecmult.h
2321
noinst_HEADERS += src/ecmult_impl.h
22+
noinst_HEADERS += src/ecmult_const.h
23+
noinst_HEADERS += src/ecmult_const_impl.h
2424
noinst_HEADERS += src/ecmult_gen.h
2525
noinst_HEADERS += src/ecmult_gen_impl.h
2626
noinst_HEADERS += src/num.h
@@ -51,7 +51,7 @@ libsecp256k1_la_LIBADD = $(SECP_LIBS)
5151

5252
noinst_PROGRAMS =
5353
if USE_BENCHMARK
54-
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal bench_ecdh
54+
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal
5555
bench_verify_SOURCES = src/bench_verify.c
5656
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS)
5757
bench_verify_LDFLAGS = -static
@@ -65,10 +65,6 @@ bench_internal_SOURCES = src/bench_internal.c
6565
bench_internal_LDADD = $(SECP_LIBS)
6666
bench_internal_LDFLAGS = -static
6767
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)
7268
endif
7369

7470
if USE_TESTS
@@ -101,3 +97,7 @@ CLEANFILES = gen_context src/ecmult_static_context.h
10197
endif
10298

10399
EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h
100+
101+
if ENABLE_MODULE_ECDH
102+
include src/modules/ecdh/Makefile.am.include
103+
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: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "field_impl.h"
1414
#include "group_impl.h"
1515
#include "scalar_impl.h"
16-
#include "ecdh_impl.h"
16+
#include "ecmult_const_impl.h"
1717
#include "ecmult_impl.h"
1818
#include "bench.h"
1919

@@ -241,12 +241,11 @@ void bench_ecdh_wnaf(void* arg) {
241241
bench_inv_t *data = (bench_inv_t*)arg;
242242

243243
for (i = 0; i < 20000; i++) {
244-
secp256k1_ecdh_wnaf(data->wnaf, data->scalar_x, WINDOW_A);
244+
secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A);
245245
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
246246
}
247247
}
248248

249-
250249
void bench_sha256(void* arg) {
251250
int i;
252251
bench_inv_t *data = (bench_inv_t*)arg;
@@ -321,7 +320,7 @@ int main(int argc, char **argv) {
321320
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);
322321
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);
323322

324-
if (have_flag(argc, argv, "ecdh") || have_flag(argc, argv, "wnaf")) run_benchmark("ecdh_wnaf", bench_ecdh_wnaf, bench_setup, NULL, &data, 10, 20000);
323+
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_const_wnaf", bench_ecdh_wnaf, bench_setup, NULL, &data, 10, 20000);
325324
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000);
326325

327326
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000);
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
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_ECMULT_CONST_
8+
#define _SECP256K1_ECMULT_CONST_
99

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

13-
static void secp256k1_point_multiply(secp256k1_gej_t *r, const secp256k1_ge_t *a, const secp256k1_scalar_t *q);
13+
static void secp256k1_ecmult_const(secp256k1_gej_t *r, const secp256k1_ge_t *a, const secp256k1_scalar_t *q);
1414

1515
#endif

src/ecdh_impl.h renamed to src/ecmult_const_impl.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
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_ECMULT_CONST_IMPL_
8+
#define _SECP256K1_ECMULT_CONST_IMPL_
99

1010
#include "scalar.h"
1111
#include "group.h"
12-
#include "ecdh.h"
12+
#include "ecmult_const.h"
1313
#include "ecmult_impl.h"
1414

1515
#ifdef USE_ENDOMORPHISM
@@ -53,7 +53,7 @@
5353
*
5454
* Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335
5555
*/
56-
static int secp256k1_ecdh_wnaf(int *wnaf, secp256k1_scalar_t s, int w) {
56+
static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar_t s, int w) {
5757
int global_sign = 1;
5858
int skew = 0;
5959
int word = 0;
@@ -119,7 +119,7 @@ static int secp256k1_ecdh_wnaf(int *wnaf, secp256k1_scalar_t s, int w) {
119119
}
120120

121121

122-
static void secp256k1_point_multiply(secp256k1_gej_t *r, const secp256k1_ge_t *a, const secp256k1_scalar_t *scalar) {
122+
static void secp256k1_ecmult_const(secp256k1_gej_t *r, const secp256k1_ge_t *a, const secp256k1_scalar_t *scalar) {
123123
secp256k1_ge_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
124124
secp256k1_ge_t tmpa;
125125
secp256k1_fe_t Z;
@@ -144,16 +144,16 @@ static void secp256k1_point_multiply(secp256k1_gej_t *r, const secp256k1_ge_t *a
144144
secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc);
145145
/* no need for zero correction when using endomorphism since even
146146
* numbers have one added to them anyway */
147-
skew_1 = secp256k1_ecdh_wnaf(wnaf_1, q_1, WINDOW_A - 1);
148-
skew_lam = secp256k1_ecdh_wnaf(wnaf_lam, q_lam, WINDOW_A - 1);
147+
skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1);
148+
skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1);
149149
#else
150150
int is_zero = secp256k1_scalar_is_zero(scalar);
151151
/* the wNAF ladder cannot handle zero, so bump this to one .. we will
152152
* correct the result after the fact */
153153
sc.d[0] += is_zero;
154154
VERIFY_CHECK(!secp256k1_scalar_is_zero(&sc));
155155

156-
secp256k1_ecdh_wnaf(wnaf, sc, WINDOW_A - 1);
156+
secp256k1_wnaf_const(wnaf, sc, WINDOW_A - 1);
157157
#endif
158158

159159
/* Calculate odd multiples of a.

src/modules/ecdh/Makefile.am.include

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

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 "ecmult_const_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_ecmult_const(&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

0 commit comments

Comments
 (0)