summaryrefslogtreecommitdiffstats
path: root/crypto/constant_time_locl.h
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/constant_time_locl.h')
-rw-r--r--crypto/constant_time_locl.h36
1 files changed, 34 insertions, 2 deletions
diff --git a/crypto/constant_time_locl.h b/crypto/constant_time_locl.h
index 0d3acd58b3..ccf7b62f5f 100644
--- a/crypto/constant_time_locl.h
+++ b/crypto/constant_time_locl.h
@@ -54,7 +54,7 @@ extern "C" {
#endif
/*
- * The following methods return a bitmask of all ones (0xff...f) for true
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
* and 0 for false. This is useful for choosing a value based on the result
* of a conditional in constant time. For example,
*
@@ -67,7 +67,7 @@ extern "C" {
* can be written as
*
* unsigned int lt = constant_time_lt(a, b);
- * c = a & lt | b & ~lt;
+ * c = constant_time_select(lt, a, b);
*/
/*
@@ -107,6 +107,21 @@ static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
/* Convenience method for getting an 8-bit mask. */
static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b);
+/*
+ * Returns (mask & a) | (~mask & b).
+ *
+ * When |mask| is all 1s or all 0s (as returned by the methods above),
+ * the select methods return either |a| (if |mask| is nonzero) or |b|
+ * (if |mask| is zero).
+ */
+static inline unsigned int constant_time_select(unsigned int mask,
+ unsigned int a, unsigned int b);
+/* Convenience method for unsigned chars. */
+static inline unsigned char constant_time_select_8(unsigned char mask,
+ unsigned char a, unsigned char b);
+/* Convenience method for signed integers. */
+static inline int constant_time_select_int(unsigned int mask, int a, int b);
+
static inline unsigned int constant_time_msb(unsigned int a)
{
return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
@@ -162,6 +177,23 @@ static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b)
return (unsigned char)(constant_time_eq(a, b));
}
+static inline unsigned int constant_time_select(unsigned int mask,
+ unsigned int a, unsigned int b)
+ {
+ return (mask & a) | (~mask & b);
+ }
+
+static inline unsigned char constant_time_select_8(unsigned char mask,
+ unsigned char a, unsigned char b)
+ {
+ return (unsigned char)(constant_time_select(mask, a, b));
+ }
+
+inline int constant_time_select_int(unsigned int mask, int a, int b)
+ {
+ return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+ }
+
#ifdef __cplusplus
}
#endif