b7ebe6436cTest APIs of funcs that need an ecmult_gen ctx with static ctx (Jonas Nick)e82144edfbFixup skew before global Z fixup (Peter Dettman)40b624c90bAdd tests for _gej_cmov (Peter Dettman)8c13a9bfe1ECDH skews by 0 or 1 (Peter Dettman)1515099433Simpler and faster ecdh skew fixup (Peter Dettman)3d7cbafb5ftests: Fix test whose result is implementation-defined (Tim Ruffing)77a19750b4Use xoshiro256++ PRNG instead of RFC6979 in tests (Pieter Wuille)5f2efe684esecp256k1_testrand_int(2**N) -> secp256k1_testrand_bits(N) (Pieter Wuille)3ed0d02bf7doc: add CHANGELOG template (Jonas Nick)6f42dc16c8doc: add release_process.md (Jonas Nick)0bd3e4243cbuild: set library version to 0.0.0 explicitly (Jonas Nick)b4b02fd8c4build: change libsecp version from 0.1 to 0.1.0-pre (Jonas Nick)05e049b73cecmult: move `_ecmult_odd_multiples_table_globalz_windowa` (siv2r)b4ac1a1d5fci: Run valgrind/memcheck tasks with 2 CPUs (Tim Ruffing)e70acab601ci: Use Cirrus "greedy" flag to use idle CPU time when available (Tim Ruffing)d07e30176eci: Update brew on macOS (Tim Ruffing)22382f0ea0ci: Test different ecmult window sizes (Tim Ruffing)26a022a3a0ci: Remove STATICPRECOMPUTATION (Tim Ruffing)10461d8bd3precompute_ecmult: Always compute all tables up to default WINDOW_G (Tim Ruffing)1287786c7adoc: Add comment to top of field_10x26_impl.h (Elliott Jin)58da5bd589doc: Fix upper bounds + cleanup in field_5x52_impl.h comment (Elliott Jin)22d25c8e0aAdd another ecmult_multi test (Pieter Wuille)515e7953caImprove checks at top of _fe_negate methods (Peter Dettman)e05da9e480Fix c++ build (Pieter Wuille)c45386d994Cleanup preprocessor indentation in precompute{,d}_ecmult{,_gen} (Pieter Wuille)19d96e15f9Split off .c file from precomputed_ecmult.h (Pieter Wuille)1a6691adaeSplit off .c file from precomputed_ecmult_gen.h (Pieter Wuille)bb36331412Simplify precompute_ecmult_print_* (Pieter Wuille)38cd84a0cbCompute ecmult tables at runtime for tests_exhaustive (Pieter Wuille)e458ec26d6Move ecmult table computation code to separate file (Pieter Wuille)fc1bf9f15fSplit ecmult table computation and printing (Pieter Wuille)31feab053bRename function secp256k1_ecmult_gen_{create_prec -> compute}_table (Pieter Wuille)725370c3f2Rename ecmult_gen_prec -> ecmult_gen_compute_table (Pieter Wuille)075252c1b7Rename ecmult_static_pre_g -> precomputed_ecmult (Pieter Wuille)7cf47f72bcRename ecmult_gen_static_prec_table -> precomputed_ecmult_gen (Pieter Wuille)f95b8106d0Rename gen_ecmult_static_pre_g -> precompute_ecmult (Pieter Wuille)bae77685ebRename gen_ecmult_gen_static_prec_table -> precompute_ecmult_gen (Pieter Wuille)7dfceceea6build: Remove #undef hack for ASM in the precomputation programs (Tim Ruffing)bb36fe9be0ci: Test `make precomp` (Tim Ruffing)d94a37a20cbuild: Remove CC_FOR_BUILD stuff (Tim Ruffing)ad63bb4c29build: Prebuild and distribute ecmult_gen table (Tim Ruffing)ac49361ed0prealloc: Get rid of manual memory management for prealloc contexts (Tim Ruffing)6573c08f65ecmult_gen: Tidy precomputed file and save space (Tim Ruffing)5eba83f17cecmult_gen: Precompute tables for all values of ECMULT_GEN_PREC_BITS (Tim Ruffing)fdb33dd122refactor: Make PREC_BITS a parameter of ecmult_gen_build_prec_table (Tim Ruffing)a4875e30a6refactor: Move default callbacks to util.h (Tim Ruffing)4c94c55bcedoc: Remove obsolete hint for valgrind stack size (Tim Ruffing)5106226991exhaustive_tests: Fix with ecmult_gen table with custom generator (Tim Ruffing)e1a76530dbrefactor: Make generator a parameter of ecmult_gen_create_prec_table (Tim Ruffing)9ad09f6911refactor: Rename program that generates static ecmult_gen table (Tim Ruffing)8ae18f1ab3refactor: Rename file that contains static ecmult_gen table (Tim Ruffing)00d2fa116eecmult_gen: Make code consistent with comment (Tim Ruffing)3b0c2185eaecmult_gen: Simplify ecmult_gen context after making table static (Tim Ruffing)e43ba02cfcrefactor: Decouple table generation and ecmult_gen context (Tim Ruffing)22dc2c0a0decmult_gen: Move table creation to new file and force static prec (Tim Ruffing)099bad945eComment and check a parameter for inf in secp256k1_ecmult_const. (Russell O'Connor)6c0be857f8Verify that secp256k1_ge_set_gej_zinv does not operate on infinity. a->x and a->y should not be used if the infinity flag is set. (Russell O'Connor)5eb519e1f6ci: reduce TEST_ITERS in memcheck run (Pieter Wuille)e2cf77328aTest ecmult functions for all i*2^j for j=0..255 and odd i=1..255. (Pieter Wuille)c0cd7de6d4build: add -no-undefined to libtool LDFLAGS (fanquake)fe32a79d35build: pass win32-dll to LT_INIT (fanquake)7c7ce872a5build: Add a check that Valgrind actually supports a host platform (Hennadii Stepanov)592661c22fci: move test environment variable declaration to .cirrus.yml (siv2r)dcbe84b841bench: add --help option to bench. (siv2r)2b7c7497efbuild: replace backtick command substitution with $() (fanquake)60bf8890dfecmult: fix definition of STRAUSS_SCRATCH_OBJECTS (Jonas Nick)214042a170build: don't append valgrind CPPFLAGS if not installed (fanquake)812ff5c747doc: remove use of 0xa0 "no break space" (fanquake)dc9b6853b7doc: Minor fixes in safegcd_implementation.md (Elliott Jin)233297579dFix typos (Dimitris Apostolou)72de1359e9ci: Enable -g if we set CFLAGS manually (Tim Ruffing)16d132215crefactor: Use (int)&(int) in boolean context to avoid compiler warning (MarcoFalke)3b157c48eddoc: Suggest keys.openpgp.org as keyserver in SECURITY.md (Tim Ruffing)73a7472cd0doc: Replace apoelstra's GPG key by jonasnick's GPG key (Tim Ruffing)af6abcb3d0Make bench support selecting which benchmarks to run (Pieter Wuille)9f56bdf5b9Merge bench_schnorrsig into bench (Pieter Wuille)3208557ae1Merge bench_recover into bench (Pieter Wuille)855e18d8a8Merge bench_ecdh into bench (Pieter Wuille)2a7be678a6Combine bench_sign and bench_verify into single bench (Pieter Wuille)5324f8942dMake aux_rnd32==NULL behave identical to 0x0000..00. (Pieter Wuille)2888640132VERIFY_CHECK precondition for secp256k1_fe_set_int. (Russell O'Connor)d49011f54cMake _set_fe_int( . , 0 ) set magnitude to 0 (Tim Ruffing)23e2f66726bench: don't return 1 in have_flag() if argc = 1 (Jonas Nick)96b1ad2ea9bench_ecmult: improve clarity of output (Jonas Nick)b4b130678dcreate csv file from the benchmark output (siv2r)26a255beb6Shared benchmark format for command line and CSV outputs (siv2r)044d956305Fix G.y parity in sage code (Pieter Wuille)b53e0cd61fAvoid overly-wide multiplications (Peter Dettman)9be7b0f083Avoid computing out-of-bounds pointer. (Tim Ruffing)bc08599e77Remove OpenSSL testing support (Pieter Wuille)db4667d5e0Make aux_rand32 arg to secp256k1_schnorrsig_sign const (Pieter Wuille)189f6bcfefFix unused parameter warnings when building without VERIFY (Jonas Nick)d43993724dtests: remove `secp256k1_fe_verify` from tests.c and modify `secp256k1_fe_from_storage` to call `secp256k1_fe_verify` (siv2r) Pull request description: [bitcoin-core/secp256k1#986]: tests: remove `secp256k1_fe_verify` from tests.c and modify `_fe_from_storage` to call `_fe_verify` [bitcoin-core/secp256k1#987]: Fix unused parameter warnings when building without VERIFY [bitcoin-core/secp256k1#966]: Make aux_rand32 arg to secp256k1_schnorrsig_sign const [bitcoin-core/secp256k1#983]: [RFC] Remove OpenSSL testing support [bitcoin-core/secp256k1#952]: Avoid computing out-of-bounds pointer. [bitcoin-core/secp256k1#810]: Avoid overly-wide multiplications in 5x52 field mul/sqr [bitcoin-core/secp256k1#996]: Fix G.y parity in sage code [bitcoin-core/secp256k1#989]: Shared benchmark format for command line and CSV outputs [bitcoin-core/secp256k1#999]: bench_ecmult: improve clarity of output [bitcoin-core/secp256k1#943]: VERIFY_CHECK precondition for secp256k1_fe_set_int. [bitcoin-core/secp256k1#1002]: Make aux_rnd32==NULL behave identical to 0x0000..00. [bitcoin-core/secp256k1#991]: Merge all "external" benchmarks into a single bench binary [bitcoin-core/secp256k1#1007]: doc: Replace apoelstra's GPG key by jonasnick's GPG key [bitcoin-core/secp256k1#1009]: refactor: Use (int)&(int) in boolean context to avoid compiler warning [bitcoin-core/secp256k1#1011]: ci: Enable -g if we set CFLAGS manually [bitcoin-core/secp256k1#1012]: Fix typos [bitcoin-core/secp256k1#1010]: doc: Minor fixes in safegcd_implementation.md [bitcoin-core/secp256k1#1020]: doc: remove use of <0xa0> "no break space" [bitcoin-core/secp256k1#1019]: build: don't append valgrind CPPFLAGS if not installed (macOS) [bitcoin-core/secp256k1#1004]: ecmult: fix definition of STRAUSS_SCRATCH_OBJECTS [bitcoin-core/secp256k1#1025]: build: replace backtick command substitution with $() [bitcoin-core/secp256k1#1008]: bench.c: add `--help` option and ci: move env variables [bitcoin-core/secp256k1#1027]: build: Add a check that Valgrind actually supports a host platform [bitcoin-core/secp256k1#1022]: build: Windows DLL additions [bitcoin-core/secp256k1#920]: Test all ecmult functions with many j*2^i combinations [bitcoin-core/secp256k1#942]: Verify that secp256k1_ge_set_gej_zinv does not operate on infinity. [bitcoin-core/secp256k1#988]: Make signing table fully static [bitcoin-core/secp256k1#1042]: Follow-ups to making all tables fully static [bitcoin-core/secp256k1#816]: Improve checks at top of _fe_negate methods [bitcoin-core/secp256k1#1044]: Add another ecmult_multi test [bitcoin-core/secp256k1#1030]: doc: Fix upper bounds + cleanup in field_5x52_impl.h comment [bitcoin-core/secp256k1#1047]: ci: Various improvements [bitcoin-core/secp256k1#1053]: ecmult: move `_ecmult_odd_multiples_table_globalz_windowa` [bitcoin-core/secp256k1#964]: Add release-process.md [bitcoin-core/secp256k1#1052]: Use xoshiro256++ instead of RFC6979 for tests [bitcoin-core/secp256k1#1054]: tests: Fix test whose result is implementation-defined [bitcoin-core/secp256k1#1029]: Simpler and faster ecdh skew fixup This PR can be recreated with `./contrib/sync-upstream.sh range a1102b12196ea27f44d6201de4d25926a2ae9640`. ACKs for top commit: apoelstra: utACKb7ebe6436creal-or-random: ACKb7ebe6436cdiff looks good. tested on my machine, also on valgrind. Tree-SHA512: 8b01347bbb9ac35cb93df628eaaf2a997fc8182046588bccc48a0623e9595d40cad2d46102a9c62c819ff77069331f344361138fd8ad0afc81bba9c1690bb541
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).
- Optional module for ECDSA adaptor signatures (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 # run the test suite
$ sudo make install # optional
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
Benchmark
If configured with --enable-benchmark (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build.
To print the benchmark result to the command line:
$ ./bench_name
To create a CSV file for the benchmark result :
$ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv
Reporting a vulnerability
See SECURITY.md