Squashed 'src/secp256k1/' changes from efad3506a8..1758a92ffd
1758a92ffd Merge #950: ci: Add ppc64le build c58c4ea470 ci: Add ppc64le build 7973576f6e Merge #662: Add ecmult_gen, ecmult_const and ecmult to benchmark 8f879c2887 Fix array size in bench_ecmult 2fe1b50df1 Add ecmult_gen, ecmult_const and ecmult to benchmark 593e6bad9c Clean up ecmult_bench to make space for more benchmarks 50f3367712 Merge #947: ci: Run PRs on merge result even for i686 a35fdd3478 ci: Run PRs on merge result even for i686 3dc8c072b6 Merge #846: ci: Run ASan/LSan and reorganize sanitizer and Valgrind jobs 02dcea1ad9 ci: Make test iterations configurable and tweak for sanitizer builds 489ff5c20a tests: Treat empty SECP2561_TEST_ITERS as if it was unset fcfcb97e74 ci: Simplify to use generic wrapper for QEMU, Valgrind, etc de4157f13a ci: Run ASan/LSan and reorganize sanitizer and Valgrind jobs 399722a63a Merge #941: Clean up git tree 09b3bb8648 Clean up git tree bf0ac46066 Merge #930: Add ARM32/ARM64 CI 202a030f7d Merge #850: add `secp256k1_ec_pubkey_cmp` method 1e78c18d5b Merge bitcoin-core/secp256k1#940: contrib: Explain explicit header guards 69394879b6 Merge #926: secp256k1.h: clarify that by default arguments must be != NULL 6eceec6d56 add `secp256k1_xonly_pubkey_cmp` method 0d9561ae87 add `secp256k1_ec_pubkey_cmp` method 22a9ea154a contrib: Explain explicit header guards 6c52ae8724 Merge #937: Have ge_set_gej_var, gej_double_var and ge_set_all_gej_var initialize all fields of their outputs. 185a6af227 Merge #925: changed include statements without prefix 'include/' 14c9739a1f tests: Improve secp256k1_ge_set_all_gej_var for some infinity inputs 4a19668c37 tests: Test secp256k1_ge_set_all_gej_var for all infinity inputs 3c90bdda95 change local lib headers to be relative for those pointing at "include/" dir 45b6468d7e Have secp256k1_ge_set_all_gej_var initialize all fields. Previous behaviour would not initialize r->y values in the case where infinity is passed in. Furthermore, the previous behaviour wouldn't initialize anything in the case where all inputs were infinity. 31c0f6de41 Have secp256k1_gej_double_var initialize all fields. Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in. dd6c3de322 Have secp256k1_ge_set_gej_var initialize all fields. Previous behaviour would not initialize r->x and r->y values in the case where infinity is passed in. d0bd2693e3 Merge bitcoin-core/secp256k1#936: Fix gen_context/ASM build on ARM 8bbad7a18e Add asm build to ARM32 CI 7d65ed5214 Add ARM32/ARM64 CI c8483520c9 Makefile.am: Don't pass a variable twice 2161f31785 Makefile.am: Honor config when building gen_context 99f47c20ec gen_context: Don't use external ASM because it complicates the build 98e0358d29 Merge #933: Avoids a missing brace warning in schnorrsig/tests_impl.h on old compilers 99e2d5be0d Avoids a missing brace warning in schnorrsig/tests_impl.h on old compilers. 34388af6b6 Merge #922: Add mingw32-w64/wine CI build 7012a188e6 Merge #928: Define SECP256K1_BUILD in secp256k1.c directly. ed5a199bed tests: fopen /dev/urandom in binary mode ae9e648526 Define SECP256K1_BUILD in secp256k1.c directly. 4dc37bf81b Add mingw32-w64/wine CI build 0881633dfd secp256k1.h: clarify that by default arguments must be != NULL git-subtree-dir: src/secp256k1 git-subtree-split: 1758a92ffd896af533b142707e9892ea6e15e5db
This commit is contained in:
parent
678f3c95df
commit
ed3e5b0f2a
163
.cirrus.yml
163
.cirrus.yml
|
@ -5,7 +5,6 @@ env:
|
||||||
ASM: no
|
ASM: no
|
||||||
BUILD: check
|
BUILD: check
|
||||||
WITH_VALGRIND: yes
|
WITH_VALGRIND: yes
|
||||||
RUN_VALGRIND: no
|
|
||||||
EXTRAFLAGS:
|
EXTRAFLAGS:
|
||||||
HOST:
|
HOST:
|
||||||
ECDH: no
|
ECDH: no
|
||||||
|
@ -14,7 +13,8 @@ env:
|
||||||
EXPERIMENTAL: no
|
EXPERIMENTAL: no
|
||||||
CTIMETEST: yes
|
CTIMETEST: yes
|
||||||
BENCH: yes
|
BENCH: yes
|
||||||
ITERS: 2
|
TEST_ITERS:
|
||||||
|
BENCH_ITERS: 2
|
||||||
MAKEFLAGS: -j2
|
MAKEFLAGS: -j2
|
||||||
|
|
||||||
cat_logs_snippet: &CAT_LOGS
|
cat_logs_snippet: &CAT_LOGS
|
||||||
|
@ -63,27 +63,8 @@ task:
|
||||||
- env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETEST: no, BENCH: no}
|
- env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETEST: no, BENCH: no}
|
||||||
- env: {CPPFLAGS: -DDETERMINISTIC}
|
- env: {CPPFLAGS: -DDETERMINISTIC}
|
||||||
- env: {CFLAGS: -O0, CTIMETEST: no}
|
- env: {CFLAGS: -O0, CTIMETEST: no}
|
||||||
- env:
|
|
||||||
CFLAGS: "-fsanitize=undefined -fno-omit-frame-pointer"
|
|
||||||
LDFLAGS: "-fsanitize=undefined -fno-omit-frame-pointer"
|
|
||||||
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
|
|
||||||
ASM: x86_64
|
|
||||||
ECDH: yes
|
|
||||||
RECOVERY: yes
|
|
||||||
EXPERIMENTAL: yes
|
|
||||||
SCHNORRSIG: yes
|
|
||||||
CTIMETEST: no
|
|
||||||
- env: { ECMULTGENPRECISION: 2 }
|
- env: { ECMULTGENPRECISION: 2 }
|
||||||
- env: { ECMULTGENPRECISION: 8 }
|
- env: { ECMULTGENPRECISION: 8 }
|
||||||
- env:
|
|
||||||
RUN_VALGRIND: yes
|
|
||||||
ASM: x86_64
|
|
||||||
ECDH: yes
|
|
||||||
RECOVERY: yes
|
|
||||||
EXPERIMENTAL: yes
|
|
||||||
SCHNORRSIG: yes
|
|
||||||
EXTRAFLAGS: "--disable-openssl-tests"
|
|
||||||
BUILD:
|
|
||||||
matrix:
|
matrix:
|
||||||
- env:
|
- env:
|
||||||
CC: gcc
|
CC: gcc
|
||||||
|
@ -111,6 +92,7 @@ task:
|
||||||
CC: i686-linux-gnu-gcc
|
CC: i686-linux-gnu-gcc
|
||||||
- env:
|
- env:
|
||||||
CC: clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include
|
CC: clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include
|
||||||
|
<< : *MERGE_BASE
|
||||||
test_script:
|
test_script:
|
||||||
- ./ci/cirrus.sh
|
- ./ci/cirrus.sh
|
||||||
<< : *CAT_LOGS
|
<< : *CAT_LOGS
|
||||||
|
@ -181,9 +163,9 @@ task:
|
||||||
cpu: 1
|
cpu: 1
|
||||||
memory: 1G
|
memory: 1G
|
||||||
env:
|
env:
|
||||||
QEMU_CMD: qemu-s390x
|
WRAPPER_CMD: qemu-s390x
|
||||||
|
TEST_ITERS: 16
|
||||||
HOST: s390x-linux-gnu
|
HOST: s390x-linux-gnu
|
||||||
BUILD:
|
|
||||||
WITH_VALGRIND: no
|
WITH_VALGRIND: no
|
||||||
ECDH: yes
|
ECDH: yes
|
||||||
RECOVERY: yes
|
RECOVERY: yes
|
||||||
|
@ -196,3 +178,138 @@ task:
|
||||||
- rm /etc/ld.so.cache
|
- rm /etc/ld.so.cache
|
||||||
- ./ci/cirrus.sh
|
- ./ci/cirrus.sh
|
||||||
<< : *CAT_LOGS
|
<< : *CAT_LOGS
|
||||||
|
|
||||||
|
task:
|
||||||
|
name: "ARM32: Linux (Debian stable, QEMU)"
|
||||||
|
container:
|
||||||
|
dockerfile: ci/linux-debian.Dockerfile
|
||||||
|
cpu: 1
|
||||||
|
memory: 1G
|
||||||
|
env:
|
||||||
|
WRAPPER_CMD: qemu-arm
|
||||||
|
TEST_ITERS: 16
|
||||||
|
HOST: arm-linux-gnueabihf
|
||||||
|
WITH_VALGRIND: no
|
||||||
|
ECDH: yes
|
||||||
|
RECOVERY: yes
|
||||||
|
EXPERIMENTAL: yes
|
||||||
|
SCHNORRSIG: yes
|
||||||
|
CTIMETEST: no
|
||||||
|
matrix:
|
||||||
|
- env: {}
|
||||||
|
- env: {ASM: arm}
|
||||||
|
<< : *MERGE_BASE
|
||||||
|
test_script:
|
||||||
|
- ./ci/cirrus.sh
|
||||||
|
<< : *CAT_LOGS
|
||||||
|
|
||||||
|
task:
|
||||||
|
name: "ARM64: Linux (Debian stable, QEMU)"
|
||||||
|
container:
|
||||||
|
dockerfile: ci/linux-debian.Dockerfile
|
||||||
|
cpu: 1
|
||||||
|
memory: 1G
|
||||||
|
env:
|
||||||
|
WRAPPER_CMD: qemu-aarch64
|
||||||
|
TEST_ITERS: 16
|
||||||
|
HOST: aarch64-linux-gnu
|
||||||
|
WITH_VALGRIND: no
|
||||||
|
ECDH: yes
|
||||||
|
RECOVERY: yes
|
||||||
|
EXPERIMENTAL: yes
|
||||||
|
SCHNORRSIG: yes
|
||||||
|
CTIMETEST: no
|
||||||
|
<< : *MERGE_BASE
|
||||||
|
test_script:
|
||||||
|
- ./ci/cirrus.sh
|
||||||
|
<< : *CAT_LOGS
|
||||||
|
|
||||||
|
task:
|
||||||
|
name: "ppc64le: Linux (Debian stable, QEMU)"
|
||||||
|
container:
|
||||||
|
dockerfile: ci/linux-debian.Dockerfile
|
||||||
|
cpu: 1
|
||||||
|
memory: 1G
|
||||||
|
env:
|
||||||
|
WRAPPER_CMD: qemu-ppc64le
|
||||||
|
TEST_ITERS: 16
|
||||||
|
HOST: powerpc64le-linux-gnu
|
||||||
|
WITH_VALGRIND: no
|
||||||
|
ECDH: yes
|
||||||
|
RECOVERY: yes
|
||||||
|
EXPERIMENTAL: yes
|
||||||
|
SCHNORRSIG: yes
|
||||||
|
CTIMETEST: no
|
||||||
|
<< : *MERGE_BASE
|
||||||
|
test_script:
|
||||||
|
- ./ci/cirrus.sh
|
||||||
|
<< : *CAT_LOGS
|
||||||
|
|
||||||
|
task:
|
||||||
|
name: "x86_64 (mingw32-w64): Windows (Debian stable, Wine)"
|
||||||
|
container:
|
||||||
|
dockerfile: ci/linux-debian.Dockerfile
|
||||||
|
cpu: 1
|
||||||
|
memory: 1G
|
||||||
|
env:
|
||||||
|
WRAPPER_CMD: wine64-stable
|
||||||
|
TEST_ITERS: 16
|
||||||
|
HOST: x86_64-w64-mingw32
|
||||||
|
WITH_VALGRIND: no
|
||||||
|
ECDH: yes
|
||||||
|
RECOVERY: yes
|
||||||
|
EXPERIMENTAL: yes
|
||||||
|
SCHNORRSIG: yes
|
||||||
|
CTIMETEST: no
|
||||||
|
<< : *MERGE_BASE
|
||||||
|
test_script:
|
||||||
|
- ./ci/cirrus.sh
|
||||||
|
<< : *CAT_LOGS
|
||||||
|
|
||||||
|
# Sanitizers
|
||||||
|
task:
|
||||||
|
container:
|
||||||
|
dockerfile: ci/linux-debian.Dockerfile
|
||||||
|
cpu: 1
|
||||||
|
memory: 1G
|
||||||
|
env:
|
||||||
|
ECDH: yes
|
||||||
|
RECOVERY: yes
|
||||||
|
EXPERIMENTAL: yes
|
||||||
|
SCHNORRSIG: yes
|
||||||
|
CTIMETEST: no
|
||||||
|
EXTRAFLAGS: "--disable-openssl-tests"
|
||||||
|
matrix:
|
||||||
|
- name: "Valgrind (memcheck)"
|
||||||
|
env:
|
||||||
|
# The `--error-exitcode` is required to make the test fail if valgrind found errors, otherwise it'll return 0 (https://www.valgrind.org/docs/manual/manual-core.html)
|
||||||
|
WRAPPER_CMD: "valgrind --error-exitcode=42"
|
||||||
|
TEST_ITERS: 16
|
||||||
|
- name: "UBSan, ASan, LSan"
|
||||||
|
env:
|
||||||
|
CFLAGS: "-fsanitize=undefined,address"
|
||||||
|
CFLAGS_FOR_BUILD: "-fsanitize=undefined,address"
|
||||||
|
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1"
|
||||||
|
ASAN_OPTIONS: "strict_string_checks=1:detect_stack_use_after_return=1:detect_leaks=1"
|
||||||
|
LSAN_OPTIONS: "use_unaligned=1"
|
||||||
|
TEST_ITERS: 32
|
||||||
|
# Try to cover many configurations with just a tiny matrix.
|
||||||
|
matrix:
|
||||||
|
- env:
|
||||||
|
ASM: auto
|
||||||
|
STATICPRECOMPUTATION: yes
|
||||||
|
- env:
|
||||||
|
ASM: no
|
||||||
|
STATICPRECOMPUTATION: no
|
||||||
|
ECMULTGENPRECISION: 2
|
||||||
|
matrix:
|
||||||
|
- env:
|
||||||
|
CC: clang
|
||||||
|
- env:
|
||||||
|
HOST: i686-linux-gnu
|
||||||
|
CC: i686-linux-gnu-gcc
|
||||||
|
<< : *MERGE_BASE
|
||||||
|
test_script:
|
||||||
|
- ./ci/cirrus.sh
|
||||||
|
<< : *CAT_LOGS
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,14 @@ libtool
|
||||||
*~
|
*~
|
||||||
*.log
|
*.log
|
||||||
*.trs
|
*.trs
|
||||||
|
|
||||||
|
coverage/
|
||||||
|
coverage.html
|
||||||
|
coverage.*.html
|
||||||
|
*.gcda
|
||||||
|
*.gcno
|
||||||
|
*.gcov
|
||||||
|
|
||||||
src/libsecp256k1-config.h
|
src/libsecp256k1-config.h
|
||||||
src/libsecp256k1-config.h.in
|
src/libsecp256k1-config.h.in
|
||||||
src/ecmult_static_context.h
|
src/ecmult_static_context.h
|
||||||
|
|
16
Makefile.am
16
Makefile.am
|
@ -68,7 +68,7 @@ endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libsecp256k1_la_SOURCES = src/secp256k1.c
|
libsecp256k1_la_SOURCES = src/secp256k1.c
|
||||||
libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES)
|
libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES)
|
||||||
libsecp256k1_la_LIBADD = $(SECP_LIBS) $(COMMON_LIB)
|
libsecp256k1_la_LIBADD = $(SECP_LIBS) $(COMMON_LIB)
|
||||||
|
|
||||||
if VALGRIND_ENABLED
|
if VALGRIND_ENABLED
|
||||||
|
@ -81,27 +81,27 @@ noinst_PROGRAMS += bench_verify bench_sign bench_internal bench_ecmult
|
||||||
bench_verify_SOURCES = src/bench_verify.c
|
bench_verify_SOURCES = src/bench_verify.c
|
||||||
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
|
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
|
||||||
# SECP_TEST_INCLUDES are only used here for CRYPTO_CPPFLAGS
|
# SECP_TEST_INCLUDES are only used here for CRYPTO_CPPFLAGS
|
||||||
bench_verify_CPPFLAGS = -DSECP256K1_BUILD $(SECP_TEST_INCLUDES)
|
bench_verify_CPPFLAGS = $(SECP_TEST_INCLUDES)
|
||||||
bench_sign_SOURCES = src/bench_sign.c
|
bench_sign_SOURCES = src/bench_sign.c
|
||||||
bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
|
bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
|
||||||
bench_internal_SOURCES = src/bench_internal.c
|
bench_internal_SOURCES = src/bench_internal.c
|
||||||
bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB)
|
bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB)
|
||||||
bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES)
|
bench_internal_CPPFLAGS = $(SECP_INCLUDES)
|
||||||
bench_ecmult_SOURCES = src/bench_ecmult.c
|
bench_ecmult_SOURCES = src/bench_ecmult.c
|
||||||
bench_ecmult_LDADD = $(SECP_LIBS) $(COMMON_LIB)
|
bench_ecmult_LDADD = $(SECP_LIBS) $(COMMON_LIB)
|
||||||
bench_ecmult_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES)
|
bench_ecmult_CPPFLAGS = $(SECP_INCLUDES)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
TESTS =
|
TESTS =
|
||||||
if USE_TESTS
|
if USE_TESTS
|
||||||
noinst_PROGRAMS += tests
|
noinst_PROGRAMS += tests
|
||||||
tests_SOURCES = src/tests.c
|
tests_SOURCES = src/tests.c
|
||||||
tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
|
tests_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
|
||||||
if VALGRIND_ENABLED
|
if VALGRIND_ENABLED
|
||||||
tests_CPPFLAGS += -DVALGRIND
|
tests_CPPFLAGS += -DVALGRIND
|
||||||
noinst_PROGRAMS += valgrind_ctime_test
|
noinst_PROGRAMS += valgrind_ctime_test
|
||||||
valgrind_ctime_test_SOURCES = src/valgrind_ctime_test.c
|
valgrind_ctime_test_SOURCES = src/valgrind_ctime_test.c
|
||||||
valgrind_ctime_test_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_LIBS) $(COMMON_LIB)
|
valgrind_ctime_test_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB)
|
||||||
endif
|
endif
|
||||||
if !ENABLE_COVERAGE
|
if !ENABLE_COVERAGE
|
||||||
tests_CPPFLAGS += -DVERIFY
|
tests_CPPFLAGS += -DVERIFY
|
||||||
|
@ -114,7 +114,7 @@ endif
|
||||||
if USE_EXHAUSTIVE_TESTS
|
if USE_EXHAUSTIVE_TESTS
|
||||||
noinst_PROGRAMS += exhaustive_tests
|
noinst_PROGRAMS += exhaustive_tests
|
||||||
exhaustive_tests_SOURCES = src/tests_exhaustive.c
|
exhaustive_tests_SOURCES = src/tests_exhaustive.c
|
||||||
exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES)
|
exhaustive_tests_CPPFLAGS = -I$(top_srcdir)/src $(SECP_INCLUDES)
|
||||||
if !ENABLE_COVERAGE
|
if !ENABLE_COVERAGE
|
||||||
exhaustive_tests_CPPFLAGS += -DVERIFY
|
exhaustive_tests_CPPFLAGS += -DVERIFY
|
||||||
endif
|
endif
|
||||||
|
@ -129,7 +129,7 @@ CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) -I$(builddir)/src
|
||||||
gen_context_OBJECTS = gen_context.o
|
gen_context_OBJECTS = gen_context.o
|
||||||
gen_context_BIN = gen_context$(BUILD_EXEEXT)
|
gen_context_BIN = gen_context$(BUILD_EXEEXT)
|
||||||
gen_%.o: src/gen_%.c src/libsecp256k1-config.h
|
gen_%.o: src/gen_%.c src/libsecp256k1-config.h
|
||||||
$(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
|
$(CC_FOR_BUILD) $(DEFS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
|
||||||
|
|
||||||
$(gen_context_BIN): $(gen_context_OBJECTS)
|
$(gen_context_BIN): $(gen_context_OBJECTS)
|
||||||
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $^ -o $@
|
$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $^ -o $@
|
||||||
|
|
|
@ -96,7 +96,8 @@ To create a report, `gcovr` is recommended, as it includes branch coverage repor
|
||||||
|
|
||||||
To create a HTML report with coloured and annotated source code:
|
To create a HTML report with coloured and annotated source code:
|
||||||
|
|
||||||
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage.html
|
$ mkdir -p coverage
|
||||||
|
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html
|
||||||
|
|
||||||
Reporting a vulnerability
|
Reporting a vulnerability
|
||||||
------------
|
------------
|
||||||
|
|
33
ci/cirrus.sh
33
ci/cirrus.sh
|
@ -25,42 +25,27 @@ valgrind --version || true
|
||||||
make
|
make
|
||||||
|
|
||||||
# Print information about binaries so that we can see that the architecture is correct
|
# Print information about binaries so that we can see that the architecture is correct
|
||||||
file *tests || true
|
file *tests* || true
|
||||||
file bench_* || true
|
file bench_* || true
|
||||||
file .libs/* || true
|
file .libs/* || true
|
||||||
|
|
||||||
if [ -n "$BUILD" ]
|
# This tells `make check` to wrap test invocations.
|
||||||
then
|
export LOG_COMPILER="$WRAPPER_CMD"
|
||||||
make "$BUILD"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$RUN_VALGRIND" = "yes" ]
|
# This limits the iterations in the tests and benchmarks.
|
||||||
then
|
export SECP256K1_TEST_ITERS="$TEST_ITERS"
|
||||||
# the `--error-exitcode` is required to make the test fail if valgrind found errors, otherwise it'll return 0 (https://www.valgrind.org/docs/manual/manual-core.html)
|
export SECP256K1_BENCH_ITERS="$BENCH_ITERS"
|
||||||
valgrind --error-exitcode=42 ./tests 16
|
|
||||||
valgrind --error-exitcode=42 ./exhaustive_tests
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$QEMU_CMD" ]
|
make "$BUILD"
|
||||||
then
|
|
||||||
$QEMU_CMD ./tests 16
|
|
||||||
$QEMU_CMD ./exhaustive_tests
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$BENCH" = "yes" ]
|
if [ "$BENCH" = "yes" ]
|
||||||
then
|
then
|
||||||
# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool
|
# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool
|
||||||
EXEC='./libtool --mode=execute'
|
EXEC='./libtool --mode=execute'
|
||||||
if [ -n "$QEMU_CMD" ]
|
if [ -n "$WRAPPER_CMD" ]
|
||||||
then
|
then
|
||||||
EXEC="$EXEC $QEMU_CMD"
|
EXEC="$EXEC $WRAPPER_CMD"
|
||||||
fi
|
fi
|
||||||
if [ "$RUN_VALGRIND" = "yes" ]
|
|
||||||
then
|
|
||||||
EXEC="$EXEC valgrind --error-exitcode=42"
|
|
||||||
fi
|
|
||||||
# This limits the iterations in the benchmarks below to ITER iterations.
|
|
||||||
export SECP256K1_BENCH_ITERS="$ITERS"
|
|
||||||
{
|
{
|
||||||
$EXEC ./bench_ecmult
|
$EXEC ./bench_ecmult
|
||||||
$EXEC ./bench_internal
|
$EXEC ./bench_internal
|
||||||
|
|
|
@ -2,12 +2,23 @@ FROM debian:stable
|
||||||
|
|
||||||
RUN dpkg --add-architecture i386
|
RUN dpkg --add-architecture i386
|
||||||
RUN dpkg --add-architecture s390x
|
RUN dpkg --add-architecture s390x
|
||||||
|
RUN dpkg --add-architecture armhf
|
||||||
|
RUN dpkg --add-architecture arm64
|
||||||
|
RUN dpkg --add-architecture ppc64el
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
|
|
||||||
# dkpg-dev: to make pkg-config work in cross-builds
|
# dkpg-dev: to make pkg-config work in cross-builds
|
||||||
|
# llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces
|
||||||
RUN apt-get install --no-install-recommends --no-upgrade -y \
|
RUN apt-get install --no-install-recommends --no-upgrade -y \
|
||||||
git ca-certificates \
|
git ca-certificates \
|
||||||
make automake libtool pkg-config dpkg-dev valgrind qemu-user \
|
make automake libtool pkg-config dpkg-dev valgrind qemu-user \
|
||||||
gcc clang libc6-dbg \
|
gcc clang llvm libc6-dbg \
|
||||||
gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 \
|
gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan5:i386 \
|
||||||
gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x
|
gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \
|
||||||
|
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \
|
||||||
|
gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 \
|
||||||
|
gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
|
||||||
|
wine gcc-mingw-w64-x86-64
|
||||||
|
|
||||||
|
# Run a dummy command in wine to make it set up configuration
|
||||||
|
RUN wine64-stable xcopy || true
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <secp256k1.h>
|
|
||||||
|
|
||||||
#include "lax_der_parsing.h"
|
#include "lax_der_parsing.h"
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,13 @@
|
||||||
#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H
|
#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H
|
||||||
#define SECP256K1_CONTRIB_LAX_DER_PARSING_H
|
#define SECP256K1_CONTRIB_LAX_DER_PARSING_H
|
||||||
|
|
||||||
|
/* #include secp256k1.h only when it hasn't been included yet.
|
||||||
|
This enables this file to be #included directly in other project
|
||||||
|
files (such as tests.c) without the need to set an explicit -I flag,
|
||||||
|
which would be necessary to locate secp256k1.h. */
|
||||||
|
#ifndef SECP256K1_H
|
||||||
#include <secp256k1.h>
|
#include <secp256k1.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <secp256k1.h>
|
|
||||||
|
|
||||||
#include "lax_der_privatekey_parsing.h"
|
#include "lax_der_privatekey_parsing.h"
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,13 @@
|
||||||
#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H
|
#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H
|
||||||
#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H
|
#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H
|
||||||
|
|
||||||
|
/* #include secp256k1.h only when it hasn't been included yet.
|
||||||
|
This enables this file to be #included directly in other project
|
||||||
|
files (such as tests.c) without the need to set an explicit -I flag,
|
||||||
|
which would be necessary to locate secp256k1.h. */
|
||||||
|
#ifndef SECP256K1_H
|
||||||
#include <secp256k1.h>
|
#include <secp256k1.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -7,7 +7,9 @@ extern "C" {
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/* These rules specify the order of arguments in API calls:
|
/* Unless explicitly stated all pointer arguments must not be NULL.
|
||||||
|
*
|
||||||
|
* The following rules specify the order of arguments in API calls:
|
||||||
*
|
*
|
||||||
* 1. Context pointers go first, followed by output arguments, combined
|
* 1. Context pointers go first, followed by output arguments, combined
|
||||||
* output/input arguments, and finally input-only arguments.
|
* output/input arguments, and finally input-only arguments.
|
||||||
|
@ -61,8 +63,9 @@ typedef struct secp256k1_scratch_space_struct secp256k1_scratch_space;
|
||||||
* The exact representation of data inside is implementation defined and not
|
* The exact representation of data inside is implementation defined and not
|
||||||
* guaranteed to be portable between different platforms or versions. It is
|
* guaranteed to be portable between different platforms or versions. It is
|
||||||
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
|
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
|
||||||
* If you need to convert to a format suitable for storage, transmission, or
|
* If you need to convert to a format suitable for storage or transmission,
|
||||||
* comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse.
|
* use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. To
|
||||||
|
* compare keys, use secp256k1_ec_pubkey_cmp.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char data[64];
|
unsigned char data[64];
|
||||||
|
@ -127,6 +130,17 @@ typedef int (*secp256k1_nonce_function)(
|
||||||
# define SECP256K1_INLINE inline
|
# define SECP256K1_INLINE inline
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
/** When this header is used at build-time the SECP256K1_BUILD define needs to be set
|
||||||
|
* to correctly setup export attributes and nullness checks. This is normally done
|
||||||
|
* by secp256k1.c but to guard against this header being included before secp256k1.c
|
||||||
|
* has had a chance to set the define (e.g. via test harnesses that just includes
|
||||||
|
* secp256k1.c) we set SECP256K1_NO_BUILD when this header is processed without the
|
||||||
|
* BUILD define so this condition can be caught.
|
||||||
|
*/
|
||||||
|
#ifndef SECP256K1_BUILD
|
||||||
|
# define SECP256K1_NO_BUILD
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SECP256K1_API
|
#ifndef SECP256K1_API
|
||||||
# if defined(_WIN32)
|
# if defined(_WIN32)
|
||||||
# ifdef SECP256K1_BUILD
|
# ifdef SECP256K1_BUILD
|
||||||
|
@ -370,6 +384,21 @@ SECP256K1_API int secp256k1_ec_pubkey_serialize(
|
||||||
unsigned int flags
|
unsigned int flags
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||||
|
|
||||||
|
/** Compare two public keys using lexicographic (of compressed serialization) order
|
||||||
|
*
|
||||||
|
* Returns: <0 if the first public key is less than the second
|
||||||
|
* >0 if the first public key is greater than the second
|
||||||
|
* 0 if the two public keys are equal
|
||||||
|
* Args: ctx: a secp256k1 context object.
|
||||||
|
* In: pubkey1: first public key to compare
|
||||||
|
* pubkey2: second public key to compare
|
||||||
|
*/
|
||||||
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
|
||||||
|
const secp256k1_context* ctx,
|
||||||
|
const secp256k1_pubkey* pubkey1,
|
||||||
|
const secp256k1_pubkey* pubkey2
|
||||||
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
/** Parse an ECDSA signature in compact (64 bytes) format.
|
/** Parse an ECDSA signature in compact (64 bytes) format.
|
||||||
*
|
*
|
||||||
* Returns: 1 when the signature could be parsed, 0 otherwise.
|
* Returns: 1 when the signature could be parsed, 0 otherwise.
|
||||||
|
|
|
@ -15,9 +15,9 @@ extern "C" {
|
||||||
* The exact representation of data inside is implementation defined and not
|
* The exact representation of data inside is implementation defined and not
|
||||||
* guaranteed to be portable between different platforms or versions. It is
|
* guaranteed to be portable between different platforms or versions. It is
|
||||||
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
|
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
|
||||||
* If you need to convert to a format suitable for storage, transmission, or
|
* If you need to convert to a format suitable for storage, transmission, use
|
||||||
* comparison, use secp256k1_xonly_pubkey_serialize and
|
* use secp256k1_xonly_pubkey_serialize and secp256k1_xonly_pubkey_parse. To
|
||||||
* secp256k1_xonly_pubkey_parse.
|
* compare keys, use secp256k1_xonly_pubkey_cmp.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char data[64];
|
unsigned char data[64];
|
||||||
|
@ -67,6 +67,21 @@ SECP256K1_API int secp256k1_xonly_pubkey_serialize(
|
||||||
const secp256k1_xonly_pubkey* pubkey
|
const secp256k1_xonly_pubkey* pubkey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
|
/** Compare two x-only public keys using lexicographic order
|
||||||
|
*
|
||||||
|
* Returns: <0 if the first public key is less than the second
|
||||||
|
* >0 if the first public key is greater than the second
|
||||||
|
* 0 if the two public keys are equal
|
||||||
|
* Args: ctx: a secp256k1 context object.
|
||||||
|
* In: pubkey1: first public key to compare
|
||||||
|
* pubkey2: second public key to compare
|
||||||
|
*/
|
||||||
|
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
|
||||||
|
const secp256k1_context* ctx,
|
||||||
|
const secp256k1_xonly_pubkey* pk1,
|
||||||
|
const secp256k1_xonly_pubkey* pk2
|
||||||
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
|
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
|
||||||
*
|
*
|
||||||
* Returns: 1 if the public key was successfully converted
|
* Returns: 1 if the public key was successfully converted
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../include/secp256k1.h"
|
||||||
#include "include/secp256k1_ecdh.h"
|
#include "../include/secp256k1_ecdh.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "secp256k1.c"
|
||||||
|
#include "../include/secp256k1.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "hash_impl.h"
|
#include "hash_impl.h"
|
||||||
|
@ -14,33 +15,177 @@
|
||||||
#include "scalar_impl.h"
|
#include "scalar_impl.h"
|
||||||
#include "ecmult_impl.h"
|
#include "ecmult_impl.h"
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "secp256k1.c"
|
|
||||||
|
|
||||||
#define POINTS 32768
|
#define POINTS 32768
|
||||||
|
|
||||||
|
void help(char **argv) {
|
||||||
|
printf("Benchmark EC multiplication algorithms\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Usage: %s <help|pippenger_wnaf|strauss_wnaf|simple>\n", argv[0]);
|
||||||
|
printf("The output shows the number of multiplied and summed points right after the\n");
|
||||||
|
printf("function name. The letter 'g' indicates that one of the points is the generator.\n");
|
||||||
|
printf("The benchmarks are divided by the number of points.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("default (ecmult_multi): picks pippenger_wnaf or strauss_wnaf depending on the\n");
|
||||||
|
printf(" batch size\n");
|
||||||
|
printf("pippenger_wnaf: for all batch sizes\n");
|
||||||
|
printf("strauss_wnaf: for all batch sizes\n");
|
||||||
|
printf("simple: multiply and sum each point individually\n");
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Setup once in advance */
|
/* Setup once in advance */
|
||||||
secp256k1_context* ctx;
|
secp256k1_context* ctx;
|
||||||
secp256k1_scratch_space* scratch;
|
secp256k1_scratch_space* scratch;
|
||||||
secp256k1_scalar* scalars;
|
secp256k1_scalar* scalars;
|
||||||
secp256k1_ge* pubkeys;
|
secp256k1_ge* pubkeys;
|
||||||
|
secp256k1_gej* pubkeys_gej;
|
||||||
secp256k1_scalar* seckeys;
|
secp256k1_scalar* seckeys;
|
||||||
secp256k1_gej* expected_output;
|
secp256k1_gej* expected_output;
|
||||||
secp256k1_ecmult_multi_func ecmult_multi;
|
secp256k1_ecmult_multi_func ecmult_multi;
|
||||||
|
|
||||||
/* Changes per test */
|
/* Changes per benchmark */
|
||||||
size_t count;
|
size_t count;
|
||||||
int includes_g;
|
int includes_g;
|
||||||
|
|
||||||
/* Changes per test iteration */
|
/* Changes per benchmark iteration, used to pick different scalars and pubkeys
|
||||||
|
* in each run. */
|
||||||
size_t offset1;
|
size_t offset1;
|
||||||
size_t offset2;
|
size_t offset2;
|
||||||
|
|
||||||
/* Test output. */
|
/* Benchmark output. */
|
||||||
secp256k1_gej* output;
|
secp256k1_gej* output;
|
||||||
} bench_data;
|
} bench_data;
|
||||||
|
|
||||||
static int bench_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, void* arg) {
|
/* Hashes x into [0, POINTS) twice and store the result in offset1 and offset2. */
|
||||||
|
static void hash_into_offset(bench_data* data, size_t x) {
|
||||||
|
data->offset1 = (x * 0x537b7f6f + 0x8f66a481) % POINTS;
|
||||||
|
data->offset2 = (x * 0x7f6f537b + 0x6a1a8f49) % POINTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check correctness of the benchmark by computing
|
||||||
|
* sum(outputs) ?= (sum(scalars_gen) + sum(seckeys)*sum(scalars))*G */
|
||||||
|
static void bench_ecmult_teardown_helper(bench_data* data, size_t* seckey_offset, size_t* scalar_offset, size_t* scalar_gen_offset, int iters) {
|
||||||
|
int i;
|
||||||
|
secp256k1_gej sum_output, tmp;
|
||||||
|
secp256k1_scalar sum_scalars;
|
||||||
|
|
||||||
|
secp256k1_gej_set_infinity(&sum_output);
|
||||||
|
secp256k1_scalar_clear(&sum_scalars);
|
||||||
|
for (i = 0; i < iters; ++i) {
|
||||||
|
secp256k1_gej_add_var(&sum_output, &sum_output, &data->output[i], NULL);
|
||||||
|
if (scalar_gen_offset != NULL) {
|
||||||
|
secp256k1_scalar_add(&sum_scalars, &sum_scalars, &data->scalars[(*scalar_gen_offset+i) % POINTS]);
|
||||||
|
}
|
||||||
|
if (seckey_offset != NULL) {
|
||||||
|
secp256k1_scalar s = data->seckeys[(*seckey_offset+i) % POINTS];
|
||||||
|
secp256k1_scalar_mul(&s, &s, &data->scalars[(*scalar_offset+i) % POINTS]);
|
||||||
|
secp256k1_scalar_add(&sum_scalars, &sum_scalars, &s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
secp256k1_ecmult_gen(&data->ctx->ecmult_gen_ctx, &tmp, &sum_scalars);
|
||||||
|
secp256k1_gej_neg(&tmp, &tmp);
|
||||||
|
secp256k1_gej_add_var(&tmp, &tmp, &sum_output, NULL);
|
||||||
|
CHECK(secp256k1_gej_is_infinity(&tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_setup(void* arg) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
/* Re-randomize offset to ensure that we're using different scalars and
|
||||||
|
* group elements in each run. */
|
||||||
|
hash_into_offset(data, data->offset1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_gen(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < iters; ++i) {
|
||||||
|
secp256k1_ecmult_gen(&data->ctx->ecmult_gen_ctx, &data->output[i], &data->scalars[(data->offset1+i) % POINTS]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_gen_teardown(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
bench_ecmult_teardown_helper(data, NULL, NULL, &data->offset1, iters);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_const(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < iters; ++i) {
|
||||||
|
secp256k1_ecmult_const(&data->output[i], &data->pubkeys[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], 256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_const_teardown(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, NULL, iters);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_1(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < iters; ++i) {
|
||||||
|
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_1_teardown(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, NULL, iters);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_1g(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
secp256k1_scalar zero;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
secp256k1_scalar_set_int(&zero, 0);
|
||||||
|
for (i = 0; i < iters; ++i) {
|
||||||
|
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->output[i], NULL, &zero, &data->scalars[(data->offset1+i) % POINTS]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_1g_teardown(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
bench_ecmult_teardown_helper(data, NULL, NULL, &data->offset1, iters);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_2g(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < iters/2; ++i) {
|
||||||
|
secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->output[i], &data->pubkeys_gej[(data->offset1+i) % POINTS], &data->scalars[(data->offset2+i) % POINTS], &data->scalars[(data->offset1+i) % POINTS]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bench_ecmult_2g_teardown(void* arg, int iters) {
|
||||||
|
bench_data* data = (bench_data*)arg;
|
||||||
|
bench_ecmult_teardown_helper(data, &data->offset1, &data->offset2, &data->offset1, iters/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_ecmult_bench(bench_data* data, int iters) {
|
||||||
|
char str[32];
|
||||||
|
sprintf(str, "ecmult_gen");
|
||||||
|
run_benchmark(str, bench_ecmult_gen, bench_ecmult_setup, bench_ecmult_gen_teardown, data, 10, iters);
|
||||||
|
sprintf(str, "ecmult_const");
|
||||||
|
run_benchmark(str, bench_ecmult_const, bench_ecmult_setup, bench_ecmult_const_teardown, data, 10, iters);
|
||||||
|
/* ecmult with non generator point */
|
||||||
|
sprintf(str, "ecmult 1");
|
||||||
|
run_benchmark(str, bench_ecmult_1, bench_ecmult_setup, bench_ecmult_1_teardown, data, 10, iters);
|
||||||
|
/* ecmult with generator point */
|
||||||
|
sprintf(str, "ecmult 1g");
|
||||||
|
run_benchmark(str, bench_ecmult_1g, bench_ecmult_setup, bench_ecmult_1g_teardown, data, 10, iters);
|
||||||
|
/* ecmult with generator and non-generator point. The reported time is per point. */
|
||||||
|
sprintf(str, "ecmult 2g");
|
||||||
|
run_benchmark(str, bench_ecmult_2g, bench_ecmult_setup, bench_ecmult_2g_teardown, data, 10, 2*iters);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bench_ecmult_multi_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, void* arg) {
|
||||||
bench_data* data = (bench_data*)arg;
|
bench_data* data = (bench_data*)arg;
|
||||||
if (data->includes_g) ++idx;
|
if (data->includes_g) ++idx;
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
|
@ -53,7 +198,7 @@ static int bench_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, vo
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bench_ecmult(void* arg, int iters) {
|
static void bench_ecmult_multi(void* arg, int iters) {
|
||||||
bench_data* data = (bench_data*)arg;
|
bench_data* data = (bench_data*)arg;
|
||||||
|
|
||||||
int includes_g = data->includes_g;
|
int includes_g = data->includes_g;
|
||||||
|
@ -62,19 +207,18 @@ static void bench_ecmult(void* arg, int iters) {
|
||||||
iters = iters / data->count;
|
iters = iters / data->count;
|
||||||
|
|
||||||
for (iter = 0; iter < iters; ++iter) {
|
for (iter = 0; iter < iters; ++iter) {
|
||||||
data->ecmult_multi(&data->ctx->error_callback, &data->ctx->ecmult_ctx, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_callback, arg, count - includes_g);
|
data->ecmult_multi(&data->ctx->error_callback, &data->ctx->ecmult_ctx, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_ecmult_multi_callback, arg, count - includes_g);
|
||||||
data->offset1 = (data->offset1 + count) % POINTS;
|
data->offset1 = (data->offset1 + count) % POINTS;
|
||||||
data->offset2 = (data->offset2 + count - 1) % POINTS;
|
data->offset2 = (data->offset2 + count - 1) % POINTS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bench_ecmult_setup(void* arg) {
|
static void bench_ecmult_multi_setup(void* arg) {
|
||||||
bench_data* data = (bench_data*)arg;
|
bench_data* data = (bench_data*)arg;
|
||||||
data->offset1 = (data->count * 0x537b7f6f + 0x8f66a481) % POINTS;
|
hash_into_offset(data, data->count);
|
||||||
data->offset2 = (data->count * 0x7f6f537b + 0x6a1a8f49) % POINTS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bench_ecmult_teardown(void* arg, int iters) {
|
static void bench_ecmult_multi_teardown(void* arg, int iters) {
|
||||||
bench_data* data = (bench_data*)arg;
|
bench_data* data = (bench_data*)arg;
|
||||||
int iter;
|
int iter;
|
||||||
iters = iters / data->count;
|
iters = iters / data->count;
|
||||||
|
@ -88,7 +232,7 @@ static void bench_ecmult_teardown(void* arg, int iters) {
|
||||||
|
|
||||||
static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) {
|
static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) {
|
||||||
secp256k1_sha256 sha256;
|
secp256k1_sha256 sha256;
|
||||||
unsigned char c[11] = {'e', 'c', 'm', 'u', 'l', 't', 0, 0, 0, 0};
|
unsigned char c[10] = {'e', 'c', 'm', 'u', 'l', 't', 0, 0, 0, 0};
|
||||||
unsigned char buf[32];
|
unsigned char buf[32];
|
||||||
int overflow = 0;
|
int overflow = 0;
|
||||||
c[6] = num;
|
c[6] = num;
|
||||||
|
@ -102,7 +246,7 @@ static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) {
|
||||||
CHECK(!overflow);
|
CHECK(!overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run_test(bench_data* data, size_t count, int includes_g, int num_iters) {
|
static void run_ecmult_multi_bench(bench_data* data, size_t count, int includes_g, int num_iters) {
|
||||||
char str[32];
|
char str[32];
|
||||||
static const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
|
static const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
size_t iters = 1 + num_iters / count;
|
size_t iters = 1 + num_iters / count;
|
||||||
|
@ -112,8 +256,7 @@ static void run_test(bench_data* data, size_t count, int includes_g, int num_ite
|
||||||
data->includes_g = includes_g;
|
data->includes_g = includes_g;
|
||||||
|
|
||||||
/* Compute (the negation of) the expected results directly. */
|
/* Compute (the negation of) the expected results directly. */
|
||||||
data->offset1 = (data->count * 0x537b7f6f + 0x8f66a481) % POINTS;
|
hash_into_offset(data, data->count);
|
||||||
data->offset2 = (data->count * 0x7f6f537b + 0x6a1a8f49) % POINTS;
|
|
||||||
for (iter = 0; iter < iters; ++iter) {
|
for (iter = 0; iter < iters; ++iter) {
|
||||||
secp256k1_scalar tmp;
|
secp256k1_scalar tmp;
|
||||||
secp256k1_scalar total = data->scalars[(data->offset1++) % POINTS];
|
secp256k1_scalar total = data->scalars[(data->offset1++) % POINTS];
|
||||||
|
@ -127,25 +270,26 @@ static void run_test(bench_data* data, size_t count, int includes_g, int num_ite
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the benchmark. */
|
/* Run the benchmark. */
|
||||||
sprintf(str, includes_g ? "ecmult_%ig" : "ecmult_%i", (int)count);
|
sprintf(str, includes_g ? "ecmult_multi %ig" : "ecmult_multi %i", (int)count);
|
||||||
run_benchmark(str, bench_ecmult, bench_ecmult_setup, bench_ecmult_teardown, data, 10, count * iters);
|
run_benchmark(str, bench_ecmult_multi, bench_ecmult_multi_setup, bench_ecmult_multi_teardown, data, 10, count * iters);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
bench_data data;
|
bench_data data;
|
||||||
int i, p;
|
int i, p;
|
||||||
secp256k1_gej* pubkeys_gej;
|
|
||||||
size_t scratch_size;
|
size_t scratch_size;
|
||||||
|
|
||||||
int iters = get_iters(10000);
|
int iters = get_iters(10000);
|
||||||
|
|
||||||
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
|
|
||||||
scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16;
|
|
||||||
data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size);
|
|
||||||
data.ecmult_multi = secp256k1_ecmult_multi_var;
|
data.ecmult_multi = secp256k1_ecmult_multi_var;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
if(have_flag(argc, argv, "pippenger_wnaf")) {
|
if(have_flag(argc, argv, "-h")
|
||||||
|
|| have_flag(argc, argv, "--help")
|
||||||
|
|| have_flag(argc, argv, "help")) {
|
||||||
|
help(argv);
|
||||||
|
return 1;
|
||||||
|
} else if(have_flag(argc, argv, "pippenger_wnaf")) {
|
||||||
printf("Using pippenger_wnaf:\n");
|
printf("Using pippenger_wnaf:\n");
|
||||||
data.ecmult_multi = secp256k1_ecmult_pippenger_batch_single;
|
data.ecmult_multi = secp256k1_ecmult_pippenger_batch_single;
|
||||||
} else if(have_flag(argc, argv, "strauss_wnaf")) {
|
} else if(have_flag(argc, argv, "strauss_wnaf")) {
|
||||||
|
@ -153,39 +297,48 @@ int main(int argc, char **argv) {
|
||||||
data.ecmult_multi = secp256k1_ecmult_strauss_batch_single;
|
data.ecmult_multi = secp256k1_ecmult_strauss_batch_single;
|
||||||
} else if(have_flag(argc, argv, "simple")) {
|
} else if(have_flag(argc, argv, "simple")) {
|
||||||
printf("Using simple algorithm:\n");
|
printf("Using simple algorithm:\n");
|
||||||
data.ecmult_multi = secp256k1_ecmult_multi_var;
|
|
||||||
secp256k1_scratch_space_destroy(data.ctx, data.scratch);
|
|
||||||
data.scratch = NULL;
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: unrecognized argument '%s'.\n", argv[0], argv[1]);
|
fprintf(stderr, "%s: unrecognized argument '%s'.\n\n", argv[0], argv[1]);
|
||||||
fprintf(stderr, "Use 'pippenger_wnaf', 'strauss_wnaf', 'simple' or no argument to benchmark a combined algorithm.\n");
|
help(argv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
|
||||||
|
scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16;
|
||||||
|
if (!have_flag(argc, argv, "simple")) {
|
||||||
|
data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size);
|
||||||
|
} else {
|
||||||
|
data.scratch = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate stuff */
|
/* Allocate stuff */
|
||||||
data.scalars = malloc(sizeof(secp256k1_scalar) * POINTS);
|
data.scalars = malloc(sizeof(secp256k1_scalar) * POINTS);
|
||||||
data.seckeys = malloc(sizeof(secp256k1_scalar) * POINTS);
|
data.seckeys = malloc(sizeof(secp256k1_scalar) * POINTS);
|
||||||
data.pubkeys = malloc(sizeof(secp256k1_ge) * POINTS);
|
data.pubkeys = malloc(sizeof(secp256k1_ge) * POINTS);
|
||||||
|
data.pubkeys_gej = malloc(sizeof(secp256k1_gej) * POINTS);
|
||||||
data.expected_output = malloc(sizeof(secp256k1_gej) * (iters + 1));
|
data.expected_output = malloc(sizeof(secp256k1_gej) * (iters + 1));
|
||||||
data.output = malloc(sizeof(secp256k1_gej) * (iters + 1));
|
data.output = malloc(sizeof(secp256k1_gej) * (iters + 1));
|
||||||
|
|
||||||
/* Generate a set of scalars, and private/public keypairs. */
|
/* Generate a set of scalars, and private/public keypairs. */
|
||||||
pubkeys_gej = malloc(sizeof(secp256k1_gej) * POINTS);
|
secp256k1_gej_set_ge(&data.pubkeys_gej[0], &secp256k1_ge_const_g);
|
||||||
secp256k1_gej_set_ge(&pubkeys_gej[0], &secp256k1_ge_const_g);
|
|
||||||
secp256k1_scalar_set_int(&data.seckeys[0], 1);
|
secp256k1_scalar_set_int(&data.seckeys[0], 1);
|
||||||
for (i = 0; i < POINTS; ++i) {
|
for (i = 0; i < POINTS; ++i) {
|
||||||
generate_scalar(i, &data.scalars[i]);
|
generate_scalar(i, &data.scalars[i]);
|
||||||
if (i) {
|
if (i) {
|
||||||
secp256k1_gej_double_var(&pubkeys_gej[i], &pubkeys_gej[i - 1], NULL);
|
secp256k1_gej_double_var(&data.pubkeys_gej[i], &data.pubkeys_gej[i - 1], NULL);
|
||||||
secp256k1_scalar_add(&data.seckeys[i], &data.seckeys[i - 1], &data.seckeys[i - 1]);
|
secp256k1_scalar_add(&data.seckeys[i], &data.seckeys[i - 1], &data.seckeys[i - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
secp256k1_ge_set_all_gej_var(data.pubkeys, pubkeys_gej, POINTS);
|
secp256k1_ge_set_all_gej_var(data.pubkeys, data.pubkeys_gej, POINTS);
|
||||||
free(pubkeys_gej);
|
|
||||||
|
|
||||||
|
/* Initialize offset1 and offset2 */
|
||||||
|
hash_into_offset(&data, 0);
|
||||||
|
run_ecmult_bench(&data, iters);
|
||||||
|
|
||||||
for (i = 1; i <= 8; ++i) {
|
for (i = 1; i <= 8; ++i) {
|
||||||
run_test(&data, i, 1, iters);
|
run_ecmult_multi_bench(&data, i, 1, iters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is disabled with low count of iterations because the loop runs 77 times even with iters=1
|
/* This is disabled with low count of iterations because the loop runs 77 times even with iters=1
|
||||||
|
@ -194,7 +347,7 @@ int main(int argc, char **argv) {
|
||||||
if (iters > 2) {
|
if (iters > 2) {
|
||||||
for (p = 0; p <= 11; ++p) {
|
for (p = 0; p <= 11; ++p) {
|
||||||
for (i = 9; i <= 16; ++i) {
|
for (i = 9; i <= 16; ++i) {
|
||||||
run_test(&data, i << p, 1, iters);
|
run_ecmult_multi_bench(&data, i << p, 1, iters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,6 +358,7 @@ int main(int argc, char **argv) {
|
||||||
secp256k1_context_destroy(data.ctx);
|
secp256k1_context_destroy(data.ctx);
|
||||||
free(data.scalars);
|
free(data.scalars);
|
||||||
free(data.pubkeys);
|
free(data.pubkeys);
|
||||||
|
free(data.pubkeys_gej);
|
||||||
free(data.seckeys);
|
free(data.seckeys);
|
||||||
free(data.output);
|
free(data.output);
|
||||||
free(data.expected_output);
|
free(data.expected_output);
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "secp256k1.c"
|
||||||
|
#include "../include/secp256k1.h"
|
||||||
|
|
||||||
#include "assumptions.h"
|
#include "assumptions.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -16,7 +17,6 @@
|
||||||
#include "ecmult_const_impl.h"
|
#include "ecmult_const_impl.h"
|
||||||
#include "ecmult_impl.h"
|
#include "ecmult_impl.h"
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "secp256k1.c"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
secp256k1_scalar scalar[2];
|
secp256k1_scalar scalar[2];
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../include/secp256k1.h"
|
||||||
#include "include/secp256k1_recovery.h"
|
#include "../include/secp256k1_recovery.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../include/secp256k1.h"
|
||||||
#include "include/secp256k1_schnorrsig.h"
|
#include "../include/secp256k1_schnorrsig.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../include/secp256k1.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../include/secp256k1.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,12 @@
|
||||||
/* We can't require the precomputed tables when creating them. */
|
/* We can't require the precomputed tables when creating them. */
|
||||||
#undef USE_ECMULT_STATIC_PRECOMPUTATION
|
#undef USE_ECMULT_STATIC_PRECOMPUTATION
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
/* In principle we could use external ASM, but this yields only a minor speedup in
|
||||||
|
build time and it's very complicated. In particular when cross-compiling, we'd
|
||||||
|
need to build the external ASM for the build and the host machine. */
|
||||||
|
#undef USE_EXTERNAL_ASM
|
||||||
|
|
||||||
|
#include "../include/secp256k1.h"
|
||||||
#include "assumptions.h"
|
#include "assumptions.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "field_impl.h"
|
#include "field_impl.h"
|
||||||
|
|
|
@ -100,8 +100,8 @@ static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) {
|
||||||
|
|
||||||
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
|
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
|
||||||
secp256k1_fe z2, z3;
|
secp256k1_fe z2, z3;
|
||||||
r->infinity = a->infinity;
|
|
||||||
if (a->infinity) {
|
if (a->infinity) {
|
||||||
|
secp256k1_ge_set_infinity(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
secp256k1_fe_inv_var(&a->z, &a->z);
|
secp256k1_fe_inv_var(&a->z, &a->z);
|
||||||
|
@ -110,8 +110,7 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
|
||||||
secp256k1_fe_mul(&a->x, &a->x, &z2);
|
secp256k1_fe_mul(&a->x, &a->x, &z2);
|
||||||
secp256k1_fe_mul(&a->y, &a->y, &z3);
|
secp256k1_fe_mul(&a->y, &a->y, &z3);
|
||||||
secp256k1_fe_set_int(&a->z, 1);
|
secp256k1_fe_set_int(&a->z, 1);
|
||||||
r->x = a->x;
|
secp256k1_ge_set_xy(r, &a->x, &a->y);
|
||||||
r->y = a->y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
|
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
|
||||||
|
@ -120,7 +119,9 @@ static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a
|
||||||
size_t last_i = SIZE_MAX;
|
size_t last_i = SIZE_MAX;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (!a[i].infinity) {
|
if (a[i].infinity) {
|
||||||
|
secp256k1_ge_set_infinity(&r[i]);
|
||||||
|
} else {
|
||||||
/* Use destination's x coordinates as scratch space */
|
/* Use destination's x coordinates as scratch space */
|
||||||
if (last_i == SIZE_MAX) {
|
if (last_i == SIZE_MAX) {
|
||||||
r[i].x = a[i].z;
|
r[i].x = a[i].z;
|
||||||
|
@ -148,7 +149,6 @@ static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a
|
||||||
r[last_i].x = u;
|
r[last_i].x = u;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
r[i].infinity = a[i].infinity;
|
|
||||||
if (!a[i].infinity) {
|
if (!a[i].infinity) {
|
||||||
secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
|
secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, s
|
||||||
* point will be gibberish (z = 0 but infinity = 0).
|
* point will be gibberish (z = 0 but infinity = 0).
|
||||||
*/
|
*/
|
||||||
if (a->infinity) {
|
if (a->infinity) {
|
||||||
r->infinity = 1;
|
secp256k1_gej_set_infinity(r);
|
||||||
if (rzr != NULL) {
|
if (rzr != NULL) {
|
||||||
secp256k1_fe_set_int(rzr, 1);
|
secp256k1_fe_set_int(rzr, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#ifndef SECP256K1_MODULE_ECDH_MAIN_H
|
#ifndef SECP256K1_MODULE_ECDH_MAIN_H
|
||||||
#define SECP256K1_MODULE_ECDH_MAIN_H
|
#define SECP256K1_MODULE_ECDH_MAIN_H
|
||||||
|
|
||||||
#include "include/secp256k1_ecdh.h"
|
#include "../../../include/secp256k1_ecdh.h"
|
||||||
#include "ecmult_const_impl.h"
|
#include "../../ecmult_const_impl.h"
|
||||||
|
|
||||||
static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) {
|
static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) {
|
||||||
unsigned char version = (y32[31] & 0x01) | 0x02;
|
unsigned char version = (y32[31] & 0x01) | 0x02;
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H
|
#ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H
|
||||||
#define SECP256K1_MODULE_EXTRAKEYS_MAIN_H
|
#define SECP256K1_MODULE_EXTRAKEYS_MAIN_H
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../../../include/secp256k1.h"
|
||||||
#include "include/secp256k1_extrakeys.h"
|
#include "../../../include/secp256k1_extrakeys.h"
|
||||||
|
|
||||||
static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context* ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey) {
|
static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context* ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey) {
|
||||||
return secp256k1_pubkey_load(ctx, ge, (const secp256k1_pubkey *) pubkey);
|
return secp256k1_pubkey_load(ctx, ge, (const secp256k1_pubkey *) pubkey);
|
||||||
|
@ -55,6 +55,32 @@ int secp256k1_xonly_pubkey_serialize(const secp256k1_context* ctx, unsigned char
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int secp256k1_xonly_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_xonly_pubkey* pk0, const secp256k1_xonly_pubkey* pk1) {
|
||||||
|
unsigned char out[2][32];
|
||||||
|
const secp256k1_xonly_pubkey* pk[2];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
VERIFY_CHECK(ctx != NULL);
|
||||||
|
pk[0] = pk0; pk[1] = pk1;
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
/* If the public key is NULL or invalid, xonly_pubkey_serialize will
|
||||||
|
* call the illegal_callback and return 0. In that case we will
|
||||||
|
* serialize the key as all zeros which is less than any valid public
|
||||||
|
* key. This results in consistent comparisons even if NULL or invalid
|
||||||
|
* pubkeys are involved and prevents edge cases such as sorting
|
||||||
|
* algorithms that use this function and do not terminate as a
|
||||||
|
* result. */
|
||||||
|
if (!secp256k1_xonly_pubkey_serialize(ctx, out[i], pk[i])) {
|
||||||
|
/* Note that xonly_pubkey_serialize should already set the output to
|
||||||
|
* zero in that case, but it's not guaranteed by the API, we can't
|
||||||
|
* test it and writing a VERIFY_CHECK is more complex than
|
||||||
|
* explicitly memsetting (again). */
|
||||||
|
memset(out[i], 0, sizeof(out[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return secp256k1_memcmp_var(out[0], out[1], sizeof(out[1]));
|
||||||
|
}
|
||||||
|
|
||||||
/** Keeps a group element as is if it has an even Y and otherwise negates it.
|
/** Keeps a group element as is if it has an even Y and otherwise negates it.
|
||||||
* y_parity is set to 0 in the former case and to 1 in the latter case.
|
* y_parity is set to 0 in the former case and to 1 in the latter case.
|
||||||
* Requires that the coordinates of r are normalized. */
|
* Requires that the coordinates of r are normalized. */
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#define SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H
|
#define SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H
|
||||||
|
|
||||||
#include "src/modules/extrakeys/main_impl.h"
|
#include "src/modules/extrakeys/main_impl.h"
|
||||||
#include "include/secp256k1_extrakeys.h"
|
#include "../../../include/secp256k1_extrakeys.h"
|
||||||
|
|
||||||
static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp256k1_ge* group) {
|
static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp256k1_ge* group) {
|
||||||
secp256k1_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1];
|
secp256k1_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1];
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_H
|
#ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_H
|
||||||
#define SECP256K1_MODULE_EXTRAKEYS_TESTS_H
|
#define SECP256K1_MODULE_EXTRAKEYS_TESTS_H
|
||||||
|
|
||||||
#include "secp256k1_extrakeys.h"
|
#include "../../../include/secp256k1_extrakeys.h"
|
||||||
|
|
||||||
static secp256k1_context* api_test_context(int flags, int *ecount) {
|
static secp256k1_context* api_test_context(int flags, int *ecount) {
|
||||||
secp256k1_context *ctx0 = secp256k1_context_create(flags);
|
secp256k1_context *ctx0 = secp256k1_context_create(flags);
|
||||||
|
@ -137,6 +137,43 @@ void test_xonly_pubkey(void) {
|
||||||
secp256k1_context_destroy(verify);
|
secp256k1_context_destroy(verify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_xonly_pubkey_comparison(void) {
|
||||||
|
unsigned char pk1_ser[32] = {
|
||||||
|
0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
|
||||||
|
0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
|
||||||
|
};
|
||||||
|
const unsigned char pk2_ser[32] = {
|
||||||
|
0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
|
||||||
|
0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
|
||||||
|
};
|
||||||
|
secp256k1_xonly_pubkey pk1;
|
||||||
|
secp256k1_xonly_pubkey pk2;
|
||||||
|
int ecount = 0;
|
||||||
|
secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
|
||||||
|
|
||||||
|
CHECK(secp256k1_xonly_pubkey_parse(none, &pk1, pk1_ser) == 1);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_parse(none, &pk2, pk2_ser) == 1);
|
||||||
|
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, NULL, &pk2) < 0);
|
||||||
|
CHECK(ecount == 1);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, NULL) > 0);
|
||||||
|
CHECK(ecount == 2);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk2) == 0);
|
||||||
|
CHECK(ecount == 2);
|
||||||
|
memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
|
||||||
|
CHECK(ecount == 3);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
|
||||||
|
CHECK(ecount == 5);
|
||||||
|
CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
|
||||||
|
CHECK(ecount == 6);
|
||||||
|
|
||||||
|
secp256k1_context_destroy(none);
|
||||||
|
}
|
||||||
|
|
||||||
void test_xonly_pubkey_tweak(void) {
|
void test_xonly_pubkey_tweak(void) {
|
||||||
unsigned char zeros64[64] = { 0 };
|
unsigned char zeros64[64] = { 0 };
|
||||||
unsigned char overflows[32];
|
unsigned char overflows[32];
|
||||||
|
@ -540,6 +577,7 @@ void run_extrakeys_tests(void) {
|
||||||
test_xonly_pubkey_tweak();
|
test_xonly_pubkey_tweak();
|
||||||
test_xonly_pubkey_tweak_check();
|
test_xonly_pubkey_tweak_check();
|
||||||
test_xonly_pubkey_tweak_recursive();
|
test_xonly_pubkey_tweak_recursive();
|
||||||
|
test_xonly_pubkey_comparison();
|
||||||
|
|
||||||
/* keypair tests */
|
/* keypair tests */
|
||||||
test_keypair();
|
test_keypair();
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef SECP256K1_MODULE_RECOVERY_MAIN_H
|
#ifndef SECP256K1_MODULE_RECOVERY_MAIN_H
|
||||||
#define SECP256K1_MODULE_RECOVERY_MAIN_H
|
#define SECP256K1_MODULE_RECOVERY_MAIN_H
|
||||||
|
|
||||||
#include "include/secp256k1_recovery.h"
|
#include "../../../include/secp256k1_recovery.h"
|
||||||
|
|
||||||
static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) {
|
static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) {
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#define SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H
|
#define SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H
|
||||||
|
|
||||||
#include "src/modules/recovery/main_impl.h"
|
#include "src/modules/recovery/main_impl.h"
|
||||||
#include "include/secp256k1_recovery.h"
|
#include "../../../include/secp256k1_recovery.h"
|
||||||
|
|
||||||
void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group) {
|
void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group) {
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
#ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H
|
#ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H
|
||||||
#define SECP256K1_MODULE_SCHNORRSIG_MAIN_H
|
#define SECP256K1_MODULE_SCHNORRSIG_MAIN_H
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../../../include/secp256k1.h"
|
||||||
#include "include/secp256k1_schnorrsig.h"
|
#include "../../../include/secp256k1_schnorrsig.h"
|
||||||
#include "hash.h"
|
#include "../../hash.h"
|
||||||
|
|
||||||
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
|
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
|
||||||
* SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */
|
* SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H
|
#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H
|
||||||
#define SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H
|
#define SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H
|
||||||
|
|
||||||
#include "include/secp256k1_schnorrsig.h"
|
#include "../../../include/secp256k1_schnorrsig.h"
|
||||||
#include "src/modules/schnorrsig/main_impl.h"
|
#include "src/modules/schnorrsig/main_impl.h"
|
||||||
|
|
||||||
static const unsigned char invalid_pubkey_bytes[][32] = {
|
static const unsigned char invalid_pubkey_bytes[][32] = {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_H
|
#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_H
|
||||||
#define SECP256K1_MODULE_SCHNORRSIG_TESTS_H
|
#define SECP256K1_MODULE_SCHNORRSIG_TESTS_H
|
||||||
|
|
||||||
#include "secp256k1_schnorrsig.h"
|
#include "../../../include/secp256k1_schnorrsig.h"
|
||||||
|
|
||||||
/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
|
/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
|
||||||
* bytes) changes the hash function
|
* bytes) changes the hash function
|
||||||
|
@ -103,7 +103,7 @@ void test_schnorrsig_api(void) {
|
||||||
unsigned char sk3[32];
|
unsigned char sk3[32];
|
||||||
unsigned char msg[32];
|
unsigned char msg[32];
|
||||||
secp256k1_keypair keypairs[3];
|
secp256k1_keypair keypairs[3];
|
||||||
secp256k1_keypair invalid_keypair = { 0 };
|
secp256k1_keypair invalid_keypair = {{ 0 }};
|
||||||
secp256k1_xonly_pubkey pk[3];
|
secp256k1_xonly_pubkey pk[3];
|
||||||
secp256k1_xonly_pubkey zero_pk;
|
secp256k1_xonly_pubkey zero_pk;
|
||||||
unsigned char sig[64];
|
unsigned char sig[64];
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#define SECP256K1_BUILD
|
||||||
#include "include/secp256k1_preallocated.h"
|
|
||||||
|
#include "../include/secp256k1.h"
|
||||||
|
#include "../include/secp256k1_preallocated.h"
|
||||||
|
|
||||||
#include "assumptions.h"
|
#include "assumptions.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -21,6 +23,10 @@
|
||||||
#include "scratch_impl.h"
|
#include "scratch_impl.h"
|
||||||
#include "selftest.h"
|
#include "selftest.h"
|
||||||
|
|
||||||
|
#ifdef SECP256K1_NO_BUILD
|
||||||
|
# error "secp256k1.h processed without SECP256K1_BUILD defined while building secp256k1.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VALGRIND)
|
#if defined(VALGRIND)
|
||||||
# include <valgrind/memcheck.h>
|
# include <valgrind/memcheck.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -316,6 +322,32 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int secp256k1_ec_pubkey_cmp(const secp256k1_context* ctx, const secp256k1_pubkey* pubkey0, const secp256k1_pubkey* pubkey1) {
|
||||||
|
unsigned char out[2][33];
|
||||||
|
const secp256k1_pubkey* pk[2];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
VERIFY_CHECK(ctx != NULL);
|
||||||
|
pk[0] = pubkey0; pk[1] = pubkey1;
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
size_t out_size = sizeof(out[i]);
|
||||||
|
/* If the public key is NULL or invalid, ec_pubkey_serialize will call
|
||||||
|
* the illegal_callback and return 0. In that case we will serialize the
|
||||||
|
* key as all zeros which is less than any valid public key. This
|
||||||
|
* results in consistent comparisons even if NULL or invalid pubkeys are
|
||||||
|
* involved and prevents edge cases such as sorting algorithms that use
|
||||||
|
* this function and do not terminate as a result. */
|
||||||
|
if (!secp256k1_ec_pubkey_serialize(ctx, out[i], &out_size, pk[i], SECP256K1_EC_COMPRESSED)) {
|
||||||
|
/* Note that ec_pubkey_serialize should already set the output to
|
||||||
|
* zero in that case, but it's not guaranteed by the API, we can't
|
||||||
|
* test it and writing a VERIFY_CHECK is more complex than
|
||||||
|
* explicitly memsetting (again). */
|
||||||
|
memset(out[i], 0, sizeof(out[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return secp256k1_memcmp_var(out[0], out[1], sizeof(out[0]));
|
||||||
|
}
|
||||||
|
|
||||||
static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) {
|
static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) {
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
if (sizeof(secp256k1_scalar) == 32) {
|
if (sizeof(secp256k1_scalar) == 32) {
|
||||||
|
|
|
@ -127,7 +127,7 @@ static void secp256k1_testrand_init(const char* hexseed) {
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FILE *frand = fopen("/dev/urandom", "r");
|
FILE *frand = fopen("/dev/urandom", "rb");
|
||||||
if ((frand == NULL) || fread(&seed16, 1, sizeof(seed16), frand) != sizeof(seed16)) {
|
if ((frand == NULL) || fread(&seed16, 1, sizeof(seed16), frand) != sizeof(seed16)) {
|
||||||
uint64_t t = time(NULL) * (uint64_t)1337;
|
uint64_t t = time(NULL) * (uint64_t)1337;
|
||||||
fprintf(stderr, "WARNING: could not read 16 bytes from /dev/urandom; falling back to insecure PRNG\n");
|
fprintf(stderr, "WARNING: could not read 16 bytes from /dev/urandom; falling back to insecure PRNG\n");
|
||||||
|
|
78
src/tests.c
78
src/tests.c
|
@ -15,8 +15,8 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "secp256k1.c"
|
#include "secp256k1.c"
|
||||||
#include "include/secp256k1.h"
|
#include "../include/secp256k1.h"
|
||||||
#include "include/secp256k1_preallocated.h"
|
#include "../include/secp256k1_preallocated.h"
|
||||||
#include "testrand_impl.h"
|
#include "testrand_impl.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "contrib/lax_der_parsing.c"
|
#include "../contrib/lax_der_parsing.c"
|
||||||
#include "contrib/lax_der_privatekey_parsing.c"
|
#include "../contrib/lax_der_privatekey_parsing.c"
|
||||||
|
|
||||||
#include "modinv32_impl.h"
|
#include "modinv32_impl.h"
|
||||||
#ifdef SECP256K1_WIDEMUL_INT128
|
#ifdef SECP256K1_WIDEMUL_INT128
|
||||||
|
@ -3101,20 +3101,34 @@ void test_ge(void) {
|
||||||
|
|
||||||
/* Test batch gej -> ge conversion with many infinities. */
|
/* Test batch gej -> ge conversion with many infinities. */
|
||||||
for (i = 0; i < 4 * runs + 1; i++) {
|
for (i = 0; i < 4 * runs + 1; i++) {
|
||||||
|
int odd;
|
||||||
random_group_element_test(&ge[i]);
|
random_group_element_test(&ge[i]);
|
||||||
|
odd = secp256k1_fe_is_odd(&ge[i].x);
|
||||||
|
CHECK(odd == 0 || odd == 1);
|
||||||
/* randomly set half the points to infinity */
|
/* randomly set half the points to infinity */
|
||||||
if(secp256k1_fe_is_odd(&ge[i].x)) {
|
if (odd == i % 2) {
|
||||||
secp256k1_ge_set_infinity(&ge[i]);
|
secp256k1_ge_set_infinity(&ge[i]);
|
||||||
}
|
}
|
||||||
secp256k1_gej_set_ge(&gej[i], &ge[i]);
|
secp256k1_gej_set_ge(&gej[i], &ge[i]);
|
||||||
}
|
}
|
||||||
/* batch invert */
|
/* batch convert */
|
||||||
secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1);
|
secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1);
|
||||||
/* check result */
|
/* check result */
|
||||||
for (i = 0; i < 4 * runs + 1; i++) {
|
for (i = 0; i < 4 * runs + 1; i++) {
|
||||||
ge_equals_gej(&ge[i], &gej[i]);
|
ge_equals_gej(&ge[i], &gej[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test batch gej -> ge conversion with all infinities. */
|
||||||
|
for (i = 0; i < 4 * runs + 1; i++) {
|
||||||
|
secp256k1_gej_set_infinity(&gej[i]);
|
||||||
|
}
|
||||||
|
/* batch convert */
|
||||||
|
secp256k1_ge_set_all_gej_var(ge, gej, 4 * runs + 1);
|
||||||
|
/* check result */
|
||||||
|
for (i = 0; i < 4 * runs + 1; i++) {
|
||||||
|
CHECK(secp256k1_ge_is_infinity(&ge[i]));
|
||||||
|
}
|
||||||
|
|
||||||
free(ge);
|
free(ge);
|
||||||
free(gej);
|
free(gej);
|
||||||
}
|
}
|
||||||
|
@ -5434,6 +5448,55 @@ void test_random_pubkeys(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void run_pubkey_comparison(void) {
|
||||||
|
unsigned char pk1_ser[33] = {
|
||||||
|
0x02,
|
||||||
|
0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
|
||||||
|
0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
|
||||||
|
};
|
||||||
|
const unsigned char pk2_ser[33] = {
|
||||||
|
0x02,
|
||||||
|
0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
|
||||||
|
0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
|
||||||
|
};
|
||||||
|
secp256k1_pubkey pk1;
|
||||||
|
secp256k1_pubkey pk2;
|
||||||
|
int32_t ecount = 0;
|
||||||
|
|
||||||
|
CHECK(secp256k1_ec_pubkey_parse(ctx, &pk1, pk1_ser, sizeof(pk1_ser)) == 1);
|
||||||
|
CHECK(secp256k1_ec_pubkey_parse(ctx, &pk2, pk2_ser, sizeof(pk2_ser)) == 1);
|
||||||
|
|
||||||
|
secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, NULL, &pk2) < 0);
|
||||||
|
CHECK(ecount == 1);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, NULL) > 0);
|
||||||
|
CHECK(ecount == 2);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, &pk2) < 0);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk1) > 0);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, &pk1) == 0);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk2) == 0);
|
||||||
|
CHECK(ecount == 2);
|
||||||
|
{
|
||||||
|
secp256k1_pubkey pk_tmp;
|
||||||
|
memset(&pk_tmp, 0, sizeof(pk_tmp)); /* illegal pubkey */
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk_tmp, &pk2) < 0);
|
||||||
|
CHECK(ecount == 3);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk_tmp, &pk_tmp) == 0);
|
||||||
|
CHECK(ecount == 5);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk_tmp) > 0);
|
||||||
|
CHECK(ecount == 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
secp256k1_context_set_illegal_callback(ctx, NULL, NULL);
|
||||||
|
|
||||||
|
/* Make pk2 the same as pk1 but with 3 rather than 2. Note that in
|
||||||
|
* an uncompressed encoding, these would have the opposite ordering */
|
||||||
|
pk1_ser[0] = 3;
|
||||||
|
CHECK(secp256k1_ec_pubkey_parse(ctx, &pk2, pk1_ser, sizeof(pk1_ser)) == 1);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk1, &pk2) < 0);
|
||||||
|
CHECK(secp256k1_ec_pubkey_cmp(ctx, &pk2, &pk1) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
void run_random_pubkeys(void) {
|
void run_random_pubkeys(void) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 10*count; i++) {
|
for (i = 0; i < 10*count; i++) {
|
||||||
|
@ -6408,7 +6471,7 @@ int main(int argc, char **argv) {
|
||||||
count = strtol(argv[1], NULL, 0);
|
count = strtol(argv[1], NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
const char* env = getenv("SECP256K1_TEST_ITERS");
|
const char* env = getenv("SECP256K1_TEST_ITERS");
|
||||||
if (env) {
|
if (env && strlen(env) > 0) {
|
||||||
count = strtol(env, NULL, 0);
|
count = strtol(env, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6485,6 +6548,7 @@ int main(int argc, char **argv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ecdsa tests */
|
/* ecdsa tests */
|
||||||
|
run_pubkey_comparison();
|
||||||
run_random_pubkeys();
|
run_random_pubkeys();
|
||||||
run_ecdsa_der_parse();
|
run_ecdsa_der_parse();
|
||||||
run_ecdsa_sign_verify();
|
run_ecdsa_sign_verify();
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#undef USE_ECMULT_STATIC_PRECOMPUTATION
|
#undef USE_ECMULT_STATIC_PRECOMPUTATION
|
||||||
|
@ -20,10 +19,10 @@
|
||||||
#define EXHAUSTIVE_TEST_ORDER 13
|
#define EXHAUSTIVE_TEST_ORDER 13
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "secp256k1.c"
|
||||||
|
#include "../include/secp256k1.h"
|
||||||
#include "assumptions.h"
|
#include "assumptions.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "secp256k1.c"
|
|
||||||
#include "testrand_impl.h"
|
#include "testrand_impl.h"
|
||||||
|
|
||||||
static int count = 2;
|
static int count = 2;
|
||||||
|
|
|
@ -7,24 +7,24 @@
|
||||||
#include <valgrind/memcheck.h>
|
#include <valgrind/memcheck.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "include/secp256k1.h"
|
#include "../include/secp256k1.h"
|
||||||
#include "assumptions.h"
|
#include "assumptions.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef ENABLE_MODULE_ECDH
|
#ifdef ENABLE_MODULE_ECDH
|
||||||
# include "include/secp256k1_ecdh.h"
|
# include "../include/secp256k1_ecdh.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_MODULE_RECOVERY
|
#ifdef ENABLE_MODULE_RECOVERY
|
||||||
# include "include/secp256k1_recovery.h"
|
# include "../include/secp256k1_recovery.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_MODULE_EXTRAKEYS
|
#ifdef ENABLE_MODULE_EXTRAKEYS
|
||||||
# include "include/secp256k1_extrakeys.h"
|
# include "../include/secp256k1_extrakeys.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_MODULE_SCHNORRSIG
|
#ifdef ENABLE_MODULE_SCHNORRSIG
|
||||||
#include "include/secp256k1_schnorrsig.h"
|
#include "../include/secp256k1_schnorrsig.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void run_tests(secp256k1_context *ctx, unsigned char *key);
|
void run_tests(secp256k1_context *ctx, unsigned char *key);
|
||||||
|
|
Loading…
Reference in New Issue