be8d9c262f Merge bitcoin-core/secp256k1#965: gen_context: Don't use any ASM aeece44599 gen_context: Don't use any ASM 7688a4f13a Merge bitcoin-core/secp256k1#963: "Schnorrsig API overhaul" fixups 90e83449b2 ci: Add C++ test f698caaff6 Use unsigned char consistently for byte arrays b5b8e7b719 Don't declare constants twice 769528f307 Don't use string literals for char arrays without NUL termination 2cc3cfa583 Fix -Wmissing-braces warning in clang 0440945fb5 Merge #844: schnorrsig API overhaul ec3aaa5014 Merge #960: tests_exhaustive: check the result of secp256k1_ecdsa_sign a1ee83c654 tests_exhaustive: check the result of secp256k1_ecdsa_sign 253f90cdeb Merge bitcoin-core/secp256k1#951: configure: replace AC_PATH_PROG to AC_CHECK_PROG 446d28d9de Merge bitcoin-core/secp256k1#944: Various improvements related to CFLAGS 0302138f75 ci: Make compiler warning into errors on CI b924e1e605 build: Ensure that configure's compile checks default to -O2 7939cd571c build: List *CPPFLAGS before *CFLAGS like on the compiler command line 595e8a35d8 build: Enable -Wcast-align=strict warning 07256267ff build: Use own variable SECP_CFLAGS instead of touching user CFLAGS 4866178dfc Merge bitcoin-core/secp256k1#955: Add random field multiply/square tests 75ce488c2a Merge bitcoin-core/secp256k1#959: tests: really test the non-var scalar inverse 41ed13942b tests: really test the non-var scalar inverse 5f6ceafcfa schnorrsig: allow setting MSGLEN != 32 in benchmark fdd06b7967 schnorrsig: add tests for sign_custom and varlen msg verification d8d806aaf3 schnorrsig: add extra parameter struct for sign_custom a0c3fc177f schnorrsig: allow signing and verification of variable length msgs 5a8e4991ad Add secp256k1_tagged_sha256 as defined in BIP-340 b6c0b72fb0 schnorrsig: remove noncefp args from sign; add sign_custom function bdf19f105c Add random field multiply/square tests 8ae56e33e7 Merge #879: Avoid passing out-of-bound pointers to 0-size memcpy a4642fa15e configure: replace AC_PATH_PROG to AC_CHECK_PROG 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 442cee5baf schnorrsig: add algolen argument to nonce_function_hardened df3bfa12c3 schnorrsig: clarify result of calling nonce_function_bip340 without data 99e8614812 README: mention schnorrsig module 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 9570f674cc Avoid passing out-of-bound pointers to 0-size memcpy git-subtree-dir: src/secp256k1 git-subtree-split: be8d9c262f46309d9b4165b0498b71d704aba8fe
5.1 KiB
libsecp256k1
Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1.
This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose.
Features:
- secp256k1 ECDSA signing/verification and key generation.
- Additive and multiplicative tweaking of secret/public keys.
- Serialization/parsing of secret keys, public keys, signatures.
- Constant time, constant memory access signing and public key generation.
- Derandomized ECDSA (via RFC6979 or with a caller provided function.)
- Very efficient implementation.
- Suitable for embedded systems.
- Optional module for public key recovery.
- Optional module for ECDH key exchange.
- Optional module for Schnorr signatures according to BIP-340 (experimental).
Experimental features have not received enough scrutiny to satisfy the standard of quality of this library but are made available for testing and review by the community. The APIs of these features should not be considered stable.
Implementation details
- General
- No runtime heap allocation.
- Extensive testing infrastructure.
- Structured to facilitate review and analysis.
- Intended to be portable to any system with a C89 compiler and uint64_t support.
- No use of floating types.
- Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
- Field operations
- Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
- Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys).
- Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan).
- Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
- Scalar operations
- Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
- Using 4 64-bit limbs (relying on __int128 support in the compiler).
- Using 8 32-bit limbs.
- Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
- Modular inverses (both field elements and scalars) based on safegcd with some modifications, and a variable-time variant (by Peter Dettman).
- Group operations
- Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
- Use addition between points in Jacobian and affine coordinates where possible.
- Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
- Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
- Point multiplication for verification (aP + bG).
- Use wNAF notation for point multiplicands.
- Use a much larger window for multiples of G, using precomputed multiples.
- Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
- Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
- Point multiplication for signing
- Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
- Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)
- Access the table with branch-free conditional moves so memory access is uniform.
- No data-dependent branches
- Optional runtime blinding which attempts to frustrate differential power analysis.
- The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.
Build steps
libsecp256k1 is built using autotools:
$ ./autogen.sh
$ ./configure
$ make
$ make check
$ sudo make install # optional
Exhaustive tests
$ ./exhaustive_tests
With valgrind, you might need to increase the max stack size:
$ valgrind --max-stackframe=2500000 ./exhaustive_tests
Test coverage
This library aims to have full coverage of the reachable lines and branches.
To create a test coverage report, configure with --enable-coverage
(use of GCC is necessary):
$ ./configure --enable-coverage
Run the tests:
$ make check
To create a report, gcovr
is recommended, as it includes branch coverage reporting:
$ gcovr --exclude 'src/bench*' --print-summary
To create a HTML report with coloured and annotated source code:
$ mkdir -p coverage
$ gcovr --exclude 'src/bench*' --html --html-details -o coverage/coverage.html
Reporting a vulnerability
See SECURITY.md