diff options
author | Jack Lloyd <[email protected]> | 2018-09-07 17:16:02 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-09-07 17:23:16 -0400 |
commit | 63cbaf52e414b2ac138d1c95143a3238741df21c (patch) | |
tree | 266bb20924a2da9d7497e8d25f3ec71de8bed19a /src/lib/utils | |
parent | 643a4041bedc18b70dde1fc257c54d6415fd352b (diff) |
Optimize CT::is_zero, CT::expand_mask, CT::expand_top_bit
Diffstat (limited to 'src/lib/utils')
-rw-r--r-- | src/lib/utils/ct_utils.h | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/src/lib/utils/ct_utils.h b/src/lib/utils/ct_utils.h index 013267874..4fd06ec3d 100644 --- a/src/lib/utils/ct_utils.h +++ b/src/lib/utils/ct_utils.h @@ -15,6 +15,7 @@ #define BOTAN_TIMING_ATTACK_CM_H_ #include <botan/secmem.h> +#include <type_traits> #include <vector> #if defined(BOTAN_HAS_VALGRIND) @@ -74,6 +75,22 @@ inline void unpoison(T& p) #endif } +/* Mask generation */ + +template<typename T> +inline T expand_top_bit(T a) + { + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); + return static_cast<T>(0) - (a >> (sizeof(T)*8-1)); + } + +template<typename T> +inline T is_zero(T x) + { + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); + return expand_top_bit<T>(~x & (x - 1)); + } + /* * T should be an unsigned machine integer type * Expand to a mask used for other operations @@ -85,26 +102,14 @@ inline void unpoison(T& p) template<typename T> inline T expand_mask(T x) { - T r = x; - // First fold r down to a single bit - for(size_t i = 1; i != sizeof(T)*8; i *= 2) - { - r = r | static_cast<T>(r >> i); - } - r &= 1; - r = static_cast<T>(~(r - 1)); - return r; - } - -template<typename T> -inline T expand_top_bit(T a) - { - return expand_mask<T>(a >> (sizeof(T)*8-1)); + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); + return ~is_zero(x); } template<typename T> inline T select(T mask, T from0, T from1) { + static_assert(std::is_unsigned<T>::value, "unsigned integer type required"); return static_cast<T>((from0 & mask) | (from1 & ~mask)); } @@ -127,12 +132,6 @@ inline ValT val_or_zero(PredT pred_val, ValT val) } template<typename T> -inline T is_zero(T x) - { - return static_cast<T>(~expand_mask(x)); - } - -template<typename T> inline T is_equal(T x, T y) { return is_zero<T>(x ^ y); |