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>
19#include <botan/internal/value_barrier.h>
27template <std::
unsigned_
integral T>
30 return static_cast<T
>(0) - top;
36template <std::
unsigned_
integral T>
44template <std::
unsigned_
integral T>
50 const T a = ~x & (x - 1);
52 const size_t mask =
static_cast<size_t>(0) - a_top;
61template <std::
unsigned_
integral T>
63 return (arg != 0) && (arg != 1) && ((arg &
static_cast<T
>(arg - 1)) == 0);
72template <std::
unsigned_
integral T>
76 for(
size_t s = 8 *
sizeof(T) / 2; s > 0; s /= 2) {
93template <std::
unsigned_
integral T>
97 for(
size_t s = 8 *
sizeof(T) / 2; s >= 8; s /= 2) {
114template <std::
unsigned_
integral T>
122 for(
size_t s = 8 *
sizeof(T) / 2; s > 0; s /= 2) {
123 const T range = (
static_cast<T
>(1) << s) - 1;
133template <std::
unsigned_
integral T>
136 return static_cast<T
>(
high_bit(n) - 1);
139template <std::
unsigned_
integral T>
141 requires(
sizeof(T) < 32)
143 if(x >> (
sizeof(T) * 8 - 1)) {
144 return sizeof(T) * 8;
166template <std::
unsigned_
integral T>
168 return (a + b - 1) / b;
174template <std::
unsigned_
integral T>
176 return (bits + 7) / 8;
181#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_ctz)
185 return __builtin_ctz(n);
191template <std::
unsigned_
integral T>
197 const T swap = ((x >> shift) ^ x) & mask;
198 return (x ^ swap) ^ (swap << shift);
201template <std::
unsigned_
integral T>
203 const T swap = ((x >> shift) ^ y) & mask;
215template <std::
unsigned_
integral T>
218 return (b ^ (mask & (a ^ b)));
221template <std::
unsigned_
integral T>
232 return choose(a ^ b, c, b);
238template <std::
unsigned_
integral T>
240 auto extend = [](uint8_t m) -> T {
242 for(
size_t i = 0; i <
sizeof(T); ++i) {
243 mask |= T(m) << i * 8;
250 b = (b & extend(0xF0)) >> 4 | (b & extend(0x0F)) << 4;
251 b = (b & extend(0xCC)) >> 2 | (b & extend(0x33)) << 2;
252 b = (b & extend(0xAA)) >> 1 | (b & extend(0x55)) << 1;
272template <std::
unsigned_
integral T>
274 constexpr size_t s =
sizeof(T);
275 static_assert(s <= 8,
"T is not a suitable unsigned integer value");
276 if constexpr(s == 8) {
277 x = x - ((x >> 1) & 0x5555555555555555);
278 x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
279 x = (x + (x >> 4)) & 0xF0F0F0F0F0F0F0F;
280 return (x * 0x101010101010101) >> 56;
281 }
else if constexpr(s == 4) {
282 x = x - ((x >> 1) & 0x55555555);
283 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
284 x = (x + (x >> 4)) & 0x0F0F0F0F;
285 return (x * 0x01010101) >> 24;
305template <u
int8_t POLY, std::
unsigned_
integral T>
308 constexpr T lo_bit = (
static_cast<T
>(-1) / 255);
311 constexpr T mask =
static_cast<T
>(~(lo_bit << 7));
313 constexpr T poly = POLY;
316 while(x > 0 && y > 0) {
320 const T
carry = ((x >> 7) & lo_bit) * poly;
321 x = ((x & mask) << 1) ^
carry;
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_FORCE_INLINE
constexpr T value_barrier(T x)
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)
constexpr T poly_mul(T x, uint8_t y)
void carry(int64_t &h0, int64_t &h1)
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 T ct_expand_top_bit(T a)
BOTAN_FORCE_INLINE constexpr size_t ctz(T n)
BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x)