constant-time: Add 64-bit versions of the helpers
While we could use _Generic() C11 expression to let the compiler select between the different versions, this only allows selection based on one of the arguments, which seems a bit fragile. So make this explicit for now. In the future we might consider using the overloadable attribute.
This commit is contained in:
@@ -36,6 +36,18 @@ static inline u_int constant_time_neq(uint32_t x, uint32_t y)
|
|||||||
return ((x-y) | (y-x)) >> 31;
|
return ((x-y) | (y-x)) >> 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given values are not equal in constant time.
|
||||||
|
*
|
||||||
|
* @param x first value to check
|
||||||
|
* @param y second value to check
|
||||||
|
* @return 1 if values are not equal, 0 otherwise
|
||||||
|
*/
|
||||||
|
static inline u_int constant_time_neq64(uint64_t x, uint64_t y)
|
||||||
|
{
|
||||||
|
return ((x-y) | (y-x)) >> 63;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given values are equal in constant time.
|
* Check if the given values are equal in constant time.
|
||||||
*
|
*
|
||||||
@@ -48,6 +60,18 @@ static inline u_int constant_time_eq(uint32_t x, uint32_t y)
|
|||||||
return 1 ^ constant_time_neq(x, y);
|
return 1 ^ constant_time_neq(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given values are equal in constant time.
|
||||||
|
*
|
||||||
|
* @param x first value to check
|
||||||
|
* @param y second value to check
|
||||||
|
* @return 1 if values are equal, 0 otherwise
|
||||||
|
*/
|
||||||
|
static inline u_int constant_time_eq64(uint64_t x, uint64_t y)
|
||||||
|
{
|
||||||
|
return 1 ^ constant_time_neq64(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare the two values and return 1 if the first argument is lower than
|
* Compare the two values and return 1 if the first argument is lower than
|
||||||
* the second in constant time.
|
* the second in constant time.
|
||||||
@@ -61,6 +85,19 @@ static inline u_int constant_time_lt(uint32_t x, uint32_t y)
|
|||||||
return (x ^ ((x^y) | ((x-y) ^ y))) >> 31;
|
return (x ^ ((x^y) | ((x-y) ^ y))) >> 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the two values and return 1 if the first argument is lower than
|
||||||
|
* the second in constant time.
|
||||||
|
*
|
||||||
|
* @param x first value to check
|
||||||
|
* @param y second value to check
|
||||||
|
* @return 1 if first value is lower than second
|
||||||
|
*/
|
||||||
|
static inline u_int constant_time_lt64(uint64_t x, uint64_t y)
|
||||||
|
{
|
||||||
|
return (x ^ ((x^y) | ((x-y) ^ y))) >> 63;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare the two values and return 1 if the first argument greater or equal to
|
* Compare the two values and return 1 if the first argument greater or equal to
|
||||||
* the second in constant time.
|
* the second in constant time.
|
||||||
@@ -74,6 +111,19 @@ static inline u_int constant_time_ge(uint32_t x, uint32_t y)
|
|||||||
return 1 ^ constant_time_lt(x, y);
|
return 1 ^ constant_time_lt(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the two values and return 1 if the first argument greater or equal to
|
||||||
|
* the second in constant time.
|
||||||
|
*
|
||||||
|
* @param x first value to check
|
||||||
|
* @param y second value to check
|
||||||
|
* @return 1 if first value is greater or equal to the second
|
||||||
|
*/
|
||||||
|
static inline u_int constant_time_ge64(uint64_t x, uint64_t y)
|
||||||
|
{
|
||||||
|
return 1 ^ constant_time_lt64(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a 32-bit all bit-set mask if the given value is not 0.
|
* Return a 32-bit all bit-set mask if the given value is not 0.
|
||||||
*
|
*
|
||||||
@@ -85,6 +135,17 @@ static inline uint32_t constant_time_mask(uint32_t x)
|
|||||||
return -(uint32_t)constant_time_neq(x, 0);
|
return -(uint32_t)constant_time_neq(x, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a 64-bit all bit-set mask if the given value is not 0.
|
||||||
|
*
|
||||||
|
* @param x value to check
|
||||||
|
* @return 0xffffffffffffffff if value is != 0, 0 otherwise
|
||||||
|
*/
|
||||||
|
static inline uint64_t constant_time_mask64(uint64_t x)
|
||||||
|
{
|
||||||
|
return -(uint64_t)constant_time_neq64(x, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select one of two values depending on whether the condition is != 0 or not.
|
* Select one of two values depending on whether the condition is != 0 or not.
|
||||||
* Basically equivalent to 'c ? x : y'.
|
* Basically equivalent to 'c ? x : y'.
|
||||||
@@ -100,4 +161,19 @@ static inline uint32_t constant_time_select(uint32_t x, uint32_t y, uint32_t c)
|
|||||||
return (x & m) | (y & ~m);
|
return (x & m) | (y & ~m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select one of two values depending on whether the condition is != 0 or not.
|
||||||
|
* Basically equivalent to 'c ? x : y'.
|
||||||
|
*
|
||||||
|
* @param x first value to select
|
||||||
|
* @param y second value to select
|
||||||
|
* @param c condition
|
||||||
|
* @return x if c is != 0, y otherwise
|
||||||
|
*/
|
||||||
|
static inline uint64_t constant_time_select64(uint64_t x, uint64_t y, uint64_t c)
|
||||||
|
{
|
||||||
|
uint64_t m = constant_time_mask64(c);
|
||||||
|
return (x & m) | (y & ~m);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /** CONSTANT_TIME_H_ @} */
|
#endif /** CONSTANT_TIME_H_ @} */
|
||||||
|
|||||||
Reference in New Issue
Block a user