Alien-libsecp256k1
view release on metacpan or search on metacpan
libsecp256k1/src/util.h view on Meta::CPAN
#endif
/* ceil(x/y) for integers x > 0 and y > 0. Here, / denotes rational division. */
#define CEIL_DIV(x, y) (1 + ((x) - 1) / (y))
#define ROUND_TO_ALIGN(size) (CEIL_DIV(size, ALIGNMENT) * ALIGNMENT)
/* Macro for restrict, when available and not in a VERIFY build. */
#if defined(SECP256K1_BUILD) && defined(VERIFY)
# define SECP256K1_RESTRICT
#else
# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
# if SECP256K1_GNUC_PREREQ(3,0)
# define SECP256K1_RESTRICT __restrict__
# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
# define SECP256K1_RESTRICT __restrict
# else
# define SECP256K1_RESTRICT
# endif
# else
# define SECP256K1_RESTRICT restrict
# endif
#endif
#if defined(__GNUC__)
# define SECP256K1_GNUC_EXT __extension__
#else
# define SECP256K1_GNUC_EXT
#endif
/* Zero memory if flag == 1. Flag must be 0 or 1. Constant time. */
static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag) {
unsigned char *p = (unsigned char *)s;
/* Access flag with a volatile-qualified lvalue.
This prevents clang from figuring out (after inlining) that flag can
take only be 0 or 1, which leads to variable time code. */
volatile int vflag = flag;
unsigned char mask = -(unsigned char) vflag;
while (len) {
*p &= ~mask;
p++;
len--;
}
}
/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
static SECP256K1_INLINE void secp256k1_memclear(void *ptr, size_t len) {
#if defined(_MSC_VER)
/* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
SecureZeroMemory(ptr, len);
#elif defined(__GNUC__)
/* We use a memory barrier that scares the compiler away from optimizing out the memset.
*
* Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
* in BoringSSL (ISC License):
* As best as we can tell, this is sufficient to break any optimisations that
* might try to eliminate "superfluous" memsets.
* This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it
* is pretty efficient, because the compiler can still implement the memset() efficently,
* just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
* Yang et al. (USENIX Security 2017) for more background.
*/
memset(ptr, 0, len);
__asm__ __volatile__("" : : "r"(ptr) : "memory");
#else
void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
volatile_memset(ptr, 0, len);
#endif
#ifdef VERIFY
SECP256K1_CHECKMEM_UNDEFINE(ptr, len);
#endif
}
/** Semantics like memcmp. Variable-time.
*
* We use this to avoid possible compiler bugs with memcmp, e.g.
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189
*/
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n) {
const unsigned char *p1 = s1, *p2 = s2;
size_t i;
for (i = 0; i < n; i++) {
int diff = p1[i] - p2[i];
if (diff != 0) {
return diff;
}
}
return 0;
}
/* Return 1 if all elements of array s are 0 and otherwise return 0.
* Constant-time. */
static SECP256K1_INLINE int secp256k1_is_zero_array(const unsigned char *s, size_t len) {
unsigned char acc = 0;
int ret;
size_t i;
for (i = 0; i < len; i++) {
acc |= s[i];
}
ret = (acc == 0);
/* acc may contain secret values. Try to explicitly clear it. */
secp256k1_memclear(&acc, sizeof(acc));
return ret;
}
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized and non-negative.*/
static SECP256K1_INLINE void secp256k1_int_cmov(int *r, const int *a, int flag) {
unsigned int mask0, mask1, r_masked, a_masked;
/* Access flag with a volatile-qualified lvalue.
This prevents clang from figuring out (after inlining) that flag can
take only be 0 or 1, which leads to variable time code. */
volatile int vflag = flag;
/* Casting a negative int to unsigned and back to int is implementation defined behavior */
VERIFY_CHECK(*r >= 0 && *a >= 0);
mask0 = (unsigned int)vflag + ~0u;
mask1 = ~mask0;
r_masked = ((unsigned int)*r & mask0);
( run in 0.607 second using v1.01-cache-2.11-cpan-0d23b851a93 )