Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/util.h
Show First 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | static SECP256K1_INLINE void memczero(void *s, size_t len, int flag) { | ||||
unsigned char mask = -(unsigned char) vflag; | unsigned char mask = -(unsigned char) vflag; | ||||
while (len) { | while (len) { | ||||
*p &= ~mask; | *p &= ~mask; | ||||
p++; | p++; | ||||
len--; | len--; | ||||
} | } | ||||
} | } | ||||
/** 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; | |||||
} | |||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized and non-negative.*/ | /** 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) { | static SECP256K1_INLINE void secp256k1_int_cmov(int *r, const int *a, int flag) { | ||||
unsigned int mask0, mask1, r_masked, a_masked; | unsigned int mask0, mask1, r_masked, a_masked; | ||||
/* Access flag with a volatile-qualified lvalue. | /* Access flag with a volatile-qualified lvalue. | ||||
This prevents clang from figuring out (after inlining) that flag can | This prevents clang from figuring out (after inlining) that flag can | ||||
take only be 0 or 1, which leads to variable time code. */ | take only be 0 or 1, which leads to variable time code. */ | ||||
volatile int vflag = flag; | volatile int vflag = flag; | ||||
Show All 29 Lines |