7#ifndef SECP256K1_UTIL_H
8#define SECP256K1_UTIL_H
10#if defined HAVE_CONFIG_H
11#include "libsecp256k1-config.h"
20 void (*fn)(
const char *text,
void* data);
25 cb->
fn(text, (
void*)cb->
data);
29#define TEST_FAILURE(msg) do { \
30 fprintf(stderr, "%s\n", msg); \
34#define TEST_FAILURE(msg) do { \
35 fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \
40#if SECP256K1_GNUC_PREREQ(3, 0)
41#define EXPECT(x,c) __builtin_expect((x),(c))
43#define EXPECT(x,c) (x)
47#define CHECK(cond) do { \
48 if (EXPECT(!(cond), 0)) { \
49 TEST_FAILURE("test condition failed"); \
53#define CHECK(cond) do { \
54 if (EXPECT(!(cond), 0)) { \
55 TEST_FAILURE("test condition failed: " #cond); \
62#define VERIFY_CHECK(check)
63#define VERIFY_SETUP(stmt)
65#define VERIFY_CHECK CHECK
66#define VERIFY_SETUP(stmt) do { stmt; } while(0)
68#define VERIFY_CHECK(cond) do { (void)(cond); } while(0)
69#define VERIFY_SETUP(stmt)
75# include <valgrind/memcheck.h>
76# define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y))
77# define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y))
86#define VG_CHECK_VERIFY(x,y) VG_CHECK((x), (y))
88#define VG_CHECK_VERIFY(x,y)
92 void *ret = malloc(size);
100 void *ret = realloc(ptr, size);
107#if defined(__BIGGEST_ALIGNMENT__)
108#define ALIGNMENT __BIGGEST_ALIGNMENT__
116#define ROUND_TO_ALIGN(size) ((((size) + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT)
140 VERIFY_CHECK((
unsigned char*)*prealloc_ptr >= (
unsigned char*)base);
142 VERIFY_CHECK((
unsigned char*)*prealloc_ptr - (
unsigned char*)base + aligned_alloc_size <= max_size);
144 *prealloc_ptr = (
unsigned char*)*prealloc_ptr + aligned_alloc_size;
149#if defined(SECP256K1_BUILD) && defined(VERIFY)
150# define SECP256K1_RESTRICT
152# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
153# if SECP256K1_GNUC_PREREQ(3,0)
154# define SECP256K1_RESTRICT __restrict__
155# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
156# define SECP256K1_RESTRICT __restrict
158# define SECP256K1_RESTRICT
161# define SECP256K1_RESTRICT restrict
166# define I64FORMAT "I64d"
167# define I64uFORMAT "I64u"
169# define I64FORMAT "lld"
170# define I64uFORMAT "llu"
174# define SECP256K1_GNUC_EXT __extension__
176# define SECP256K1_GNUC_EXT
180#if !defined(SECP256K1_LITTLE_ENDIAN) && !defined(SECP256K1_BIG_ENDIAN)
182# if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
183 defined(_X86_) || defined(__x86_64__) || defined(__i386__) || \
184 defined(__i486__) || defined(__i586__) || defined(__i686__) || \
185 defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) || \
186 defined(__ARMEL__) || defined(__AARCH64EL__) || \
187 (defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__ == 1) || \
188 (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN == 1) || \
189 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM)
190# define SECP256K1_LITTLE_ENDIAN
192# if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
193 defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) || \
194 defined(__MICROBLAZEEB__) || defined(__ARMEB__) || defined(__AARCH64EB__) || \
195 (defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ == 1) || \
196 (defined(_BIG_ENDIAN) && _BIG_ENDIAN == 1)
197# define SECP256K1_BIG_ENDIAN
200#if defined(SECP256K1_LITTLE_ENDIAN) == defined(SECP256K1_BIG_ENDIAN)
201# error Please make sure that either SECP256K1_LITTLE_ENDIAN or SECP256K1_BIG_ENDIAN is set, see src/util.h.
206 unsigned char *p = (
unsigned char *)s;
210 volatile int vflag = flag;
211 unsigned char mask = -(
unsigned char) vflag;
225 const unsigned char *p1 = s1, *p2 = s2;
228 for (i = 0; i < n; i++) {
229 int diff = p1[i] - p2[i];
239 unsigned int mask0, mask1, r_masked, a_masked;
243 volatile int vflag = flag;
248 mask0 = (
unsigned int)vflag + ~0u;
250 r_masked = ((
unsigned int)*r & mask0);
251 a_masked = ((
unsigned int)*a & mask1);
253 *r = (int)(r_masked | a_masked);
259#if defined(USE_FORCE_WIDEMUL_INT128)
260# define SECP256K1_WIDEMUL_INT128 1
261#elif defined(USE_FORCE_WIDEMUL_INT64)
262# define SECP256K1_WIDEMUL_INT64 1
263#elif defined(UINT128_MAX) || defined(__SIZEOF_INT128__)
264# define SECP256K1_WIDEMUL_INT128 1
266# define SECP256K1_WIDEMUL_INT64 1
268#if defined(SECP256K1_WIDEMUL_INT128)
269# if !defined(UINT128_MAX) && defined(__SIZEOF_INT128__)
272#define UINT128_MAX ((uint128_t)(-1))
273#define INT128_MAX ((int128_t)(UINT128_MAX >> 1))
274#define INT128_MIN (-INT128_MAX - 1)
280#define __has_builtin(x) 0
287 static const uint8_t debruijn[32] = {
288 0x00, 0x01, 0x02, 0x18, 0x03, 0x13, 0x06, 0x19, 0x16, 0x04, 0x14, 0x0A,
289 0x10, 0x07, 0x0C, 0x1A, 0x1F, 0x17, 0x12, 0x05, 0x15, 0x09, 0x0F, 0x0B,
290 0x1E, 0x11, 0x08, 0x0E, 0x1D, 0x0D, 0x1C, 0x1B
292 return debruijn[((x & -x) * 0x04D7651F) >> 27];
299 static const uint8_t debruijn[64] = {
300 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
301 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
302 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
303 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
305 return debruijn[((x & -x) * 0x022FDD63CC95386D) >> 58];
311#if (__has_builtin(__builtin_ctz) || SECP256K1_GNUC_PREREQ(3,4))
313 if (((
unsigned)UINT32_MAX) == UINT32_MAX) {
314 return __builtin_ctz(x);
317#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4))
319 return __builtin_ctzl(x);
329#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4))
331 if (((
unsigned long)UINT64_MAX) == UINT64_MAX) {
332 return __builtin_ctzl(x);
335#if (__has_builtin(__builtin_ctzll) || SECP256K1_GNUC_PREREQ(3,4))
337 return __builtin_ctzll(x);
static SECP256K1_INLINE int secp256k1_ctz64_var(uint64_t x)
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
static SECP256K1_INLINE void * manual_alloc(void **prealloc_ptr, size_t alloc_size, void *base, size_t max_size)
static SECP256K1_INLINE void secp256k1_int_cmov(int *r, const int *a, int flag)
If flag is true, set *r equal to *a; otherwise leave it.
#define SECP256K1_GNUC_EXT
#define ROUND_TO_ALIGN(size)
static SECP256K1_INLINE int secp256k1_ctz32_var(uint32_t x)
static SECP256K1_INLINE int secp256k1_ctz64_var_debruijn(uint64_t x)
static SECP256K1_INLINE void * checked_realloc(const secp256k1_callback *cb, void *ptr, size_t size)
#define VERIFY_CHECK(cond)
static SECP256K1_INLINE int secp256k1_ctz32_var_debruijn(uint32_t x)
static SECP256K1_INLINE void * checked_malloc(const secp256k1_callback *cb, size_t size)
static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag)
static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback *const cb, const char *const text)
void(* fn)(const char *text, void *data)