Skip to content

Commit d84a378

Browse files
committed
Merge pull request #252
72ae443 Improve perf. of cmov-based table lookup (Peter Dettman) 92e53fc Implement endomorphism optimization for secp256k1_ecmult_const (Andrew Poelstra) ed35d43 Make `secp256k1_scalar_add_bit` conditional; make `secp256k1_scalar_split_lambda_var` constant time (Andrew Poelstra) 91c0ce9 Add benchmarks for ECDH and const-time multiplication (Andrew Poelstra) 0739bbb Add ECDH module which works by hashing the output of ecmult_const (Andrew Poelstra) 4401500 Add constant-time multiply `secp256k1_ecmult_const` for ECDH (Andrew Poelstra) baa75da tests: add a couple tests (Andrew Poelstra)
2 parents ae4f0c6 + 72ae443 commit d84a378

22 files changed

+886
-19
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
bench_inv
2+
bench_ecdh
23
bench_sign
34
bench_verify
45
bench_recover

.travis.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ compiler:
88
- gcc
99
env:
1010
global:
11-
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=no ASM=no BUILD=check EXTRAFLAGS= HOST=
11+
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=no ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no
1212
matrix:
1313
- SCALAR=32bit
14+
- SCALAR=32bit FIELD=32bit ECDH=yes
1415
- SCALAR=64bit
1516
- FIELD=64bit
1617
- FIELD=64bit ENDOMORPHISM=yes
18+
- FIELD=64bit ENDOMORPHISM=yes ECDH=yes
1719
- FIELD=64bit ASM=x86_64
1820
- FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
1921
- FIELD=32bit
@@ -56,5 +58,5 @@ before_script: ./autogen.sh
5658
script:
5759
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
5860
- if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
59-
- ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
61+
- ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
6062
os: linux

Makefile.am

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ noinst_HEADERS += src/eckey.h
1919
noinst_HEADERS += src/eckey_impl.h
2020
noinst_HEADERS += src/ecmult.h
2121
noinst_HEADERS += src/ecmult_impl.h
22+
noinst_HEADERS += src/ecmult_const.h
23+
noinst_HEADERS += src/ecmult_const_impl.h
2224
noinst_HEADERS += src/ecmult_gen.h
2325
noinst_HEADERS += src/ecmult_gen_impl.h
2426
noinst_HEADERS += src/num.h
@@ -95,3 +97,7 @@ CLEANFILES = gen_context src/ecmult_static_context.h
9597
endif
9698

9799
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_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: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**********************************************************************
2+
* Copyright (c) 2015 Pieter Wuille, 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+
#include <string.h>
8+
9+
#include "include/secp256k1.h"
10+
#include "include/secp256k1_ecdh.h"
11+
#include "util.h"
12+
#include "bench.h"
13+
14+
typedef struct {
15+
secp256k1_context_t *ctx;
16+
secp256k1_pubkey_t point;
17+
unsigned char scalar[32];
18+
} bench_ecdh_t;
19+
20+
static void bench_ecdh_setup(void* arg) {
21+
int i;
22+
bench_ecdh_t *data = (bench_ecdh_t*)arg;
23+
const unsigned char point[] = {
24+
0x03,
25+
0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06,
26+
0xc2, 0x39, 0x5f, 0x94, 0x34, 0x87, 0x45, 0xfd,
27+
0x75, 0x7c, 0xe3, 0x0e, 0x4e, 0x8c, 0x90, 0xfb,
28+
0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f
29+
};
30+
31+
data->ctx = secp256k1_context_create(0);
32+
for (i = 0; i < 32; i++) data->scalar[i] = i + 1;
33+
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1);
34+
}
35+
36+
static void bench_ecdh(void* arg) {
37+
int i;
38+
unsigned char res[32];
39+
bench_ecdh_t *data = (bench_ecdh_t*)arg;
40+
41+
for (i = 0; i < 20000; i++) {
42+
CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar) == 1);
43+
}
44+
}
45+
46+
int main(void) {
47+
bench_ecdh_t data;
48+
49+
run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000);
50+
return 0;
51+
}

src/bench_internal.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "field_impl.h"
1414
#include "group_impl.h"
1515
#include "scalar_impl.h"
16+
#include "ecmult_const_impl.h"
1617
#include "ecmult_impl.h"
1718
#include "bench.h"
1819

@@ -97,7 +98,7 @@ void bench_scalar_split(void* arg) {
9798

9899
for (i = 0; i < 20000; i++) {
99100
secp256k1_scalar_t l, r;
100-
secp256k1_scalar_split_lambda_var(&l, &r, &data->scalar_x);
101+
secp256k1_scalar_split_lambda(&l, &r, &data->scalar_x);
101102
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
102103
}
103104
}
@@ -235,6 +236,16 @@ void bench_ecmult_wnaf(void* arg) {
235236
}
236237
}
237238

239+
void bench_wnaf_const(void* arg) {
240+
int i;
241+
bench_inv_t *data = (bench_inv_t*)arg;
242+
243+
for (i = 0; i < 20000; i++) {
244+
secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A);
245+
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
246+
}
247+
}
248+
238249

239250
void bench_sha256(void* arg) {
240251
int i;
@@ -310,6 +321,7 @@ int main(int argc, char **argv) {
310321
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);
311322
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);
312323

324+
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000);
313325
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000);
314326

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

src/ecmult_const.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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_ECMULT_CONST_
8+
#define _SECP256K1_ECMULT_CONST_
9+
10+
#include "scalar.h"
11+
#include "group.h"
12+
13+
static void secp256k1_ecmult_const(secp256k1_gej_t *r, const secp256k1_ge_t *a, const secp256k1_scalar_t *q);
14+
15+
#endif

0 commit comments

Comments
 (0)