Skip to content

Commit e626f00

Browse files
2 parents 0ffca6f + e4af41c commit e626f00

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1551
-1584
lines changed

.cirrus.yml

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
env:
2+
### cirrus config
3+
CIRRUS_CLONE_DEPTH: 1
4+
### compiler options
5+
HOST:
6+
WRAPPER_CMD:
7+
# Specific warnings can be disabled with -Wno-error=foo.
8+
# -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual.
9+
WERROR_CFLAGS: -Werror -pedantic-errors
10+
MAKEFLAGS: -j4
11+
BUILD: check
12+
### secp256k1 config
13+
ECMULTWINDOW: auto
14+
ECMULTGENPRECISION: auto
15+
ASM: no
16+
WIDEMUL: auto
17+
WITH_VALGRIND: yes
18+
EXTRAFLAGS:
19+
### secp256k1 modules
20+
EXPERIMENTAL: no
21+
ECDH: no
22+
RECOVERY: no
23+
SCHNORRSIG: no
24+
ELLSWIFT: no
25+
### test options
26+
SECP256K1_TEST_ITERS:
27+
BENCH: yes
28+
SECP256K1_BENCH_ITERS: 2
29+
CTIMETESTS: yes
30+
# Compile and run the tests
31+
EXAMPLES: yes
32+
33+
cat_logs_snippet: &CAT_LOGS
34+
always:
35+
cat_tests_log_script:
36+
- cat tests.log || true
37+
cat_noverify_tests_log_script:
38+
- cat noverify_tests.log || true
39+
cat_exhaustive_tests_log_script:
40+
- cat exhaustive_tests.log || true
41+
cat_ctime_tests_log_script:
42+
- cat ctime_tests.log || true
43+
cat_bench_log_script:
44+
- cat bench.log || true
45+
cat_config_log_script:
46+
- cat config.log || true
47+
cat_test_env_script:
48+
- cat test_env.log || true
49+
cat_ci_env_script:
50+
- env
51+
52+
linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER
53+
env_script:
54+
- env | tee /tmp/env
55+
build_script:
56+
- DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm"
57+
- docker image prune --force # Cleanup stale layers
58+
test_script:
59+
- docker run --rm --mount "type=bind,src=./,dst=/ci_secp256k1" --env-file /tmp/env --replace --name "ci_secp256k1_arm" "ci_secp256k1_arm" bash -c "cd /ci_secp256k1/ && ./ci/ci.sh"
60+
61+
task:
62+
name: "ARM64: Linux (Debian stable)"
63+
persistent_worker:
64+
labels:
65+
type: arm64
66+
env:
67+
ECDH: yes
68+
RECOVERY: yes
69+
SCHNORRSIG: yes
70+
ELLSWIFT: yes
71+
matrix:
72+
# Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU
73+
- env: { CC: 'gcc-snapshot' }
74+
<< : *LINUX_ARM64_CONTAINER
75+
<< : *CAT_LOGS
76+
77+
task:
78+
name: "ARM64: Linux (Debian stable), Valgrind"
79+
persistent_worker:
80+
labels:
81+
type: arm64
82+
env:
83+
ECDH: yes
84+
RECOVERY: yes
85+
SCHNORRSIG: yes
86+
ELLSWIFT: yes
87+
WRAPPER_CMD: 'valgrind --error-exitcode=42'
88+
SECP256K1_TEST_ITERS: 2
89+
matrix:
90+
- env: { CC: 'gcc' }
91+
- env: { CC: 'clang' }
92+
- env: { CC: 'gcc-snapshot' }
93+
- env: { CC: 'clang-snapshot' }
94+
<< : *LINUX_ARM64_CONTAINER
95+
<< : *CAT_LOGS

CHANGELOG.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010

1111
## [Unreleased]
1212

13+
## [0.4.1] - 2023-12-21
14+
15+
#### Changed
16+
- The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one.
17+
- Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`.
18+
19+
#### ABI Compatibility
20+
The ABI is backward compatible with versions 0.4.0 and 0.3.x.
21+
1322
## [0.4.0] - 2023-09-04
1423

1524
#### Added
@@ -109,7 +118,8 @@ This version was in fact never released.
109118
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
110119
Therefore, this version number does not uniquely identify a set of source files.
111120

112-
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...HEAD
121+
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...HEAD
122+
[0.4.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...v0.4.1
113123
[0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0
114124
[0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2
115125
[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1

CMakeLists.txt

+37-18
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ project(libsecp256k1
1111
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
1212
# the API. All changes in experimental modules are treated as
1313
# backwards-compatible and therefore at most increase the minor version.
14-
VERSION 0.4.1
14+
VERSION 0.4.2
1515
DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
1616
HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
1717
LANGUAGES C
@@ -35,7 +35,7 @@ endif()
3535
# All changes in experimental modules are treated as if they don't affect the
3636
# interface and therefore only increase the revision.
3737
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 3)
38-
set(${PROJECT_NAME}_LIB_VERSION_REVISION 1)
38+
set(${PROJECT_NAME}_LIB_VERSION_REVISION 2)
3939
set(${PROJECT_NAME}_LIB_VERSION_AGE 1)
4040

4141
set(CMAKE_C_STANDARD 90)
@@ -51,29 +51,40 @@ endif()
5151

5252
option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL})
5353

54-
option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
55-
if(SECP256K1_ENABLE_MODULE_ECDH)
56-
add_compile_definitions(ENABLE_MODULE_ECDH=1)
57-
endif()
54+
## Modules
5855

56+
# We declare all options before processing them, to make sure we can express
57+
# dependendencies while processing.
58+
option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
5959
option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
60-
if(SECP256K1_ENABLE_MODULE_RECOVERY)
61-
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
62-
endif()
63-
6460
option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
6561
option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
62+
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
63+
64+
# Processing must be done in a topological sorting of the dependency graph
65+
# (dependent module first).
66+
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
67+
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
68+
endif()
69+
6670
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
71+
if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS)
72+
message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.")
73+
endif()
6774
set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON)
6875
add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1)
6976
endif()
77+
7078
if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
7179
add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1)
7280
endif()
7381

74-
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
75-
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
76-
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
82+
if(SECP256K1_ENABLE_MODULE_RECOVERY)
83+
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
84+
endif()
85+
86+
if(SECP256K1_ENABLE_MODULE_ECDH)
87+
add_compile_definitions(ENABLE_MODULE_ECDH=1)
7788
endif()
7889

7990
option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
@@ -107,7 +118,7 @@ if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
107118
endif()
108119
mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
109120

110-
set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly optimizations to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]")
121+
set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]")
111122
set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32")
112123
check_string_option_value(SECP256K1_ASM)
113124
if(SECP256K1_ASM STREQUAL "arm32")
@@ -117,7 +128,7 @@ if(SECP256K1_ASM STREQUAL "arm32")
117128
if(HAVE_ARM32_ASM)
118129
add_compile_definitions(USE_EXTERNAL_ASM=1)
119130
else()
120-
message(FATAL_ERROR "ARM32 assembly optimization requested but not available.")
131+
message(FATAL_ERROR "ARM32 assembly requested but not available.")
121132
endif()
122133
elseif(SECP256K1_ASM)
123134
include(CheckX86_64Assembly)
@@ -128,14 +139,14 @@ elseif(SECP256K1_ASM)
128139
elseif(SECP256K1_ASM STREQUAL "AUTO")
129140
set(SECP256K1_ASM "OFF")
130141
else()
131-
message(FATAL_ERROR "x86_64 assembly optimization requested but not available.")
142+
message(FATAL_ERROR "x86_64 assembly requested but not available.")
132143
endif()
133144
endif()
134145

135146
option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF)
136147
if(NOT SECP256K1_EXPERIMENTAL)
137148
if(SECP256K1_ASM STREQUAL "arm32")
138-
message(FATAL_ERROR "ARM32 assembly optimization is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
149+
message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
139150
endif()
140151
endif()
141152

@@ -254,9 +265,14 @@ if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUST
254265
enable_testing()
255266
endif()
256267

268+
set(SECP256K1_LATE_CFLAGS "" CACHE STRING "Compiler flags that are added to the command line after all other flags added by the build system.")
269+
include(AllTargetsCompileOptions)
270+
257271
add_subdirectory(src)
272+
all_targets_compile_options(src "${SECP256K1_LATE_CFLAGS}")
258273
if(SECP256K1_BUILD_EXAMPLES)
259274
add_subdirectory(examples)
275+
all_targets_compile_options(examples "${SECP256K1_LATE_CFLAGS}")
260276
endif()
261277

262278
message("\n")
@@ -280,7 +296,7 @@ message("Parameters:")
280296
message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
281297
message(" ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}")
282298
message("Optional features:")
283-
message(" assembly optimization ............... ${SECP256K1_ASM}")
299+
message(" assembly ............................ ${SECP256K1_ASM}")
284300
message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}")
285301
if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
286302
message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}")
@@ -330,6 +346,9 @@ else()
330346
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
331347
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
332348
endif()
349+
if(SECP256K1_LATE_CFLAGS)
350+
message("SECP256K1_LATE_CFLAGS ................. ${SECP256K1_LATE_CFLAGS}")
351+
endif()
333352
message("\n")
334353
if(SECP256K1_EXPERIMENTAL)
335354
message(

CONTRIBUTING.md

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Contributing to libsecp256k1
2+
3+
## Scope
4+
5+
libsecp256k1 is a library for elliptic curve cryptography on the curve secp256k1, not a general-purpose cryptography library.
6+
The library primarily serves the needs of the Bitcoin Core project but provides additional functionality for the benefit of the wider Bitcoin ecosystem.
7+
8+
## Adding new functionality or modules
9+
10+
The libsecp256k1 project welcomes contributions in the form of new functionality or modules, provided they are within the project's scope.
11+
12+
It is the responsibility of the contributors to convince the maintainers that the proposed functionality is within the project's scope, high-quality and maintainable.
13+
Contributors are recommended to provide the following in addition to the new code:
14+
15+
* **Specification:**
16+
A specification can help significantly in reviewing the new code as it provides documentation and context.
17+
It may justify various design decisions, give a motivation and outline security goals.
18+
If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code.
19+
* **Security Arguments:**
20+
In addition to a defining the security goals, it should be argued that the new functionality meets these goals.
21+
Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security.
22+
* **Relevance Arguments:**
23+
The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases.
24+
25+
These are not the only factors taken into account when considering to add new functionality.
26+
The proposed new libsecp256k1 code must be of high quality, including API documentation and tests, as well as featuring a misuse-resistant API design.
27+
28+
We recommend reaching out to other contributors (see [Communication Channels](#communication-channels)) and get feedback before implementing new functionality.
29+
30+
## Communication channels
31+
32+
Most communication about libsecp256k1 occurs on the GitHub repository: in issues, pull request or on the discussion board.
33+
34+
Additionally, there is an IRC channel dedicated to libsecp256k1, with biweekly meetings (see channel topic).
35+
The channel is `#secp256k1` on Libera Chat.
36+
The easiest way to participate on IRC is with the web client, [web.libera.chat](https://web.libera.chat/#secp256k1).
37+
Chat history logs can be found at https://gnusha.org/secp256k1/.
38+
39+
## Contributor workflow & peer review
40+
41+
The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Core's workflow and review processes described in its [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md).
42+
43+
### Coding conventions
44+
45+
In addition, libsecp256k1 tries to maintain the following coding conventions:
46+
47+
* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations.
48+
* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)).
49+
* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)).
50+
* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory.
51+
* Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)).
52+
53+
#### Style conventions
54+
55+
* Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures.
56+
* New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting.
57+
* The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block:
58+
```C
59+
void secp256k_foo(void) {
60+
unsigned int x; /* declaration */
61+
int y = 2*x; /* declaration */
62+
x = 17; /* statement */
63+
{
64+
int a, b; /* declaration */
65+
a = x + y; /* statement */
66+
secp256k_bar(x, &b); /* statement */
67+
}
68+
}
69+
```
70+
* Use `unsigned int` instead of just `unsigned`.
71+
* Use `void *ptr` instead of `void* ptr`.
72+
* Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h).
73+
* User-facing comment lines in headers should be limited to 80 chars if possible.
74+
* All identifiers in file scope should start with `secp256k1_`.
75+
* Avoid trailing whitespace.
76+
77+
### Tests
78+
79+
#### Coverage
80+
81+
This library aims to have full coverage of reachable lines and branches.
82+
83+
To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary):
84+
85+
$ ./configure --enable-coverage
86+
87+
Run the tests:
88+
89+
$ make check
90+
91+
To create a report, `gcovr` is recommended, as it includes branch coverage reporting:
92+
93+
$ gcovr --exclude 'src/bench*' --print-summary
94+
95+
To create a HTML report with coloured and annotated source code:
96+
97+
$ mkdir -p coverage
98+
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html
99+
100+
#### Exhaustive tests
101+
102+
There are tests of several functions in which a small group replaces secp256k1.
103+
These tests are *exhaustive* since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)).
104+
105+
### Benchmarks
106+
107+
See `src/bench*.c` for examples of benchmarks.

Makefile.am

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ noinst_HEADERS += src/field_10x26_impl.h
3939
noinst_HEADERS += src/field_5x52.h
4040
noinst_HEADERS += src/field_5x52_impl.h
4141
noinst_HEADERS += src/field_5x52_int128_impl.h
42-
noinst_HEADERS += src/field_5x52_asm_impl.h
4342
noinst_HEADERS += src/modinv32.h
4443
noinst_HEADERS += src/modinv32_impl.h
4544
noinst_HEADERS += src/modinv64.h

0 commit comments

Comments
 (0)