Skip to content

Commit ddf2b29

Browse files
Merge #1000: Synthetic int128 type.
a340d95 ci: add int128_struct tests (Jonas Nick) dceaa1f int128: Tidy #includes of int128.h and int128_impl.h (Tim Ruffing) 2914bcc Simulated int128 type. (Russell O'Connor) Pull request description: Abstracts the int128 type and provides an native version, if available, or a implements it using a pair of int64_t's. This is activated by setting the configuration flag `--with-test-override-wide-multiply=int128_struct`. The primary purpose of this PR is to take advantage of MSVC's [umulh](https://docs.microsoft.com/en-us/cpp/intrinsics/umulh?view=msvc-170) intrinsic that we can use to simulate an int128 type which MSVC does not have (AFAIU). This PR lays out the groundwork for this level of MSVC support, but doesn't include the configuration logic to enable it yet. For completeness, and implementation of `umulh` and `mulh` are also provided for compilers that support neither the intrinsic nor the int128 type (such as CompCert?). This also opens up the possibility of removing the 32-bit field and scalar implementations should that ever be desired. ACKs for top commit: sipa: ACK a340d95 jonasnick: ACK a340d95 Tree-SHA512: b4f2853fa3ab60ce9d77b4eaee1fd20c4b612850e19fcb3179d7e36986f420c6c4589ff72f0cf844f989584ace49a1cd23cca3f4e405dabefc8da647a0df679d
2 parents 86e3b38 + a340d95 commit ddf2b29

18 files changed

+814
-297
lines changed

.cirrus.yml

+10-7
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ task:
6868
- env: {WIDEMUL: int64, RECOVERY: yes}
6969
- env: {WIDEMUL: int64, ECDH: yes, SCHNORRSIG: yes}
7070
- env: {WIDEMUL: int128}
71+
- env: {WIDEMUL: int128_struct}
7172
- env: {WIDEMUL: int128, RECOVERY: yes, SCHNORRSIG: yes}
7273
- env: {WIDEMUL: int128, ECDH: yes, SCHNORRSIG: yes}
7374
- env: {WIDEMUL: int128, ASM: x86_64}
@@ -271,20 +272,22 @@ task:
271272
EXPERIMENTAL: yes
272273
SCHNORRSIG: yes
273274
CTIMETEST: no
275+
# Use a MinGW-w64 host to tell ./configure we're building for Windows.
276+
# This will detect some MinGW-w64 tools but then make will need only
277+
# the MSVC tools CC, AR and NM as specified below.
278+
HOST: x86_64-w64-mingw32
279+
CC: /opt/msvc/bin/x64/cl
280+
AR: /opt/msvc/bin/x64/lib
281+
NM: /opt/msvc/bin/x64/dumpbin -symbols -headers
274282
# Set non-essential options that affect the CLI messages here.
275283
# (They depend on the user's taste, so we don't want to set them automatically in configure.ac.)
276284
CFLAGS: -nologo -diagnostics:caret
277285
LDFLAGS: -XCClinker -nologo -XCClinker -diagnostics:caret
278-
# Use a MinGW-w64 host to tell ./configure we're building for Windows.
279-
# This will detect some MinGW-w64 tools but then make will need only
280-
# the MSVC tools CC, AR and NM as specified below.
281286
matrix:
282287
- name: "x86_64 (MSVC): Windows (Debian stable, Wine)"
288+
- name: "x86_64 (MSVC): Windows (Debian stable, Wine, int128_struct)"
283289
env:
284-
HOST: x86_64-w64-mingw32
285-
CC: /opt/msvc/bin/x64/cl
286-
AR: /opt/msvc/bin/x64/lib
287-
NM: /opt/msvc/bin/x64/dumpbin -symbols -headers
290+
WIDEMUL: int128_struct
288291
- name: "i686 (MSVC): Windows (Debian stable, Wine)"
289292
env:
290293
HOST: i686-w64-mingw32

Makefile.am

+6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ noinst_HEADERS += src/precomputed_ecmult.h
4848
noinst_HEADERS += src/precomputed_ecmult_gen.h
4949
noinst_HEADERS += src/assumptions.h
5050
noinst_HEADERS += src/util.h
51+
noinst_HEADERS += src/int128.h
52+
noinst_HEADERS += src/int128_impl.h
53+
noinst_HEADERS += src/int128_native.h
54+
noinst_HEADERS += src/int128_native_impl.h
55+
noinst_HEADERS += src/int128_struct.h
56+
noinst_HEADERS += src/int128_struct_impl.h
5157
noinst_HEADERS += src/scratch.h
5258
noinst_HEADERS += src/scratch_impl.h
5359
noinst_HEADERS += src/selftest.h

configure.ac

+8-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,11 @@ AC_ARG_ENABLE(external_default_callbacks,
175175
[SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])])
176176

177177
# Test-only override of the (autodetected by the C code) "widemul" setting.
178-
# Legal values are int64 (for [u]int64_t), int128 (for [unsigned] __int128), and auto (the default).
178+
# Legal values are:
179+
# * int64 (for [u]int64_t),
180+
# * int128 (for [unsigned] __int128),
181+
# * int128_struct (for int128 implemented as a structure),
182+
# * and auto (the default).
179183
AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_widemul=auto])
180184

181185
AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto],
@@ -285,6 +289,9 @@ fi
285289

286290
# Select wide multiplication implementation
287291
case $set_widemul in
292+
int128_struct)
293+
AC_DEFINE(USE_FORCE_WIDEMUL_INT128_STRUCT, 1, [Define this symbol to force the use of the structure for simulating (unsigned) int128 based wide multiplication])
294+
;;
288295
int128)
289296
AC_DEFINE(USE_FORCE_WIDEMUL_INT128, 1, [Define this symbol to force the use of the (unsigned) __int128 based wide multiplication implementation])
290297
;;

src/assumptions.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#include <limits.h>
1111

1212
#include "util.h"
13+
#if defined(SECP256K1_INT128_NATIVE)
14+
#include "int128_native.h"
15+
#endif
1316

1417
/* This library, like most software, relies on a number of compiler implementation defined (but not undefined)
1518
behaviours. Although the behaviours we require are essentially universal we test them specifically here to
@@ -55,7 +58,7 @@ struct secp256k1_assumption_checker {
5558

5659
/* To int64_t. */
5760
((int64_t)(uint64_t)0xB123C456D789E012ULL == (int64_t)-(int64_t)0x4EDC3BA928761FEEULL) &&
58-
#if defined(SECP256K1_WIDEMUL_INT128)
61+
#if defined(SECP256K1_INT128_NATIVE)
5962
((int64_t)(((uint128_t)0xA1234567B8901234ULL << 64) + 0xC5678901D2345678ULL) == (int64_t)-(int64_t)0x3A9876FE2DCBA988ULL) &&
6063
(((int64_t)(int128_t)(((uint128_t)0xB1C2D3E4F5A6B7C8ULL << 64) + 0xD9E0F1A2B3C4D5E6ULL)) == (int64_t)(uint64_t)0xD9E0F1A2B3C4D5E6ULL) &&
6164
(((int64_t)(int128_t)(((uint128_t)0xABCDEF0123456789ULL << 64) + 0x0123456789ABCDEFULL)) == (int64_t)(uint64_t)0x0123456789ABCDEFULL) &&
@@ -71,7 +74,7 @@ struct secp256k1_assumption_checker {
7174
((((int16_t)0xE9AC) >> 4) == (int16_t)(uint16_t)0xFE9A) &&
7275
((((int32_t)0x937C918A) >> 9) == (int32_t)(uint32_t)0xFFC9BE48) &&
7376
((((int64_t)0xA8B72231DF9CF4B9ULL) >> 19) == (int64_t)(uint64_t)0xFFFFF516E4463BF3ULL) &&
74-
#if defined(SECP256K1_WIDEMUL_INT128)
77+
#if defined(SECP256K1_INT128_NATIVE)
7578
((((int128_t)(((uint128_t)0xCD833A65684A0DBCULL << 64) + 0xB349312F71EA7637ULL)) >> 39) == (int128_t)(((uint128_t)0xFFFFFFFFFF9B0674ULL << 64) + 0xCAD0941B79669262ULL)) &&
7679
#endif
7780
1) * 2 - 1];

0 commit comments

Comments
 (0)