Skip to content

Commit cbd2555

Browse files
Merge #1209: build: Add SECP256K1_API_VAR to fix importing variables from DLLs
e433034 ci: Shutdown wineserver whenever CI script exits (Tim Ruffing) 9a5a611 build: Suppress stupid MSVC linker warning (Tim Ruffing) 739c53b examples: Extend sig examples by call that uses static context (Tim Ruffing) 914276e build: Add SECP256K1_API_VAR to fix importing variables from DLLs (Tim Ruffing) Pull request description: ... and more Windows fixes, please see the individual commits. The fixed issues were discovered in #1198. ACKs for top commit: sipa: utACK e433034 hebasto: ACK e433034, tested on Windows using [CMake](#1113) (which means that the 3rd commit is reviewed only, but not tested). FWIW, `LNK4217` warnings have been indeed observed. Tree-SHA512: ce7845b106190cdc517988c30aaf2cc9f1d6da22904dfc5cb6bf4ee05f063929dc8b3038479e703b6cebac79d1c21d0c84560344d2478cb1c1740087383f40e3
2 parents 1b21aa5 + e433034 commit cbd2555

8 files changed

+55
-26
lines changed

.cirrus.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ task:
258258
# Set non-essential options that affect the CLI messages here.
259259
# (They depend on the user's taste, so we don't want to set them automatically in configure.ac.)
260260
CFLAGS: -nologo -diagnostics:caret
261-
LDFLAGS: -XCClinker -nologo -XCClinker -diagnostics:caret
261+
LDFLAGS: -Xlinker -Xlinker -Xlinker -nologo
262262
matrix:
263263
- name: "x86_64 (MSVC): Windows (Debian stable, Wine)"
264264
- name: "x86_64 (MSVC): Windows (Debian stable, Wine, int128_struct)"

ci/cirrus.sh

+2-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ print_environment
3434
# This speeds up jobs with many invocations of wine (e.g., ./configure with MSVC) tremendously.
3535
case "$WRAPPER_CMD" in
3636
*wine*)
37+
# Make sure to shutdown wineserver whenever we exit.
38+
trap "wineserver -k || true" EXIT INT HUP
3739
# This is apparently only reliable when we run a dummy command such as "hh.exe" afterwards.
3840
wineserver -p && wine hh.exe
3941
;;
@@ -111,9 +113,6 @@ then
111113
make precomp
112114
fi
113115

114-
# Shutdown wineserver again
115-
wineserver -k || true
116-
117116
# Check that no repo files have been modified by the build.
118117
# (This fails for example if the precomp files need to be updated in the repo.)
119118
git diff --exit-code

configure.ac

+6
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
115115
if test x"$GCC" != x"yes" && test x"$build_windows" = x"yes"; then
116116
SECP_TRY_APPEND_CFLAGS([-W2 -wd4146], $1) # Moderate warning level, disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned"
117117
SECP_TRY_APPEND_CFLAGS([-external:anglebrackets -external:W0], $1) # Suppress warnings from #include <...> files
118+
# We pass -ignore:4217 to the MSVC linker to suppress warning 4217 when
119+
# importing variables from a statically linked secp256k1.
120+
# (See the libtool manual, section "Windows DLLs" for background.)
121+
# Unfortunately, libtool tries to be too clever and strips "-Xlinker arg"
122+
# into "arg", so this will be " -Xlinker -ignore:4217" after stripping.
123+
LDFLAGS="-Xlinker -Xlinker -Xlinker -ignore:4217 $LDFLAGS"
118124
fi
119125
])
120126
SECP_TRY_APPEND_DEFAULT_CFLAGS(SECP_CFLAGS)

examples/ecdsa.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int main(void) {
3434
unsigned char compressed_pubkey[33];
3535
unsigned char serialized_signature[64];
3636
size_t len;
37-
int is_signature_valid;
37+
int is_signature_valid, is_signature_valid2;
3838
int return_val;
3939
secp256k1_pubkey pubkey;
4040
secp256k1_ecdsa_signature sig;
@@ -116,10 +116,18 @@ int main(void) {
116116
printf("Signature: ");
117117
print_hex(serialized_signature, sizeof(serialized_signature));
118118

119-
120119
/* This will clear everything from the context and free the memory */
121120
secp256k1_context_destroy(ctx);
122121

122+
/* Bonus example: if all we need is signature verification (and no key
123+
generation or signing), we don't need to use a context created via
124+
secp256k1_context_create(). We can simply use the static (i.e., global)
125+
context secp256k1_context_static. See its description in
126+
include/secp256k1.h for details. */
127+
is_signature_valid2 = secp256k1_ecdsa_verify(secp256k1_context_static,
128+
&sig, msg_hash, &pubkey);
129+
assert(is_signature_valid2 == is_signature_valid);
130+
123131
/* It's best practice to try to clear secrets from memory after using them.
124132
* This is done because some bugs can allow an attacker to leak memory, for
125133
* example through "out of bounds" array access (see Heartbleed), Or the OS

examples/schnorr.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ int main(void) {
2626
unsigned char auxiliary_rand[32];
2727
unsigned char serialized_pubkey[32];
2828
unsigned char signature[64];
29-
int is_signature_valid;
29+
int is_signature_valid, is_signature_valid2;
3030
int return_val;
3131
secp256k1_xonly_pubkey pubkey;
3232
secp256k1_keypair keypair;
@@ -135,6 +135,15 @@ int main(void) {
135135
/* This will clear everything from the context and free the memory */
136136
secp256k1_context_destroy(ctx);
137137

138+
/* Bonus example: if all we need is signature verification (and no key
139+
generation or signing), we don't need to use a context created via
140+
secp256k1_context_create(). We can simply use the static (i.e., global)
141+
context secp256k1_context_static. See its description in
142+
include/secp256k1.h for details. */
143+
is_signature_valid2 = secp256k1_schnorrsig_verify(secp256k1_context_static,
144+
signature, msg_hash, 32, &pubkey);
145+
assert(is_signature_valid2 == is_signature_valid);
146+
138147
/* It's best practice to try to clear secrets from memory after using them.
139148
* This is done because some bugs can allow an attacker to leak memory, for
140149
* example through "out of bounds" array access (see Heartbleed), Or the OS

include/secp256k1.h

+23-16
Original file line numberDiff line numberDiff line change
@@ -145,21 +145,28 @@ typedef int (*secp256k1_nonce_function)(
145145
# define SECP256K1_NO_BUILD
146146
#endif
147147

148-
/** At secp256k1 build-time DLL_EXPORT is defined when building objects destined
149-
* for a shared library, but not for those intended for static libraries.
150-
*/
151-
152-
#ifndef SECP256K1_API
153-
# if defined(_WIN32)
154-
# if defined(SECP256K1_BUILD) && defined(DLL_EXPORT)
155-
# define SECP256K1_API __declspec(dllexport)
156-
# else
157-
# define SECP256K1_API
148+
/* Symbol visibility. See libtool manual, section "Windows DLLs". */
149+
#if defined(_WIN32) && !defined(__GNUC__)
150+
# ifdef SECP256K1_BUILD
151+
# ifdef DLL_EXPORT
152+
# define SECP256K1_API __declspec (dllexport)
153+
# define SECP256K1_API_VAR extern __declspec (dllexport)
158154
# endif
159-
# elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
160-
# define SECP256K1_API __attribute__ ((visibility ("default")))
155+
# elif defined _MSC_VER
156+
# define SECP256K1_API
157+
# define SECP256K1_API_VAR extern __declspec (dllimport)
158+
# elif defined DLL_EXPORT
159+
# define SECP256K1_API __declspec (dllimport)
160+
# define SECP256K1_API_VAR extern __declspec (dllimport)
161+
# endif
162+
#endif
163+
#ifndef SECP256K1_API
164+
# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
165+
# define SECP256K1_API __attribute__ ((visibility ("default")))
166+
# define SECP256K1_API_VAR extern __attribute__ ((visibility ("default")))
161167
# else
162168
# define SECP256K1_API
169+
# define SECP256K1_API_VAR extern
163170
# endif
164171
#endif
165172

@@ -231,10 +238,10 @@ typedef int (*secp256k1_nonce_function)(
231238
*
232239
* It is highly recommended to call secp256k1_selftest before using this context.
233240
*/
234-
SECP256K1_API extern const secp256k1_context *secp256k1_context_static;
241+
SECP256K1_API_VAR const secp256k1_context *secp256k1_context_static;
235242

236243
/** Deprecated alias for secp256k1_context_static. */
237-
SECP256K1_API extern const secp256k1_context *secp256k1_context_no_precomp
244+
SECP256K1_API_VAR const secp256k1_context *secp256k1_context_no_precomp
238245
SECP256K1_DEPRECATED("Use secp256k1_context_static instead");
239246

240247
/** Perform basic self tests (to be used in conjunction with secp256k1_context_static)
@@ -631,10 +638,10 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize(
631638
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
632639
* extra entropy.
633640
*/
634-
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
641+
SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
635642

636643
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
637-
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default;
644+
SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_default;
638645

639646
/** Create an ECDSA signature.
640647
*

include/secp256k1_ecdh.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ typedef int (*secp256k1_ecdh_hash_function)(
2727

2828
/** An implementation of SHA256 hash function that applies to compressed public key.
2929
* Populates the output parameter with 32 bytes. */
30-
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
30+
SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
3131

3232
/** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256).
3333
* Populates the output parameter with 32 bytes. */
34-
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
34+
SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
3535

3636
/** Compute an EC Diffie-Hellman secret in constant time
3737
*

include/secp256k1_schnorrsig.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ typedef int (*secp256k1_nonce_function_hardened)(
6161
* Therefore, to create BIP-340 compliant signatures, algo must be set to
6262
* "BIP0340/nonce" and algolen to 13.
6363
*/
64-
SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
64+
SECP256K1_API_VAR const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
6565

6666
/** Data structure that contains additional arguments for schnorrsig_sign_custom.
6767
*

0 commit comments

Comments
 (0)