Skip to content

Commit ecae2ac

Browse files
committed
Squashed 'src/secp256k1/' changes from b0210a9..bccaf86
bccaf86 Merge pull request bitcoin-core#150 2a53a47 Merge pull request bitcoin-core#151 5f5a31f Merge pull request bitcoin-core#149 3907277 Merge pull request bitcoin-core#142 a3e0611 Enable tests in x86 travis builds 45da235 x86 builder 8bb0e93 Merge pull request bitcoin-core#155 971fe81 build: fix openssl detection for cross builds f22d73e Explicitly access %0..%2 as 64-bit so we use the right registers for x32 ABI e66d4d6 Avoid the stack in assembly and use explicit registers cf7b2b4 Fix ECDSA message hashes to 32 bytes 056ad31 Really compile with -O3 by default 74ad63a Merge pull request bitcoin-core#146 9000458 Merge pull request bitcoin-core#145 1f46b00 build: fix __builtin_expect detection for clang aaba2e0 Merge pull request bitcoin-core#136 8a0775c Merge pull request bitcoin-core#144 ee1eaa7 Merge pull request bitcoin-core#141 c88e2b8 Compile with -O3 by default 6558a26 Make the benchmarks print out stats 000bdf6 Rename bench_verify to bench_recovery 7c6fed2 Add a few more additional tests. 992e03b travis: add clang to the test matrix b43b79a Merge pull request bitcoin-core#143 e06a924 Include time.h header for time(). 8d11164 Add some additional tests. 3545627 Merge pull request bitcoin-core#118 6a9901e Merge pull request bitcoin-core#137 376b28b Merge pull request bitcoin-core#128 1728806 Merge pull request bitcoin-core#138 a5759c5 Check return value of malloc 39bd94d Variable time normalize ad86bdf Merge pull request bitcoin-core#140 54b768c Another redundant secp256k1_fe_normalize 69dcaab Merge pull request bitcoin-core#139 1c29f2e Remove redundant secp256k1_fe_normalize from secp256k1_gej_add_ge_var. 2b9388b Remove unused secp256k1_fe_inv_all f461b76 Allocate precomputation arrays on the heap b2c9681 Make {mul,sqr}_inner use the same argument order as {mul,sqr} 6793505 Convert YASM code into inline assembly f048615 Rewrite field assembly to match the C version 3ce74b1 Tweak precomputed table size for G git-subtree-dir: src/secp256k1 git-subtree-split: bccaf86caa9c44166e5a66600b742c516e03c3f0
1 parent 87bddb7 commit ecae2ac

29 files changed

+1198
-845
lines changed

.travis.yml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
language: cpp
2-
compiler: gcc
1+
language: c
2+
compiler:
3+
- clang
4+
- gcc
35
install:
46
- sudo apt-get install -qq libssl-dev
5-
- if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; then sudo apt-get install -qq libgmp-dev; fi
6-
- if [ "$FIELD" = "64bit_asm" ]; then sudo apt-get install -qq yasm; fi
7+
- if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi
8+
- if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi
79
env:
810
global:
9-
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no BUILD=check EXTRAFLAGS=
11+
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES=
1012
matrix:
1113
- SCALAR=32bit
1214
- SCALAR=64bit
@@ -22,6 +24,11 @@ env:
2224
- BIGNUM=none ENDOMORPHISM=yes
2325
- BUILD=distcheck
2426
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
27+
- HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib"
28+
- HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" ENDOMORPHISM=yes
2529
before_script: ./autogen.sh
26-
script: ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS && make -j2 $BUILD
30+
script:
31+
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
32+
- if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
33+
- ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
2734
os: linux

Makefile.am

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
ACLOCAL_AMFLAGS = -I build-aux/m4
22

33
lib_LTLIBRARIES = libsecp256k1.la
4-
if USE_ASM
5-
COMMON_LIB = libsecp256k1_common.la
6-
else
7-
COMMON_LIB =
8-
endif
9-
noinst_LTLIBRARIES = $(COMMON_LIB)
104
include_HEADERS = include/secp256k1.h
115
noinst_HEADERS =
126
noinst_HEADERS += src/scalar.h
@@ -43,30 +37,30 @@ noinst_HEADERS += src/field_gmp.h
4337
noinst_HEADERS += src/field_gmp_impl.h
4438
noinst_HEADERS += src/field.h
4539
noinst_HEADERS += src/field_impl.h
40+
noinst_HEADERS += src/bench.h
4641

4742
pkgconfigdir = $(libdir)/pkgconfig
4843
pkgconfig_DATA = libsecp256k1.pc
4944

50-
if USE_ASM
51-
libsecp256k1_common_la_SOURCES = src/field_5x52_asm.asm
52-
endif
53-
5445
libsecp256k1_la_SOURCES = src/secp256k1.c
5546
libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include $(SECP_INCLUDES)
56-
libsecp256k1_la_LIBADD = $(COMMON_LIB) $(SECP_LIBS)
47+
libsecp256k1_la_LIBADD = $(SECP_LIBS)
5748

5849

5950
noinst_PROGRAMS =
6051
if USE_BENCHMARK
61-
noinst_PROGRAMS += bench_verify bench_sign bench_inv
52+
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_inv
6253
bench_verify_SOURCES = src/bench_verify.c
6354
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS)
6455
bench_verify_LDFLAGS = -static
56+
bench_recover_SOURCES = src/bench_recover.c
57+
bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS)
58+
bench_recover_LDFLAGS = -static
6559
bench_sign_SOURCES = src/bench_sign.c
6660
bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS)
6761
bench_sign_LDFLAGS = -static
6862
bench_inv_SOURCES = src/bench_inv.c
69-
bench_inv_LDADD = $(COMMON_LIB) $(SECP_LIBS)
63+
bench_inv_LDADD = $(SECP_LIBS)
7064
bench_inv_LDFLAGS = -static
7165
bench_inv_CPPFLAGS = $(SECP_INCLUDES)
7266
endif
@@ -75,15 +69,9 @@ if USE_TESTS
7569
noinst_PROGRAMS += tests
7670
tests_SOURCES = src/tests.c
7771
tests_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
78-
tests_LDADD = $(COMMON_LIB) $(SECP_LIBS) $(SECP_TEST_LIBS)
72+
tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS)
7973
tests_LDFLAGS = -static
8074
TESTS = tests
8175
endif
8276

83-
EXTRA_DIST = autogen.sh nasm_lt.sh
84-
85-
#x86_64 only
86-
if USE_ASM
87-
.asm.lo:
88-
$(LIBTOOL) --mode=compile --tag YASM $(srcdir)/nasm_lt.sh $(YASM) -f $(YASM_BINFMT) $(YAFLAGS) -I$(srcdir) -I. $< -o $@
89-
endif
77+
EXTRA_DIST = autogen.sh

build-aux/m4/bitcoin_secp.m4

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,16 @@ fi
1111

1212
dnl
1313
AC_DEFUN([SECP_64BIT_ASM_CHECK],[
14-
if test x"$host_cpu" == x"x86_64"; then
15-
AC_CHECK_PROG(YASM, yasm, yasm)
16-
else
17-
if test x"$set_field" = x"64bit_asm"; then
18-
AC_MSG_ERROR([$set_field field support explicitly requested but is not compatible with this host])
19-
fi
20-
fi
21-
if test x$YASM = x; then
22-
if test x"$set_field" = x"64bit_asm"; then
23-
AC_MSG_ERROR([$set_field field support explicitly requested but yasm was not found])
24-
fi
25-
has_64bit_asm=no
26-
else
27-
case x"$host_os" in
28-
xdarwin*)
29-
YASM_BINFMT=macho64
30-
;;
31-
x*-gnux32)
32-
YASM_BINFMT=elfx32
33-
;;
34-
*)
35-
YASM_BINFMT=elf64
36-
;;
37-
esac
38-
if $YASM -f help | grep -q $YASM_BINFMT; then
39-
has_64bit_asm=yes
40-
else
41-
if test x"$set_field" = x"64bit_asm"; then
42-
AC_MSG_ERROR([$set_field field support explicitly requested but yasm doesn't support $YASM_BINFMT format])
43-
fi
44-
AC_MSG_WARN([yasm too old for $YASM_BINFMT format])
45-
has_64bit_asm=no
14+
AC_MSG_CHECKING(for x86_64 assembly availability)
15+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
16+
#include <stdint.h>]],[[
17+
uint64_t a = 11, tmp;
18+
__asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
19+
]])],[has_64bit_asm=yes],[has_64bit_asm=no])
20+
AC_MSG_RESULT([$has_64bit_asm])
21+
if test x"$set_field" == x"64bit_asm"; then
22+
if test x"$has_64bit_asm" == x"no"; then
23+
AC_MSG_ERROR([$set_field field support explicitly requested but no x86_64 assembly available])
4624
fi
4725
fi
4826
])
@@ -52,8 +30,13 @@ AC_DEFUN([SECP_OPENSSL_CHECK],[
5230
if test x"$use_pkgconfig" = x"yes"; then
5331
: #NOP
5432
m4_ifdef([PKG_CHECK_MODULES],[
55-
PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no])
56-
: #NOP
33+
PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no])
34+
if test x"$has_libcrypto" = x"yes"; then
35+
TEMP_LIBS="$LIBS"
36+
LIBS="$LIBS $CRYPTO_LIBS"
37+
AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no])
38+
LIBS="$TEMP_LIBS"
39+
fi
5740
])
5841
else
5942
AC_CHECK_HEADER(openssl/crypto.h,[AC_CHECK_LIB(crypto, main,[has_libcrypto=yes; CRYPTO_LIBS=-lcrypto; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])]

configure.ac

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ AC_PATH_TOOL(AR, ar)
1818
AC_PATH_TOOL(RANLIB, ranlib)
1919
AC_PATH_TOOL(STRIP, strip)
2020

21+
if test "x$CFLAGS" = "x"; then
22+
CFLAGS="-O3 -g"
23+
fi
24+
2125
AC_PROG_CC_C99
2226
if test x"$ac_cv_prog_cc_c99" == x"no"; then
2327
AC_MSG_ERROR([c99 compiler support required])
@@ -103,7 +107,11 @@ AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto],
103107

104108
AC_CHECK_TYPES([__int128])
105109

106-
AC_CHECK_DECL(__builtin_expect,AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]),,)
110+
AC_MSG_CHECKING([for __builtin_expect])
111+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])],
112+
[ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ],
113+
[ AC_MSG_RESULT([no])
114+
])
107115

108116
if test x"$req_field" = x"auto"; then
109117
SECP_64BIT_ASM_CHECK
@@ -283,7 +291,6 @@ AC_SUBST(SECP_INCLUDES)
283291
AC_SUBST(SECP_LIBS)
284292
AC_SUBST(SECP_TEST_LIBS)
285293
AC_SUBST(SECP_TEST_INCLUDES)
286-
AC_SUBST(YASM_BINFMT)
287294
AM_CONDITIONAL([USE_ASM], [test x"$set_field" == x"64bit_asm"])
288295
AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
289296
AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" != x"no"])

include/secp256k1.h

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,25 @@ void secp256k1_stop(void);
6262
* 0: incorrect signature
6363
* -1: invalid public key
6464
* -2: invalid signature
65-
* In: msg: the message being verified (cannot be NULL)
66-
* msglen: the length of the message (at most 32)
65+
* In: msg32: the 32-byte message hash being verified (cannot be NULL)
6766
* sig: the signature being verified (cannot be NULL)
6867
* siglen: the length of the signature
6968
* pubkey: the public key to verify with (cannot be NULL)
7069
* pubkeylen: the length of pubkey
7170
* Requires starting using SECP256K1_START_VERIFY.
7271
*/
7372
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
74-
const unsigned char *msg,
75-
int msglen,
73+
const unsigned char *msg32,
7674
const unsigned char *sig,
7775
int siglen,
7876
const unsigned char *pubkey,
7977
int pubkeylen
80-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
78+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
8179

8280
/** Create an ECDSA signature.
8381
* Returns: 1: signature created
8482
* 0: nonce invalid, try another one
85-
* In: msg: the message being signed (cannot be NULL)
86-
* msglen: the length of the message being signed (at most 32)
83+
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
8784
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
8885
* nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
8986
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
@@ -92,39 +89,35 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
9289
* Requires starting using SECP256K1_START_SIGN.
9390
*/
9491
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign(
95-
const unsigned char *msg,
96-
int msglen,
92+
const unsigned char *msg32,
9793
unsigned char *sig,
9894
int *siglen,
9995
const unsigned char *seckey,
10096
const unsigned char *nonce
101-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
97+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
10298

10399
/** Create a compact ECDSA signature (64 byte + recovery id).
104100
* Returns: 1: signature created
105101
* 0: nonce invalid, try another one
106-
* In: msg: the message being signed (cannot be NULL)
107-
* msglen: the length of the message being signed (at most 32)
102+
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
108103
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
109104
* nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
110105
* Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL)
111106
* recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
112107
* Requires starting using SECP256K1_START_SIGN.
113108
*/
114109
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact(
115-
const unsigned char *msg,
116-
int msglen,
110+
const unsigned char *msg32,
117111
unsigned char *sig64,
118112
const unsigned char *seckey,
119113
const unsigned char *nonce,
120114
int *recid
121-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
115+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
122116

123117
/** Recover an ECDSA public key from a compact signature.
124118
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
125119
* 0: otherwise.
126-
* In: msg: the message assumed to be signed (cannot be NULL)
127-
* msglen: the length of the message (at most 32)
120+
* In: msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
128121
* sig64: signature as 64 byte array (cannot be NULL)
129122
* compressed: whether to recover a compressed or uncompressed pubkey
130123
* recid: the recovery id (0-3, as returned by ecdsa_sign_compact)
@@ -133,14 +126,13 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact(
133126
* Requires starting using SECP256K1_START_VERIFY.
134127
*/
135128
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(
136-
const unsigned char *msg,
137-
int msglen,
129+
const unsigned char *msg32,
138130
const unsigned char *sig64,
139131
unsigned char *pubkey,
140132
int *pubkeylen,
141133
int compressed,
142134
int recid
143-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
135+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
144136

145137
/** Verify an ECDSA secret key.
146138
* Returns: 1: secret key is valid

nasm_lt.sh

Lines changed: 0 additions & 57 deletions
This file was deleted.

src/bench.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**********************************************************************
2+
* Copyright (c) 2014 Pieter Wuille *
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_BENCH_H_
8+
#define _SECP256K1_BENCH_H_
9+
10+
#include <stdio.h>
11+
#include <math.h>
12+
#include "sys/time.h"
13+
14+
static double gettimedouble(void) {
15+
struct timeval tv;
16+
gettimeofday(&tv, NULL);
17+
return tv.tv_usec * 0.000001 + tv.tv_sec;
18+
}
19+
20+
void run_benchmark(void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
21+
double min = HUGE_VAL;
22+
double sum = 0.0;
23+
double max = 0.0;
24+
for (int i = 0; i < count; i++) {
25+
if (setup) setup(data);
26+
double begin = gettimedouble();
27+
benchmark(data);
28+
double total = gettimedouble() - begin;
29+
if (teardown) teardown(data);
30+
if (total < min) min = total;
31+
if (total > max) max = total;
32+
sum += total;
33+
}
34+
printf("min %.3fus / avg %.3fus / max %.3fus\n", min * 1000000.0 / iter, (sum / count) * 1000000.0 / iter, max * 1000000.0 / iter);
35+
}
36+
37+
#endif

0 commit comments

Comments
 (0)