Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/util.h
Show First 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | while (len) { | ||||
p++; | p++; | ||||
len--; | len--; | ||||
} | } | ||||
} | } | ||||
/** 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. | |||||
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 */ | /* Casting a negative int to unsigned and back to int is implementation defined behavior */ | ||||
VERIFY_CHECK(*r >= 0 && *a >= 0); | VERIFY_CHECK(*r >= 0 && *a >= 0); | ||||
mask0 = (unsigned int)flag + ~0u; | mask0 = (unsigned int)vflag + ~0u; | ||||
mask1 = ~mask0; | mask1 = ~mask0; | ||||
r_masked = ((unsigned int)*r & mask0); | r_masked = ((unsigned int)*r & mask0); | ||||
a_masked = ((unsigned int)*a & mask1); | a_masked = ((unsigned int)*a & mask1); | ||||
*r = (int)(r_masked | a_masked); | *r = (int)(r_masked | a_masked); | ||||
} | } | ||||
#endif /* SECP256K1_UTIL_H */ | #endif /* SECP256K1_UTIL_H */ |