Botan 3.9.0
Crypto and TLS for C&
Botan::bitvector_base< AllocatorT > Class Template Reference

#include <bitvector.h>

Classes

class  bitref
class  bitref< BlockT >

Public Types

using allocator_type = AllocatorT<block_type>
using block_type = uint8_t
using const_iterator = detail::bitvector_iterator<const bitvector_base<AllocatorT>>
using iterator = detail::bitvector_iterator<bitvector_base<AllocatorT>>
using size_type = size_t
using value_type = block_type

Public Member Functions

template<bitvectorish OutT>
OutT as () const
 bitvector_base ()
 bitvector_base (size_type bits)
 bitvector_base (std::initializer_list< block_type > blocks, std::optional< size_type > bits=std::nullopt)
 bitvector_base (std::span< const uint8_t > bytes, std::optional< size_type > bits=std::nullopt)
bool empty () const
template<bitvectorish OtherT>
bool equals (const OtherT &other) const noexcept
template<bitvectorish OtherT>
bool equals_vartime (const OtherT &other) const noexcept
size_type hamming_weight () const
CT::Choice has_odd_hamming_weight () const
size_type size () const
Serialization
void from_bytes (std::span< const uint8_t > bytes, std::optional< size_type > bits=std::nullopt)
template<concepts::resizable_byte_buffer OutT = std::conditional_t<uses_secure_allocator, secure_vector<uint8_t>, std::vector<uint8_t>>>
OutT to_bytes () const
void to_bytes (std::span< uint8_t > out) const
std::string to_string () const
Capacity Accessors and Modifiers
size_type capacity () const
void reserve (size_type bits)
void resize (size_type bits)
void push_back (bool bit)
void pop_back ()
Bitwise and Global Accessors and Modifiers
auto at (size_type pos)
auto at (size_type pos) const
auto front ()
auto front () const
auto back ()
auto back () const
bitvector_baseset (size_type pos)
bitvector_baseset ()
bitvector_baseunset (size_type pos)
bitvector_baseunset ()
bitvector_baseflip (size_type pos)
bitvector_baseflip ()
bool none_vartime () const
bool none () const
bool any_vartime () const
bool any () const
bool all_vartime () const
bool all () const
auto operator[] (size_type pos)
auto operator[] (size_type pos) const
Subvectors
template<bitvectorish OutT = bitvector_base<AllocatorT>>
auto subvector (size_type pos, std::optional< size_type > length=std::nullopt) const
template<typename OutT>
requires (std::unsigned_integral<strong_type_wrapped_type<OutT>> && !std::same_as<bool, strong_type_wrapped_type<OutT>>)
OutT subvector (size_type pos) const
template<typename InT>
requires (std::unsigned_integral<strong_type_wrapped_type<InT>> && !std::same_as<bool, InT>)
void subvector_replace (size_type pos, InT value)
Operators
auto operator~ ()
template<bitvectorish OtherT>
auto & operator|= (const OtherT &other)
template<bitvectorish OtherT>
auto & operator&= (const OtherT &other)
template<bitvectorish OtherT>
auto & operator^= (const OtherT &other)
Constant Time Operations
template<bitvectorish OtherT>
void ct_conditional_xor (CT::Choice condition, const OtherT &other)
constexpr void _const_time_poison () const
constexpr void _const_time_unpoison () const
Iterators
iterator begin () noexcept
const_iterator begin () const noexcept
const_iterator cbegin () const noexcept
iterator end () noexcept
const_iterator end () const noexcept
const_iterator cend () noexcept

Static Public Attributes

static constexpr size_type block_size_bits = block_size_bytes * 8
static constexpr size_type block_size_bytes = sizeof(block_type)
static constexpr bool uses_secure_allocator = std::is_same_v<allocator_type, secure_allocator<block_type>>

Friends

template<template< typename > typename FriendAllocatorT>
class bitvector_base

Detailed Description

template<template< typename > typename AllocatorT>
class Botan::bitvector_base< AllocatorT >

An arbitrarily large bitvector with typical bit manipulation and convenient bitwise access methods. Don't use bitvector_base directly, but the type aliases::

  • bitvector - with a standard allocator
  • secure_bitvector - with a secure allocator that auto-scrubs the memory

Definition at line 232 of file bitvector.h.

Member Typedef Documentation

◆ allocator_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::allocator_type = AllocatorT<block_type>

Definition at line 236 of file bitvector.h.

◆ block_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::block_type = uint8_t

Definition at line 234 of file bitvector.h.

◆ const_iterator

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::const_iterator = detail::bitvector_iterator<const bitvector_base<AllocatorT>>

Definition at line 239 of file bitvector.h.

◆ iterator

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::iterator = detail::bitvector_iterator<bitvector_base<AllocatorT>>

Definition at line 238 of file bitvector.h.

◆ size_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::size_type = size_t

Definition at line 235 of file bitvector.h.

◆ value_type

template<template< typename > typename AllocatorT>
using Botan::bitvector_base< AllocatorT >::value_type = block_type

Definition at line 237 of file bitvector.h.

Constructor & Destructor Documentation

◆ bitvector_base() [1/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( )
inline

Definition at line 375 of file bitvector.h.

375: m_bits(0) {}

◆ bitvector_base() [2/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( size_type bits)
inlineexplicit

Definition at line 377 of file bitvector.h.

377: m_bits(bits), m_blocks(ceil_toblocks(bits)) {}

◆ bitvector_base() [3/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( std::span< const uint8_t > bytes,
std::optional< size_type > bits = std::nullopt )
inline

Initialize the bitvector from a byte-array. Bits are taken byte-wise from least significant to most significant. Example::

bitvector[0] -> LSB(Byte[0]) bitvector[1] -> LSB+1(Byte[0]) ... bitvector[8] -> LSB(Byte[1])

Parameters
bytesThe byte vector to be loaded
bitsThe number of bits to be loaded. This must not be more than the number of bytes in bytes.

Definition at line 392 of file bitvector.h.

393 :
394 m_bits() {
396 }
void from_bytes(std::span< const uint8_t > bytes, std::optional< size_type > bits=std::nullopt)
Definition bitvector.h:467

◆ bitvector_base() [4/4]

template<template< typename > typename AllocatorT>
Botan::bitvector_base< AllocatorT >::bitvector_base ( std::initializer_list< block_type > blocks,
std::optional< size_type > bits = std::nullopt )
inline

Definition at line 398 of file bitvector.h.

398 :
399 m_bits(bits.value_or(blocks.size() * block_size_bits)), m_blocks(blocks.begin(), blocks.end()) {}
static constexpr size_type block_size_bits
Definition bitvector.h:242
size_type size() const
Definition bitvector.h:403
iterator begin() noexcept
Definition bitvector.h:891
iterator end() noexcept
Definition bitvector.h:897

Member Function Documentation

◆ _const_time_poison()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::_const_time_poison ( ) const
inlineconstexpr

Definition at line 881 of file bitvector.h.

881{ CT::poison(m_blocks); }
constexpr void poison(const T *p, size_t n)
Definition ct_utils.h:54

◆ _const_time_unpoison()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::_const_time_unpoison ( ) const
inlineconstexpr

Definition at line 883 of file bitvector.h.

883{ CT::unpoison(m_blocks); }
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:65

◆ all()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::all ( ) const
inline
Returns
true iff all bits are set in constant time

Definition at line 686 of file bitvector.h.

686{ return hamming_weight() == m_bits; }
size_type hamming_weight() const
Definition bitvector.h:423

◆ all_vartime()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::all_vartime ( ) const
inline
Returns
true iff all bits are set

Definition at line 678 of file bitvector.h.

678 {
679 return full_range_operation(
680 []<std::unsigned_integral BlockT>(BlockT block, BlockT mask) { return block == mask; }, *this);
681 }

◆ any()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::any ( ) const
inline
Returns
true iff at least one bit is set in constant time

Definition at line 673 of file bitvector.h.

673{ return !none(); }
bool none() const
Definition bitvector.h:663

◆ any_vartime()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::any_vartime ( ) const
inline
Returns
true iff at least one bit is set

Definition at line 668 of file bitvector.h.

668{ return !none_vartime(); }
bool none_vartime() const
Definition bitvector.h:656

◆ as()

template<template< typename > typename AllocatorT>
template<bitvectorish OutT>
OutT Botan::bitvector_base< AllocatorT >::as ( ) const
inline
Returns
copies this bitvector into a new bitvector of type OutT

Definition at line 433 of file bitvector.h.

433 {
434 return subvector<OutT>(0, size());
435 }
auto subvector(size_type pos, std::optional< size_type > length=std::nullopt) const
Definition bitvector.h:703

Referenced by Botan::bitvector_base< secure_allocator >::to_bytes().

◆ at() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::at ( size_type pos)
inline

Definition at line 570 of file bitvector.h.

570 {
571 check_offset(pos);
572 return ref(pos);
573 }

◆ at() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::at ( size_type pos) const
inline

Definition at line 576 of file bitvector.h.

576 {
577 check_offset(pos);
578 return ref(pos);
579 }

◆ back() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::back ( )
inline

Definition at line 586 of file bitvector.h.

586{ return ref(size() - 1); }

◆ back() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::back ( ) const
inline

Definition at line 589 of file bitvector.h.

589{ return ref(size() - 1); }

◆ begin() [1/2]

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::begin ( ) const
inlinenoexcept

Definition at line 893 of file bitvector.h.

893{ return const_iterator(this, 0); }
detail::bitvector_iterator< const bitvector_base< AllocatorT > > const_iterator
Definition bitvector.h:239

◆ begin() [2/2]

template<template< typename > typename AllocatorT>
iterator Botan::bitvector_base< AllocatorT >::begin ( )
inlinenoexcept

Definition at line 891 of file bitvector.h.

891{ return iterator(this, 0); }
detail::bitvector_iterator< bitvector_base< AllocatorT > > iterator
Definition bitvector.h:238

◆ capacity()

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::capacity ( ) const
inline

Definition at line 539 of file bitvector.h.

539{ return m_blocks.capacity() * block_size_bits; }

◆ cbegin()

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::cbegin ( ) const
inlinenoexcept

Definition at line 895 of file bitvector.h.

895{ return const_iterator(this, 0); }

◆ cend()

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::cend ( )
inlinenoexcept

Definition at line 901 of file bitvector.h.

901{ return const_iterator(this, size()); }

◆ ct_conditional_xor()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
void Botan::bitvector_base< AllocatorT >::ct_conditional_xor ( CT::Choice condition,
const OtherT & other )
inline

Implements::

if(condition) { *this ^= other; }

omitting runtime dependence on any of the parameters.

Definition at line 859 of file bitvector.h.

859 {
860 BOTAN_ASSERT_NOMSG(m_bits == other.m_bits);
861 BOTAN_ASSERT_NOMSG(m_blocks.size() == other.m_blocks.size());
862
863 auto maybe_xor = overloaded{
865 return lhs ^ m.if_set_return(rhs);
866 },
868 return lhs ^ m.if_set_return(rhs);
869 },
871 return lhs ^ m.if_set_return(rhs);
872 },
874 return lhs ^ m.if_set_return(rhs);
875 },
876 };
877
878 full_range_operation(maybe_xor, *this, unwrap_strong_type(other));
879 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
static constexpr Mask< T > from_choice(Choice c)
Definition ct_utils.h:430

◆ empty()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::empty ( ) const
inline

Definition at line 401 of file bitvector.h.

401{ return m_bits == 0; }

Referenced by Botan::bitvector_base< secure_allocator >::pop_back().

◆ end() [1/2]

template<template< typename > typename AllocatorT>
const_iterator Botan::bitvector_base< AllocatorT >::end ( ) const
inlinenoexcept

Definition at line 899 of file bitvector.h.

899{ return const_iterator(this, size()); }

◆ end() [2/2]

template<template< typename > typename AllocatorT>
iterator Botan::bitvector_base< AllocatorT >::end ( )
inlinenoexcept

Definition at line 897 of file bitvector.h.

897{ return iterator(this, size()); }

◆ equals()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
bool Botan::bitvector_base< AllocatorT >::equals ( const OtherT & other) const
inlinenoexcept
Returns
true if other contains the same bit pattern as this

Definition at line 452 of file bitvector.h.

452 {
453 return (*this ^ other).none();
454 }

◆ equals_vartime()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
bool Botan::bitvector_base< AllocatorT >::equals_vartime ( const OtherT & other) const
inlinenoexcept
Returns
true if other contains the same bit pattern as this

Definition at line 441 of file bitvector.h.

441 {
442 return size() == other.size() &&
443 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) { return lhs == rhs; },
444 *this,
446 }

◆ flip() [1/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::flip ( )
inline

Flips all currently allocated bits.

Definition at line 647 of file bitvector.h.

647 {
648 full_range_operation([](std::unsigned_integral auto block) -> decltype(block) { return ~block; }, *this);
649 zero_unused_bits();
650 return *this;
651 }

◆ flip() [2/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::flip ( size_type pos)
inline

Flips the bit at position pos.

Exceptions
Botan::Invalid_Argumentif pos is out of range

Definition at line 638 of file bitvector.h.

638 {
639 check_offset(pos);
640 ref(pos).flip();
641 return *this;
642 }

◆ from_bytes()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::from_bytes ( std::span< const uint8_t > bytes,
std::optional< size_type > bits = std::nullopt )
inline

Re-initialize the bitvector with the given bytes. See the respective constructor for details. This should be used only when trying to save allocations. Otherwise, use the constructor.

Parameters
bytesthe byte range to load bits from
bits(optional) if not all bytes should be loaded in full

Definition at line 467 of file bitvector.h.

467 {
468 m_bits = bits.value_or(bytes.size_bytes() * 8);
469 BOTAN_ARG_CHECK(m_bits <= bytes.size_bytes() * 8, "not enough data to load so many bits");
470 resize(m_bits);
471
472 // load as much aligned data as possible
473 const auto verbatim_blocks = m_bits / block_size_bits;
475 if(verbatim_blocks > 0) {
477 }
478
479 // load remaining unaligned data
480 for(size_type i = verbatim_bytes * 8; i < m_bits; ++i) {
481 ref(i) = ((bytes[i >> 3] & (uint8_t(1) << (i & 7))) != 0);
482 }
483 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
static constexpr size_type block_size_bytes
Definition bitvector.h:241
void resize(size_type bits)
Definition bitvector.h:543

Referenced by Botan::bitvector_base< secure_allocator >::bitvector_base().

◆ front() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::front ( )
inline

Definition at line 581 of file bitvector.h.

581{ return ref(0); }

◆ front() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::front ( ) const
inline

Definition at line 584 of file bitvector.h.

584{ return ref(0); }

◆ hamming_weight()

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::hamming_weight ( ) const
inline

Counts the number of 1-bits in the bitvector in constant time.

Returns
the "population count" (or hamming weight) of the bitvector

Definition at line 423 of file bitvector.h.

423 {
424 size_type acc = 0;
425 full_range_operation([&](std::unsigned_integral auto block) { acc += ct_popcount(block); }, *this);
426 return acc;
427 }

Referenced by Botan::bitvector_base< secure_allocator >::all(), and Botan::bitvector_base< secure_allocator >::none().

◆ has_odd_hamming_weight()

template<template< typename > typename AllocatorT>
CT::Choice Botan::bitvector_base< AllocatorT >::has_odd_hamming_weight ( ) const
inline
Returns
true iff the number of 1-bits in this is odd, false otherwise (constant time)

Definition at line 408 of file bitvector.h.

408 {
409 uint64_t acc = 0;
410 full_range_operation([&](std::unsigned_integral auto block) { acc ^= block; }, *this);
411
412 for(size_t i = (sizeof(acc) * 8) >> 1; i > 0; i >>= 1) {
413 acc ^= acc >> i;
414 }
415
416 return CT::Choice::from_int(acc & one);
417 }
static constexpr Choice from_int(T v)
Definition ct_utils.h:314

◆ none()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::none ( ) const
inline
Returns
true iff no bit is set in constant time

Definition at line 663 of file bitvector.h.

663{ return hamming_weight() == 0; }

Referenced by Botan::bitvector_base< secure_allocator >::any().

◆ none_vartime()

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::none_vartime ( ) const
inline
Returns
true iff no bit is set

Definition at line 656 of file bitvector.h.

656 {
657 return full_range_operation([](std::unsigned_integral auto block) { return block == 0; }, *this);
658 }

Referenced by Botan::bitvector_base< secure_allocator >::any_vartime().

◆ operator&=()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
auto & Botan::bitvector_base< AllocatorT >::operator&= ( const OtherT & other)
inline

Definition at line 828 of file bitvector.h.

828 {
829 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs & rhs; },
830 *this,
832 return *this;
833 }

◆ operator[]() [1/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::operator[] ( size_type pos)
inline

Definition at line 688 of file bitvector.h.

688{ return ref(pos); }

◆ operator[]() [2/2]

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::operator[] ( size_type pos) const
inline

Definition at line 691 of file bitvector.h.

691{ return ref(pos); }

◆ operator^=()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
auto & Botan::bitvector_base< AllocatorT >::operator^= ( const OtherT & other)
inline

Definition at line 836 of file bitvector.h.

836 {
837 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs ^ rhs; },
838 *this,
840 return *this;
841 }

◆ operator|=()

template<template< typename > typename AllocatorT>
template<bitvectorish OtherT>
auto & Botan::bitvector_base< AllocatorT >::operator|= ( const OtherT & other)
inline

Definition at line 820 of file bitvector.h.

820 {
821 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs | rhs; },
822 *this,
824 return *this;
825 }

◆ operator~()

template<template< typename > typename AllocatorT>
auto Botan::bitvector_base< AllocatorT >::operator~ ( )
inline

Definition at line 813 of file bitvector.h.

813 {
814 auto newbv = *this;
815 newbv.flip();
816 return newbv;
817 }
bitvector_base & flip(size_type pos)
Definition bitvector.h:638

◆ pop_back()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::pop_back ( )
inline

Definition at line 559 of file bitvector.h.

559 {
560 if(!empty()) {
561 resize(size() - 1);
562 }
563 }
bool empty() const
Definition bitvector.h:401

◆ push_back()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::push_back ( bool bit)
inline

Definition at line 553 of file bitvector.h.

553 {
554 const auto i = size();
555 resize(i + 1);
556 ref(i) = bit;
557 }

◆ reserve()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::reserve ( size_type bits)
inline

Definition at line 541 of file bitvector.h.

541{ m_blocks.reserve(ceil_toblocks(bits)); }

◆ resize()

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::resize ( size_type bits)
inline

Definition at line 543 of file bitvector.h.

543 {
544 const auto new_number_of_blocks = ceil_toblocks(bits);
545 if(new_number_of_blocks != m_blocks.size()) {
546 m_blocks.resize(new_number_of_blocks);
547 }
548
549 m_bits = bits;
550 zero_unused_bits();
551 }

Referenced by Botan::bitvector_base< secure_allocator >::from_bytes(), Botan::bitvector_base< secure_allocator >::pop_back(), and Botan::bitvector_base< secure_allocator >::push_back().

◆ set() [1/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::set ( )
inline

Sets all currently allocated bits.

Definition at line 604 of file bitvector.h.

604 {
605 full_range_operation(
606 [](std::unsigned_integral auto block) -> decltype(block) {
607 return static_cast<decltype(block)>(~static_cast<decltype(block)>(0));
608 },
609 *this);
610 zero_unused_bits();
611 return *this;
612 }

◆ set() [2/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::set ( size_type pos)
inline

Sets the bit at position pos.

Exceptions
Botan::Invalid_Argumentif pos is out of range

Definition at line 595 of file bitvector.h.

595 {
596 check_offset(pos);
597 ref(pos).set();
598 return *this;
599 }

◆ size()

◆ subvector() [1/2]

template<template< typename > typename AllocatorT>
template<typename OutT>
requires (std::unsigned_integral<strong_type_wrapped_type<OutT>> && !std::same_as<bool, strong_type_wrapped_type<OutT>>)
OutT Botan::bitvector_base< AllocatorT >::subvector ( size_type pos) const
inline

Extracts a subvector of bits as an unsigned integral type OutT starting from bit pos and copying exactly sizeof(OutT)*8 bits.

Hint: The bits are in big-endian order, i.e. the least significant bit is the 0th bit and the most significant bit it the n-th. Hence, addressing the bits with bitwise operations is done like so: bool bit = (out_int >> pos) & 1;

Definition at line 743 of file bitvector.h.

743 {
745 constexpr size_t bits = sizeof(result_t) * 8;
746 BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to copy");
747 result_t out = 0;
748
749 if(pos % 8 == 0) {
750 out = load_le<result_t>(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(result_t)>());
751 } else {
752 BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(*this, pos, bits);
753 range_operation(
755 if constexpr(std::same_as<result_t, decltype(integer)>) {
756 out = integer;
757 }
758 },
759 op);
760 }
761
763 }

◆ subvector() [2/2]

template<template< typename > typename AllocatorT>
template<bitvectorish OutT = bitvector_base<AllocatorT>>
auto Botan::bitvector_base< AllocatorT >::subvector ( size_type pos,
std::optional< size_type > length = std::nullopt ) const
inline

Creates a new bitvector with a subsection of this bitvector starting at pos copying exactly length bits.

Definition at line 703 of file bitvector.h.

703 {
704 size_type bitlen = length.value_or(size() - pos);
705 BOTAN_ARG_CHECK(pos + bitlen <= size(), "Not enough bits to copy");
706
708
709 // Handle bitvectors that are wrapped in strong types
711
712 if(bitlen > 0) {
713 if(pos % 8 == 0) {
714 copy_mem(
715 newvector_unwrapped.m_blocks,
716 std::span{m_blocks}.subspan(block_index(pos), block_index(pos + bitlen - 1) - block_index(pos) + 1));
717 } else {
718 BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> from_op(
719 *this, pos, bitlen);
720 BitRangeOperator<strong_type_wrapped_type<OutT>> to_op(
722 range_operation([](auto /* to */, auto from) { return from; }, to_op, from_op);
723 }
724
725 newvector_unwrapped.zero_unused_bits();
726 }
727
728 return newvector;
729 }

Referenced by Botan::bitvector_base< secure_allocator >::as().

◆ subvector_replace()

template<template< typename > typename AllocatorT>
template<typename InT>
requires (std::unsigned_integral<strong_type_wrapped_type<InT>> && !std::same_as<bool, InT>)
void Botan::bitvector_base< AllocatorT >::subvector_replace ( size_type pos,
InT value )
inline

Replaces a subvector of bits with the bits of another bitvector value starting at bit pos. The number of bits to replace is determined by the size of value.

Note
This is currently supported for byte-aligned pos only.
Exceptions
Not_Implementedwhen called with pos not divisible by 8.
Parameters
posthe position to start replacing bits
valuethe bitvector to copy bits from

Definition at line 779 of file bitvector.h.

779 {
781 constexpr size_t bits = sizeof(in_t) * 8;
782 BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to replace");
783
784 if(pos % 8 == 0) {
785 store_le(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(in_t)>(),
787 } else {
788 BitRangeOperator<bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(*this, pos, bits);
789 range_operation(
791 if constexpr(std::same_as<in_t, BlockT>) {
793 } else {
794 // This should never be reached. BOTAN_ASSERT_UNREACHABLE()
795 // caused warning "unreachable code" on MSVC, though. You
796 // don't say!
797 //
798 // Returning the given block back, is the most reasonable
799 // thing to do in this case, though.
800 return block;
801 }
802 },
803 op);
804 }
805 }

◆ to_bytes() [1/2]

template<template< typename > typename AllocatorT>
template<concepts::resizable_byte_buffer OutT = std::conditional_t<uses_secure_allocator, secure_vector<uint8_t>, std::vector<uint8_t>>>
OutT Botan::bitvector_base< AllocatorT >::to_bytes ( ) const
inline

Renders the bitvector into a byte array. By default, this will use std::vector<uint8_t> or Botan::secure_vector<uint8_t>, depending on the allocator used by the bitvector. The rendering is compatible with the bit layout explained in the respective constructor.

Definition at line 493 of file bitvector.h.

493 {
494 OutT out(ceil_tobytes(m_bits));
495 to_bytes(out);
496 return out;
497 }
OutT to_bytes() const
Definition bitvector.h:493

Referenced by Botan::Classic_McEliece_Encryptor::raw_kem_encrypt(), and Botan::bitvector_base< secure_allocator >::to_bytes().

◆ to_bytes() [2/2]

template<template< typename > typename AllocatorT>
void Botan::bitvector_base< AllocatorT >::to_bytes ( std::span< uint8_t > out) const
inline

Renders the bitvector into a properly sized byte range.

Parameters
outa byte range that has a length of at least ceil_tobytes(size()).

Definition at line 504 of file bitvector.h.

504 {
505 const auto bytes_needed = ceil_tobytes(m_bits);
506 BOTAN_ARG_CHECK(bytes_needed <= out.size_bytes(), "Not enough space to render bitvector");
507
508 // copy as much aligned data as possible
509 const auto verbatim_blocks = m_bits / block_size_bits;
511 if(verbatim_blocks > 0) {
512 typecast_copy(out.first(verbatim_bytes), std::span{m_blocks}.first(verbatim_blocks));
513 }
514
515 // copy remaining unaligned data
516 clear_mem(out.subspan(verbatim_bytes));
517 for(size_type i = verbatim_bytes * 8; i < m_bits; ++i) {
518 out[i >> 3] |= ref(i).template as<uint8_t>() << (i & 7);
519 }
520 }

◆ to_string()

template<template< typename > typename AllocatorT>
std::string Botan::bitvector_base< AllocatorT >::to_string ( ) const
inline

Renders this bitvector into a sequence of "0"s and "1"s. This is meant for debugging purposes and is not efficient.

Definition at line 526 of file bitvector.h.

526 {
528 for(size_type i = 0; i < size(); ++i) {
529 ss << ref(i);
530 }
531 return ss.str();
532 }

◆ unset() [1/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::unset ( )
inline

Unsets all currently allocated bits.

Definition at line 627 of file bitvector.h.

627 {
628 full_range_operation(
629 [](std::unsigned_integral auto block) -> decltype(block) { return static_cast<decltype(block)>(0); },
630 *this);
631 return *this;
632 }

◆ unset() [2/2]

template<template< typename > typename AllocatorT>
bitvector_base & Botan::bitvector_base< AllocatorT >::unset ( size_type pos)
inline

Unsets the bit at position pos.

Exceptions
Botan::Invalid_Argumentif pos is out of range

Definition at line 618 of file bitvector.h.

618 {
619 check_offset(pos);
620 ref(pos).unset();
621 return *this;
622 }

◆ bitvector_base

template<template< typename > typename AllocatorT>
template<template< typename > typename FriendAllocatorT>
friend class bitvector_base
friend

Definition at line 247 of file bitvector.h.

Member Data Documentation

◆ block_size_bits

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::block_size_bits = block_size_bytes * 8
staticconstexpr

Definition at line 242 of file bitvector.h.

◆ block_size_bytes

template<template< typename > typename AllocatorT>
size_type Botan::bitvector_base< AllocatorT >::block_size_bytes = sizeof(block_type)
staticconstexpr

Definition at line 241 of file bitvector.h.

◆ uses_secure_allocator

template<template< typename > typename AllocatorT>
bool Botan::bitvector_base< AllocatorT >::uses_secure_allocator = std::is_same_v<allocator_type, secure_allocator<block_type>>
staticconstexpr

Definition at line 243 of file bitvector.h.


The documentation for this class was generated from the following file: