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 (void) base; (void) max_size;
146 *prealloc_ptr = (
unsigned char*)*prealloc_ptr + aligned_alloc_size;
151#if defined(SECP256K1_BUILD) && defined(VERIFY)
152# define SECP256K1_RESTRICT
154# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
155# if SECP256K1_GNUC_PREREQ(3,0)
156# define SECP256K1_RESTRICT __restrict__
157# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
158# define SECP256K1_RESTRICT __restrict
160# define SECP256K1_RESTRICT
163# define SECP256K1_RESTRICT restrict
168# define I64FORMAT "I64d"
169# define I64uFORMAT "I64u"
171# define I64FORMAT "lld"
172# define I64uFORMAT "llu"
176# define SECP256K1_GNUC_EXT __extension__
178# define SECP256K1_GNUC_EXT
182#if !defined(SECP256K1_LITTLE_ENDIAN) && !defined(SECP256K1_BIG_ENDIAN)
184# if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
185 defined(_X86_) || defined(__x86_64__) || defined(__i386__) || \
186 defined(__i486__) || defined(__i586__) || defined(__i686__) || \
187 defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) || \
188 defined(__ARMEL__) || defined(__AARCH64EL__) || \
189 (defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__ == 1) || \
190 (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN == 1) || \
191 defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM)
192# define SECP256K1_LITTLE_ENDIAN
194# if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
195 defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) || \
196 defined(__MICROBLAZEEB__) || defined(__ARMEB__) || defined(__AARCH64EB__) || \
197 (defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ == 1) || \
198 (defined(_BIG_ENDIAN) && _BIG_ENDIAN == 1)
199# define SECP256K1_BIG_ENDIAN
202#if defined(SECP256K1_LITTLE_ENDIAN) == defined(SECP256K1_BIG_ENDIAN)
203# error Please make sure that either SECP256K1_LITTLE_ENDIAN or SECP256K1_BIG_ENDIAN is set, see src/util.h.
208 unsigned char *p = (
unsigned char *)s;
212 volatile int vflag = flag;
213 unsigned char mask = -(
unsigned char) vflag;
227 const unsigned char *p1 = s1, *p2 = s2;
230 for (i = 0; i < n; i++) {
231 int diff = p1[i] - p2[i];
241 unsigned int mask0, mask1, r_masked, a_masked;
245 volatile int vflag = flag;
250 mask0 = (
unsigned int)vflag + ~0u;
252 r_masked = ((
unsigned int)*r & mask0);
253 a_masked = ((
unsigned int)*a & mask1);
255 *r = (int)(r_masked | a_masked);
261#if defined(USE_FORCE_WIDEMUL_INT128)
262# define SECP256K1_WIDEMUL_INT128 1
263#elif defined(USE_FORCE_WIDEMUL_INT64)
264# define SECP256K1_WIDEMUL_INT64 1
265#elif defined(UINT128_MAX) || defined(__SIZEOF_INT128__)
266# define SECP256K1_WIDEMUL_INT128 1
268# define SECP256K1_WIDEMUL_INT64 1
270#if defined(SECP256K1_WIDEMUL_INT128)
271# if !defined(UINT128_MAX) && defined(__SIZEOF_INT128__)
274#define UINT128_MAX ((uint128_t)(-1))
275#define INT128_MAX ((int128_t)(UINT128_MAX >> 1))
276#define INT128_MIN (-INT128_MAX - 1)
282#define __has_builtin(x) 0
289 static const uint8_t debruijn[32] = {
290 0x00, 0x01, 0x02, 0x18, 0x03, 0x13, 0x06, 0x19, 0x16, 0x04, 0x14, 0x0A,
291 0x10, 0x07, 0x0C, 0x1A, 0x1F, 0x17, 0x12, 0x05, 0x15, 0x09, 0x0F, 0x0B,
292 0x1E, 0x11, 0x08, 0x0E, 0x1D, 0x0D, 0x1C, 0x1B
294 return debruijn[((x & -x) * 0x04D7651F) >> 27];
301 static const uint8_t debruijn[64] = {
302 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
303 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
304 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
305 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
307 return debruijn[((x & -x) * 0x022FDD63CC95386D) >> 58];
313#if (__has_builtin(__builtin_ctz) || SECP256K1_GNUC_PREREQ(3,4))
315 if (((
unsigned)UINT32_MAX) == UINT32_MAX) {
316 return __builtin_ctz(x);
319#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4))
321 return __builtin_ctzl(x);
331#if (__has_builtin(__builtin_ctzl) || SECP256K1_GNUC_PREREQ(3,4))
333 if (((
unsigned long)UINT64_MAX) == UINT64_MAX) {
334 return __builtin_ctzl(x);
337#if (__has_builtin(__builtin_ctzll) || SECP256K1_GNUC_PREREQ(3,4))
339 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)