Add ECDH module which works by hashing the output of ecmult_const
This commit is contained in:
parent
4401500060
commit
0739bbb6f0
|
@ -8,12 +8,14 @@ compiler:
|
|||
- gcc
|
||||
env:
|
||||
global:
|
||||
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=no ASM=no BUILD=check EXTRAFLAGS= HOST=
|
||||
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=no ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no
|
||||
matrix:
|
||||
- SCALAR=32bit
|
||||
- SCALAR=32bit FIELD=32bit ECDH=yes
|
||||
- SCALAR=64bit
|
||||
- FIELD=64bit
|
||||
- FIELD=64bit ENDOMORPHISM=yes
|
||||
- FIELD=64bit ENDOMORPHISM=yes ECDH=yes
|
||||
- FIELD=64bit ASM=x86_64
|
||||
- FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
|
||||
- FIELD=32bit
|
||||
|
@ -56,5 +58,5 @@ before_script: ./autogen.sh
|
|||
script:
|
||||
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
|
||||
- if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
|
||||
- ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
|
||||
- ./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
|
||||
os: linux
|
||||
|
|
|
@ -97,3 +97,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
configure.ac
11
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"
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
include_HEADERS += include/secp256k1_ecdh.h
|
||||
noinst_HEADERS += src/modules/ecdh/main_impl.h
|
||||
noinst_HEADERS += src/modules/ecdh/tests_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 "ecmult_const_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_ecmult_const(&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
|
|
@ -0,0 +1,75 @@
|
|||
/**********************************************************************
|
||||
* 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_TESTS_
|
||||
#define _SECP256K1_MODULE_ECDH_TESTS_
|
||||
|
||||
void test_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 test_bad_scalar(void) {
|
||||
unsigned char s_zero[32] = { 0 };
|
||||
unsigned char s_overflow[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
|
||||
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41
|
||||
};
|
||||
unsigned char s_rand[32] = { 0 };
|
||||
unsigned char output[32];
|
||||
secp256k1_scalar_t rand;
|
||||
secp256k1_pubkey_t point;
|
||||
|
||||
/* Create random point */
|
||||
random_scalar_order(&rand);
|
||||
secp256k1_scalar_get_b32(s_rand, &rand);
|
||||
CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1);
|
||||
|
||||
/* Try to multiply it by bad values */
|
||||
CHECK(secp256k1_ecdh(ctx, output, &point, s_zero) == 0);
|
||||
CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 0);
|
||||
/* ...and a good one */
|
||||
s_overflow[31] -= 1;
|
||||
CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 1);
|
||||
}
|
||||
|
||||
void run_ecdh_tests(void) {
|
||||
test_ecdh_generator_basepoint();
|
||||
test_bad_scalar();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -526,3 +526,7 @@ 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
|
||||
|
|
|
@ -2356,6 +2356,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};
|
||||
|
@ -2444,6 +2448,11 @@ int main(int argc, char **argv) {
|
|||
run_endomorphism_tests();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MODULE_ECDH
|
||||
/* ecdh tests */
|
||||
run_ecdh_tests();
|
||||
#endif
|
||||
|
||||
/* ecdsa tests */
|
||||
run_random_pubkeys();
|
||||
run_ecdsa_sign_verify();
|
||||
|
|
Loading…
Reference in New Issue