mirror of
https://github.com/bitcoin-core/secp256k1.git
synced 2026-07-21 14:43:37 +00:00
field: force-inline 5x52 mul and sqr
The 5x52 field multiplication and squaring routines are hot in group arithmetic and scalar multiplication. Use the new `SECP256K1_FORCE_INLINE` for the thin wrappers and `int128` inner helpers so compilers can schedule the 64x64->128 arithmetic without a call boundary. Across the measured GCC and MSVC Release builds, this improves ECDSA verification by 0.6% to 9.1%, ECDH by 0.7% to 9.3%, and Schnorr verification by 0.6% to 9.6%. The direct field benchmarks generally show the intended effect on field squaring and multiplication, while Clang results are mostly flat and less consistently positive. This is a code-size tradeoff: the tested static library builds grew by about 4.6% to 4.7%, and the tested Windows Release DLL grew by 14.1%. Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com> Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Co-authored-by: Tim Ruffing <crypto@timruffing.de>
This commit is contained in:
@@ -147,6 +147,8 @@ if(MSVC)
|
||||
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
|
||||
# Match GCC/Clang's size-optimization macro for the inline guard
|
||||
add_compile_definitions($<$<CONFIG:MinSizeRel>:__OPTIMIZE_SIZE__=1>)
|
||||
else()
|
||||
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
|
||||
@@ -338,11 +338,11 @@ SECP256K1_INLINE static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp25
|
||||
r->n[4] += a->n[4];
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) {
|
||||
SECP256K1_FORCE_INLINE static void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) {
|
||||
secp256k1_fe_mul_inner(r->n, a->n, b->n);
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
|
||||
SECP256K1_FORCE_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
|
||||
secp256k1_fe_sqr_inner(r->n, a->n);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0)
|
||||
#define VERIFY_BITS_128(x, n) VERIFY_CHECK(secp256k1_u128_check_bits((x), (n)))
|
||||
|
||||
SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) {
|
||||
SECP256K1_FORCE_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) {
|
||||
secp256k1_uint128 c, d;
|
||||
uint64_t t3, t4, tx, u0;
|
||||
uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4];
|
||||
@@ -151,7 +151,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t
|
||||
/* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) {
|
||||
SECP256K1_FORCE_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) {
|
||||
secp256k1_uint128 c, d;
|
||||
uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4];
|
||||
uint64_t t3, t4, tx, u0;
|
||||
|
||||
+11
@@ -57,6 +57,17 @@ static void print_buf_plain(const unsigned char *buf, size_t len) {
|
||||
# define SECP256K1_INLINE inline
|
||||
# endif
|
||||
|
||||
# if !defined(_DEBUG) && !defined(__NO_INLINE__) && !defined(__OPTIMIZE_SIZE__)
|
||||
# if defined(__OPTIMIZE__) && (SECP256K1_GNUC_PREREQ(3, 0) || defined(__clang__))
|
||||
# define SECP256K1_FORCE_INLINE SECP256K1_INLINE __attribute__((always_inline))
|
||||
# elif defined(_MSC_VER)
|
||||
# define SECP256K1_FORCE_INLINE __forceinline
|
||||
# endif
|
||||
# endif
|
||||
# ifndef SECP256K1_FORCE_INLINE
|
||||
# define SECP256K1_FORCE_INLINE SECP256K1_INLINE
|
||||
# endif
|
||||
|
||||
/** Assert statically that expr is true.
|
||||
*
|
||||
* This is a statement-like macro and can only be used inside functions.
|
||||
|
||||
Reference in New Issue
Block a user