Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
26166c4
ecmult_multi: reduce strauss memory usage by 30%
jonasnick Oct 17, 2025
153eea2
bench: Use `ALIGNMENT` macro instead of hardcoded value
hebasto Oct 27, 2025
2f73e52
group: Avoid using infinity field directly in other modules
real-or-random Oct 28, 2025
115b135
Merge bitcoin-core/secp256k1#1763: bench: Use `ALIGNMENT` macro inste…
real-or-random Nov 6, 2025
f252da7
ci: Use Python virtual environment in "x86_64-macos-native" job
hebasto Nov 7, 2025
c8206b1
Merge bitcoin-core/secp256k1#1771: ci: Use Python virtual environment…
real-or-random Nov 7, 2025
fc7458c
introduce `secp256k1_eckey_pubkey_serialize{33,65}` functions
theStack Nov 17, 2025
adb76f8
use new `_eckey_pubkey_serialize{33,65}` functions in public API
theStack Nov 17, 2025
0d3659c
use new `_eckey_pubkey_serialize{33,65}` functions in modules (ellswi…
theStack Nov 17, 2025
f5e815f
remove secp256k1_eckey_pubkey_serialize function
theStack Nov 17, 2025
b6c2a3c
Merge bitcoin-core/secp256k1#1761: ecmult_multi: reduce strauss memor…
real-or-random Nov 18, 2025
e7f7083
Merge bitcoin-core/secp256k1#1774: refactor: split up internal pubkey…
real-or-random Nov 27, 2025
3b5b03f
doc/bench: Added cmake build options to bench error messages
kevkevinpal Dec 4, 2025
5a08c1b
Add ARG_CHECKs to ensure "array of pointers" elements are non-NULL
theStack Dec 6, 2025
8bcda18
test: Add non-NULL checks for "pointer of array" API functions
theStack Dec 9, 2025
3daab83
refactor: remove ret from secp256k1_ec_pubkey_serialize
kevkevinpal Dec 9, 2025
be5e4f0
Merge bitcoin-core/secp256k1#1779: Add ARG_CHECKs to ensure "array of…
real-or-random Dec 10, 2025
5c75183
Merge bitcoin-core/secp256k1#1784: refactor: remove ret from secp256k…
real-or-random Dec 10, 2025
ae00c55
Add VERIFY_CHECKs that flags are 0 or 1
john-moffett Dec 9, 2025
d822b29
test: split monolithic ellswift test into independent cases
furszy Dec 14, 2025
540fec8
Merge bitcoin-core/secp256k1#1788: test: split monolithic ellswift te…
real-or-random Dec 15, 2025
aa2a39c
Merge bitcoin-core/secp256k1#1778: doc/bench: Added cmake build optio…
real-or-random Dec 15, 2025
8d44573
Merge bitcoin-core/secp256k1#1783: Add VERIFY_CHECKs and documentatio…
real-or-random Dec 15, 2025
0406cfc
doc: include arg -DUSE_EXTERNAL_DEFAULT_CALLBACKS=1 for cmake
kevkevinpal Dec 19, 2025
f9a944f
Merge bitcoin-core/secp256k1#1790: doc: include arg -DSECP256K1_USE_E…
real-or-random Dec 19, 2025
2d9137c
Merge bitcoin-core/secp256k1#1764: group: Avoid using infinity field …
real-or-random Jan 6, 2026
bd5ced1
doc/bench: added help text for SECP256K1_BENCH_ITERS env var for benc…
kevkevinpal Dec 30, 2025
4721e07
Merge bitcoin-core/secp256k1#1793: doc/bench: added help text for SEC…
jonasnick Jan 11, 2026
29ac4d8
sage: verify Eisenstein integer connection for GLV constants
Justsomebuddy Jan 14, 2026
471e3a1
Merge bitcoin-core/secp256k1#1800: sage: verify Eisenstein integer co…
real-or-random Jan 21, 2026
c09215f
bench: fail early if user inputs invalid value for SECP256K1_BENCH_ITERS
kevkevinpal Jan 8, 2026
ebb3588
Merge bitcoin-core/secp256k1#1796: bench: fail early if user inputs i…
real-or-random Jan 23, 2026
c4b6a81
changelog: update in preparation for the v0.7.1 release
jonasnick Jan 26, 2026
20a209f
release: prepare for 0.7.1
jonasnick Jan 26, 2026
1a53f49
Merge bitcoin-core/secp256k1#1808: Prepare for 0.7.1
sipa Jan 26, 2026
ae7eb72
release cleanup: bump version after 0.7.1
jonasnick Jan 26, 2026
c7a5240
Merge bitcoin-core/secp256k1#1809: release cleanup: bump version afte…
sipa Jan 26, 2026
07d4de6
Merge commits '115b135f c8206b1c b6c2a3cd e7f7083b be5e4f02 5c751833 …
mllwchrry Mar 2, 2026
2542b43
modules: Port bitcoin-core/secp256k1#1774 to zkp-specific code
mllwchrry Mar 2, 2026
d8e87e4
unit_test: bump MAX_ARGS from 150 to 200
mllwchrry Mar 2, 2026
d111d31
generator: Port bitcoin-core/secp256k1#1779 to zkp-specific code
mllwchrry Mar 2, 2026
fe48cc9
generator: Port bitcoin-core/secp256k1#1764 to zkp-specific code
mllwchrry Mar 2, 2026
dc0bda5
bench: Port bitcoin-core/secp256k1#1796 to zkp-specific code
mllwchrry Mar 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,8 @@ jobs:
env: ${{ matrix.env_vars }}
run: ./ci/ci.sh

- name: Symbol check
- &SYMBOL_CHECK_MACOS
name: Symbol check
env:
VIRTUAL_ENV: '${{ github.workspace }}/venv'
run: |
Expand Down Expand Up @@ -595,17 +596,7 @@ jobs:
ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc

- *CI_SCRIPT_ON_HOST

- name: Symbol check
env:
VIRTUAL_ENV: '${{ github.workspace }}/venv'
run: |
python3 --version
python3 -m venv $VIRTUAL_ENV
export PATH="$VIRTUAL_ENV/bin:$PATH"
python3 -m pip install lief
python3 ./tools/symbol-check.py .libs/libsecp256k1.dylib

- *SYMBOL_CHECK_MACOS
- *PRINT_LOGS

win64-native:
Expand Down
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.7.1] - 2026-01-26

#### Changed
- Tests: Introduced a unit test framework with support for parallel test execution, selective test running, and named command-line arguments. Run `./tests -help` for usage information.

#### Fixed
- Increased the number of cases where the library attempts to clear secrets from the stack.
- build: Fixed x86_64 assembly feature check that could fail when user-provided `CFLAGS` included `-Werror`. This would cause the build to fall back to the slower C implementation instead of using the optimized x86_64 assembly.

#### ABI Compatibility
The ABI is backward compatible with version 0.7.0.

## [0.7.0] - 2025-07-21

#### Added
Expand Down Expand Up @@ -190,7 +202,8 @@ This version was in fact never released.
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
Therefore, this version number does not uniquely identify a set of source files.

[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.7.0...HEAD
[Unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.7.1...HEAD
[0.7.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.7.0...v0.7.1
[0.7.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.6.0...v0.7.0
[0.6.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.1...v0.6.0
[0.5.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.0...v0.5.1
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ project(libsecp256k1
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
# the API. All changes in experimental modules are treated as
# backwards-compatible and therefore at most increase the minor version.
VERSION 0.7.1
VERSION 0.7.2
DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
LANGUAGES C
Expand All @@ -22,7 +22,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
# All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision.
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 6)
set(${PROJECT_NAME}_LIB_VERSION_REVISION 1)
set(${PROJECT_NAME}_LIB_VERSION_REVISION 2)
set(${PROJECT_NAME}_LIB_VERSION_AGE 0)

#=============================
Expand Down
3 changes: 2 additions & 1 deletion include/secp256k1.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,8 @@ SECP256K1_API void secp256k1_context_destroy(
* writes the message to stderr and calls abort. This default callback can be
* replaced at link time if the preprocessor macro
* USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
* has been configured with --enable-external-default-callbacks. Then the
* has been configured with --enable-external-default-callbacks (GNU Autotools) or
* -DSECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS=ON (CMake). Then the
* following two symbols must be provided to link against:
* - void secp256k1_default_illegal_callback_fn(const char *message, void *data);
* - void secp256k1_default_error_callback_fn(const char *message, void *data);
Expand Down
9 changes: 9 additions & 0 deletions sage/gen_split_lambda_constants.sage
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ assert (A1 + A2)/2 < sqrt(N)
assert B1 < sqrt(N)
assert B2 < sqrt(N)

# Verify connection to Eisenstein integers Z[w] where w = (-1 + sqrt(-3))/2.
# The group order N factors as N = pi * conj(pi) in Z[w], where pi = A - B*w
# is an Eisenstein prime with norm A^2 + A*B + B^2. The GLV endomorphism
# eigenvalue LAMBDA equals B/A mod N, which is the image of w^2 under the
# isomorphism Z[w]/(pi) -> Z/NZ (since w -> A/B and (A/B)^2 = B/A in Z/NZ).
A_EIS, B_EIS = -B1, A1
assert A_EIS**2 + A_EIS*B_EIS + B_EIS**2 == N
assert Z(B_EIS / A_EIS) == LAMBDA

G1 = round((2**384)*B2/N)
G2 = round((2**384)*(-B1)/N)

Expand Down
17 changes: 11 additions & 6 deletions src/bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ int main(int argc, char** argv) {
bench_data data;

int d = argc == 1;
int default_iters = 20000;
int iters = get_iters(default_iters);

/* Check for invalid user arguments */
char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover",
Expand All @@ -188,6 +186,13 @@ int main(int argc, char** argv) {
size_t valid_args_size = sizeof(valid_args)/sizeof(valid_args[0]);
int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size);

int default_iters = 20000;
int iters = get_iters(default_iters);
if (iters == 0) {
help(default_iters);
return EXIT_FAILURE;
}

if (argc > 1) {
if (have_flag(argc, argv, "-h")
|| have_flag(argc, argv, "--help")
Expand All @@ -205,23 +210,23 @@ int main(int argc, char** argv) {
#ifndef ENABLE_MODULE_ECDH
if (have_flag(argc, argv, "ecdh")) {
fprintf(stderr, "./bench: ECDH module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-ecdh.\n\n");
fprintf(stderr, "See README.md for configuration instructions.\n\n");
return EXIT_FAILURE;
}
#endif

#ifndef ENABLE_MODULE_RECOVERY
if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) {
fprintf(stderr, "./bench: Public key recovery module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n");
fprintf(stderr, "See README.md for configuration instructions.\n\n");
return EXIT_FAILURE;
}
#endif

#ifndef ENABLE_MODULE_SCHNORRSIG
if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) {
fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n");
fprintf(stderr, "See README.md for configuration instructions.\n\n");
return EXIT_FAILURE;
}
#endif
Expand All @@ -231,7 +236,7 @@ int main(int argc, char** argv) {
have_flag(argc, argv, "encode") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_keygen") ||
have_flag(argc, argv, "ellswift_ecdh")) {
fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n");
fprintf(stderr, "See README.md for configuration instructions.\n\n");
return EXIT_FAILURE;
}
#endif
Expand Down
8 changes: 7 additions & 1 deletion src/bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,13 @@ static int have_invalid_args(int argc, char** argv, char** valid_args, size_t n)
static int get_iters(int default_iters) {
char* env = getenv("SECP256K1_BENCH_ITERS");
if (env) {
return strtol(env, NULL, 0);
char* endptr;
long int iters = strtol(env, &endptr, 0);
if (*endptr != '\0' || iters <= 0) {
printf("Error: Value of SECP256K1_BENCH_ITERS is not a positive integer: %s\n\n", env);
return 0;
}
return iters;
} else {
return default_iters;
}
Expand Down
3 changes: 3 additions & 0 deletions src/bench_bppp.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ static void bench_bppp(void* arg, int iters) {
int main(void) {
bench_bppp_data data;
int iters = get_iters(32);
if (iters == 0) {
return EXIT_FAILURE;
}

data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

Expand Down
20 changes: 15 additions & 5 deletions src/bench_ecmult.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@

#define POINTS 32768

static void help(char **argv) {
static void help(char **argv, int default_iters) {
printf("Benchmark EC multiplication algorithms\n");
printf("\n");
printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters);
printf("customized using the SECP256K1_BENCH_ITERS environment variable.\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");
Expand Down Expand Up @@ -308,15 +311,20 @@ int main(int argc, char **argv) {
int i, p;
size_t scratch_size;

int iters = get_iters(10000);
int default_iters = 10000;
int iters = get_iters(default_iters);
if (iters == 0) {
help(argv, default_iters);
return EXIT_FAILURE;
}

data.ecmult_multi = secp256k1_ecmult_multi_var;

if (argc > 1) {
if(have_flag(argc, argv, "-h")
|| have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) {
help(argv);
help(argv, default_iters);
return EXIT_SUCCESS;
} else if(have_flag(argc, argv, "pippenger_wnaf")) {
printf("Using pippenger_wnaf:\n");
Expand All @@ -328,13 +336,13 @@ int main(int argc, char **argv) {
printf("Using simple algorithm:\n");
} else {
fprintf(stderr, "%s: unrecognized argument '%s'.\n\n", argv[0], argv[1]);
help(argv);
help(argv, default_iters);
return EXIT_FAILURE;
}
}

data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16;
scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT;
if (!have_flag(argc, argv, "simple")) {
data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size);
} else {
Expand Down Expand Up @@ -381,6 +389,8 @@ int main(int argc, char **argv) {
run_ecmult_multi_bench(&data, i << p, 1, iters);
}
}
} else {
printf("Skipping some benchmarks due to SECP256K1_BENCH_ITERS <= 2\n");
}

if (data.scratch != NULL) {
Expand Down
3 changes: 3 additions & 0 deletions src/bench_generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ static void bench_generator_generate_blinded(void* arg, int iters) {
int main(void) {
bench_generator_t data;
int iters = get_iters(20000);
if (iters == 0) {
return EXIT_FAILURE;
}

data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

Expand Down
6 changes: 5 additions & 1 deletion src/bench_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,13 @@ static void bench_context(void* arg, int iters) {

int main(int argc, char **argv) {
bench_inv data;
int d = argc == 1; /* default */
int default_iters = 20000;
int iters = get_iters(default_iters);
int d = argc == 1; /* default */
if (iters == 0) {
help(default_iters);
return EXIT_FAILURE;
}

if (argc > 1) {
if (have_flag(argc, argv, "-h")
Expand Down
3 changes: 3 additions & 0 deletions src/bench_rangeproof.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ int main(void) {

data.min_bits = 32;
iters = data.min_bits*get_iters(32);
if (iters == 0) {
return EXIT_FAILURE;
}

run_benchmark("rangeproof_verify_bit", bench_rangeproof, bench_rangeproof_setup, NULL, &data, 10, iters);

Expand Down
3 changes: 3 additions & 0 deletions src/bench_whitelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ int main(void) {
size_t n_keys = 30;
secp256k1_scalar ssub;
int iters = get_iters(5);
if (iters == 0) {
return EXIT_FAILURE;
}

data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

Expand Down
5 changes: 4 additions & 1 deletion src/eckey.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
#include "ecmult_gen.h"

static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size);
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed);
/** Serialize a group element (that is not allowed to be infinity) to a compressed public key (33 bytes). */
static void secp256k1_eckey_pubkey_serialize33(secp256k1_ge *elem, unsigned char *pub33);
/** Serialize a group element (that is not allowed to be infinity) to an uncompressed public key (65 bytes). */
static void secp256k1_eckey_pubkey_serialize65(secp256k1_ge *elem, unsigned char *pub65);

static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak);
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak);
Expand Down
29 changes: 14 additions & 15 deletions src/eckey_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,23 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char
}
}

static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) {
VERIFY_CHECK(compressed == 0 || compressed == 1);
static void secp256k1_eckey_pubkey_serialize33(secp256k1_ge *elem, unsigned char *pub33) {
VERIFY_CHECK(!secp256k1_ge_is_infinity(elem));

if (secp256k1_ge_is_infinity(elem)) {
return 0;
}
secp256k1_fe_normalize_var(&elem->x);
secp256k1_fe_normalize_var(&elem->y);
secp256k1_fe_get_b32(&pub[1], &elem->x);
if (compressed) {
*size = 33;
pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN;
} else {
*size = 65;
pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED;
secp256k1_fe_get_b32(&pub[33], &elem->y);
}
return 1;
pub33[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN;
secp256k1_fe_get_b32(&pub33[1], &elem->x);
}

static void secp256k1_eckey_pubkey_serialize65(secp256k1_ge *elem, unsigned char *pub65) {
VERIFY_CHECK(!secp256k1_ge_is_infinity(elem));

secp256k1_fe_normalize_var(&elem->x);
secp256k1_fe_normalize_var(&elem->y);
pub65[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED;
secp256k1_fe_get_b32(&pub65[1], &elem->x);
secp256k1_fe_get_b32(&pub65[33], &elem->y);
}

static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) {
Expand Down
19 changes: 10 additions & 9 deletions src/ecmult_const_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,15 @@ static void secp256k1_ecmult_const_odd_multiples_table_globalz(secp256k1_ge *pre
secp256k1_fe neg_y; \
VERIFY_CHECK((n) < (1U << ECMULT_CONST_GROUP_SIZE)); \
VERIFY_CHECK(index < (1U << (ECMULT_CONST_GROUP_SIZE - 1))); \
/* Unconditionally set r->x = (pre)[m].x. r->y = (pre)[m].y. because it's either the correct one
/* Unconditionally set r->x = (pre)[m].x and r->y = (pre)[m].y because it's either the correct one
* or will get replaced in the later iterations, this is needed to make sure `r` is initialized. */ \
(r)->x = (pre)[m].x; \
(r)->y = (pre)[m].y; \
secp256k1_ge_set_xy((r), &(pre)[m].x, &(pre)[m].y); \
for (m = 1; m < ECMULT_CONST_TABLE_SIZE; m++) { \
/* This loop is used to avoid secret data in array indices. See
* the comment in ecmult_gen_impl.h for rationale. */ \
secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == index); \
secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == index); \
} \
(r)->infinity = 0; \
secp256k1_fe_negate(&neg_y, &(r)->y, 1); \
secp256k1_fe_cmov(&(r)->y, &neg_y, negative); \
} while(0)
Expand Down Expand Up @@ -375,11 +373,14 @@ static int secp256k1_ecmult_const_xonly(secp256k1_fe* r, const secp256k1_fe *n,

SECP256K1_FE_VERIFY_MAGNITUDE(&g, 2);

/* Compute base point P = (n*g, g^2), the effective affine version of (n*g, g^2, v), which has
* corresponding affine X coordinate n/d. */
secp256k1_fe_mul(&p.x, &g, n);
secp256k1_fe_sqr(&p.y, &g);
p.infinity = 0;
/* Compute base point P = (n*g, g^2), the effective affine version of
* (n*g, g^2, v), which has corresponding affine X coordinate n/d. */
{
secp256k1_fe x, y;
secp256k1_fe_mul(&x, &g, n);
secp256k1_fe_sqr(&y, &g);
secp256k1_ge_set_xy(&p, &x, &y);
}

/* Perform x-only EC multiplication of P with q. */
VERIFY_CHECK(!secp256k1_scalar_is_zero(q));
Expand Down
Loading