12#ifndef BOTAN_BIT_OPS_H_
13#define BOTAN_BIT_OPS_H_
15#include <botan/types.h>
17#include <botan/compiler.h>
18#include <botan/internal/bswap.h>
26template <std::
unsigned_
integral T>
28 return static_cast<T
>(0) - (a >> (
sizeof(T) * 8 - 1));
34template <std::
unsigned_
integral T>
42template <std::
unsigned_
integral T>
44 const T a = ~x & (x - 1);
45 const size_t mask =
static_cast<size_t>(0) -
static_cast<size_t>(a >> (
sizeof(T) * 8 - 1));
54template <std::
unsigned_
integral T>
56 return (arg != 0) && (arg != 1) && ((arg &
static_cast<T
>(arg - 1)) == 0);
65template <std::
unsigned_
integral T>
69 for(
size_t s = 8 *
sizeof(T) / 2; s > 0; s /= 2) {
86template <std::
unsigned_
integral T>
90 for(
size_t s = 8 *
sizeof(T) / 2; s >= 8; s /= 2) {
107template <std::
unsigned_
integral T>
115 for(
size_t s = 8 *
sizeof(T) / 2; s > 0; s /= 2) {
116 const T range = (
static_cast<T
>(1) << s) - 1;
126template <std::
unsigned_
integral T>
129 return static_cast<T
>(
high_bit(n) - 1);
132template <std::
unsigned_
integral T>
134 requires(
sizeof(T) < 32)
136 if(x >> (
sizeof(T) * 8 - 1)) {
137 return sizeof(T) * 8;
159template <std::
unsigned_
integral T>
161 return (a + b - 1) / b;
167template <std::
unsigned_
integral T>
169 return (bits + 7) / 8;
174#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_ctz)
178 return __builtin_ctz(n);
184template <std::
unsigned_
integral T>
190 const T swap = ((x >> shift) ^ x) & mask;
191 return (x ^ swap) ^ (swap << shift);
194template <std::
unsigned_
integral T>
196 const T swap = ((x >> shift) ^ y) & mask;
208template <std::
unsigned_
integral T>
211 return (b ^ (mask & (a ^ b)));
214template <std::
unsigned_
integral T>
225 return choose(a ^ b, c, b);
231template <std::
unsigned_
integral T>
233 auto extend = [](uint8_t m) -> T {
235 for(
size_t i = 0; i <
sizeof(T); ++i) {
236 mask |= T(m) << i * 8;
243 b = (b & extend(0xF0)) >> 4 | (b & extend(0x0F)) << 4;
244 b = (b & extend(0xCC)) >> 2 | (b & extend(0x33)) << 2;
245 b = (b & extend(0xAA)) >> 1 | (b & extend(0x55)) << 1;
265template <std::
unsigned_
integral T>
267 constexpr size_t s =
sizeof(T);
268 static_assert(s <= 8,
"T is not a suitable unsigned integer value");
269 if constexpr(s == 8) {
270 x = x - ((x >> 1) & 0x5555555555555555);
271 x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
272 x = (x + (x >> 4)) & 0xF0F0F0F0F0F0F0F;
273 return (x * 0x101010101010101) >> 56;
274 }
else if constexpr(s == 4) {
275 x = x - ((x >> 1) & 0x55555555);
276 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
277 x = (x + (x >> 4)) & 0x0F0F0F0F;
278 return (x * 0x01010101) >> 24;
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_FORCE_INLINE
BOTAN_FORCE_INLINE constexpr bool is_power_of_2(T arg)
BOTAN_FORCE_INLINE constexpr T floor_log2(T n)
BOTAN_FORCE_INLINE constexpr T ceil_division(T a, T b)
BOTAN_FORCE_INLINE constexpr T majority(T a, T b, T c)
BOTAN_FORCE_INLINE constexpr void swap_bits(T &x, T &y, T mask, size_t shift)
constexpr T ct_reverse_bits(T b)
BOTAN_FORCE_INLINE constexpr T bit_permute_step(T x, T mask, size_t shift)
BOTAN_FORCE_INLINE constexpr size_t var_ctz32(uint32_t n)
constexpr uint8_t ceil_log2(T x)
BOTAN_FORCE_INLINE constexpr size_t significant_bytes(T n)
constexpr T reverse_bytes(T x)
BOTAN_FORCE_INLINE constexpr T ceil_tobytes(T bits)
BOTAN_FORCE_INLINE constexpr uint8_t ct_popcount(T x)
BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b)
BOTAN_FORCE_INLINE constexpr size_t high_bit(T n)
BOTAN_FORCE_INLINE constexpr size_t ct_if_is_zero_ret(T x, size_t s)
BOTAN_FORCE_INLINE constexpr size_t ctz(T n)
BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x)
BOTAN_FORCE_INLINE constexpr T expand_top_bit(T a)