Suppress a harmless variable-time optimization by clang in _int_cmov
Follow up on 52a03512c1d800603b5c923c1a28bdba12dadb30
This commit is contained in:
parent
5b196338f0
commit
67a429f31f
@ -197,10 +197,15 @@ static SECP256K1_INLINE void memczero(void *s, size_t len, int flag) {
|
|||||||
/** 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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user