Botan 3.13.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 push_back (CT::Choice 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>
OutT subvector (size_type pos) const
template<typename 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 233 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 237 of file bitvector.h.

◆ block_type

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

Definition at line 235 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 240 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 239 of file bitvector.h.

◆ size_type

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

Definition at line 236 of file bitvector.h.

◆ value_type

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

Definition at line 238 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 397 of file bitvector.h.

397: 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 399 of file bitvector.h.

399: 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 414 of file bitvector.h.

415 :
416 m_bits() {
418 }
void from_bytes(std::span< const uint8_t > bytes, std::optional< size_type > bits=std::nullopt)
Definition bitvector.h:498

◆ 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 420 of file bitvector.h.

420 :
421 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:243
size_type size() const
Definition bitvector.h:425
iterator begin() noexcept
Definition bitvector.h:935
iterator end() noexcept
Definition bitvector.h:941

Member Function Documentation

◆ _const_time_poison()

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

Definition at line 925 of file bitvector.h.

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

◆ _const_time_unpoison()

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

Definition at line 927 of file bitvector.h.

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

◆ 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 729 of file bitvector.h.

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

◆ 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 721 of file bitvector.h.

721 {
722 return full_range_operation(
723 []<std::unsigned_integral BlockT>(BlockT block, BlockT mask) { return block == mask; }, *this);
724 }

◆ 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 716 of file bitvector.h.

716{ return !none(); }
bool none() const
Definition bitvector.h:706

◆ 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 711 of file bitvector.h.

711{ return !none_vartime(); }
bool none_vartime() const
Definition bitvector.h:699

◆ 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 455 of file bitvector.h.

455 {
456 return subvector<OutT>(0, size());
457 }
auto subvector(size_type pos, std::optional< size_type > length=std::nullopt) const
Definition bitvector.h:746

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 613 of file bitvector.h.

613 {
614 check_offset(pos);
615 return ref(pos);
616 }

◆ at() [2/2]

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

Definition at line 619 of file bitvector.h.

619 {
620 check_offset(pos);
621 return ref(pos);
622 }

◆ back() [1/2]

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

Definition at line 629 of file bitvector.h.

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

◆ back() [2/2]

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

Definition at line 632 of file bitvector.h.

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

◆ begin() [1/2]

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

Definition at line 937 of file bitvector.h.

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

◆ begin() [2/2]

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

Definition at line 935 of file bitvector.h.

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

◆ capacity()

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

Definition at line 573 of file bitvector.h.

573{ 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 939 of file bitvector.h.

939{ return const_iterator(this, 0); }

◆ cend()

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

Definition at line 945 of file bitvector.h.

945{ 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 903 of file bitvector.h.

903 {
904 BOTAN_ASSERT_NOMSG(m_bits == other.m_bits);
905 BOTAN_ASSERT_NOMSG(m_blocks.size() == other.m_blocks.size());
906
907 auto maybe_xor = overloaded{
909 return lhs ^ m.if_set_return(rhs);
910 },
912 return lhs ^ m.if_set_return(rhs);
913 },
915 return lhs ^ m.if_set_return(rhs);
916 },
918 return lhs ^ m.if_set_return(rhs);
919 },
920 };
921
922 full_range_operation(maybe_xor, *this, unwrap_strong_type(other));
923 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
static constexpr Mask< T > from_choice(Choice c)
Definition ct_utils.h:402

◆ empty()

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

Definition at line 423 of file bitvector.h.

423{ 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 943 of file bitvector.h.

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

◆ end() [2/2]

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

Definition at line 941 of file bitvector.h.

941{ 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 474 of file bitvector.h.

474 {
475 if(size() != other.size()) {
476 return false;
477 }
478
479 uint64_t acc = 0;
480 full_range_operation(
481 [&]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) { acc |= static_cast<uint64_t>(lhs ^ rhs); },
482 *this,
485 }
static constexpr Choice from_int(T v)
Definition ct_utils.h:268
constexpr bool as_bool() const
Definition ct_utils.h:329

◆ 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 463 of file bitvector.h.

463 {
464 return size() == other.size() &&
465 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) { return lhs == rhs; },
466 *this,
468 }

◆ flip() [1/2]

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

Flips all currently allocated bits.

Definition at line 690 of file bitvector.h.

690 {
691 full_range_operation([](std::unsigned_integral auto block) -> decltype(block) { return ~block; }, *this);
692 zero_unused_bits();
693 return *this;
694 }

◆ 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 681 of file bitvector.h.

681 {
682 check_offset(pos);
683 ref(pos).flip();
684 return *this;
685 }

◆ 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 498 of file bitvector.h.

498 {
499 const size_type new_bits = bits.has_value()
500 ? bits.value()
501 : mul_or_throw<size_t>(8, bytes.size_bytes(), "bitvector input is too large");
502 const size_type bytes_needed = (new_bits / 8) + (new_bits % 8 != 0 ? 1 : 0);
503 BOTAN_ARG_CHECK(bytes_needed <= bytes.size_bytes(), "not enough data to load so many bits");
505
506 // load as much aligned data as possible
509 if(verbatim_blocks > 0) {
511 }
512
513 // load remaining unaligned data
514 for(size_type i = verbatim_bytes * 8; i < new_bits; ++i) {
515 ref(i) = ((bytes[i >> 3] & (uint8_t(1) << (i & 7))) != 0);
516 }
517 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
static constexpr size_type block_size_bytes
Definition bitvector.h:242
void resize(size_type bits)
Definition bitvector.h:577

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 624 of file bitvector.h.

624{ return ref(0); }

◆ front() [2/2]

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

Definition at line 627 of file bitvector.h.

627{ 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 445 of file bitvector.h.

445 {
446 size_type acc = 0;
447 full_range_operation([&](std::unsigned_integral auto block) { acc += ct_popcount(block); }, *this);
448 return acc;
449 }

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 430 of file bitvector.h.

430 {
431 uint64_t acc = 0;
432 full_range_operation([&](std::unsigned_integral auto block) { acc ^= block; }, *this);
433
434 for(size_t i = (sizeof(acc) * 8) >> 1; i > 0; i >>= 1) {
435 acc ^= acc >> i;
436 }
437
438 return CT::Choice::from_int(acc & one);
439 }

◆ 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 706 of file bitvector.h.

706{ 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 699 of file bitvector.h.

699 {
700 return full_range_operation([](std::unsigned_integral auto block) { return block == 0; }, *this);
701 }

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 872 of file bitvector.h.

872 {
873 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs & rhs; },
874 *this,
876 return *this;
877 }

◆ operator[]() [1/2]

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

Definition at line 731 of file bitvector.h.

731{ 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 734 of file bitvector.h.

734{ 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 880 of file bitvector.h.

880 {
881 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs ^ rhs; },
882 *this,
884 return *this;
885 }

◆ operator|=()

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

Definition at line 864 of file bitvector.h.

864 {
865 full_range_operation([]<std::unsigned_integral BlockT>(BlockT lhs, BlockT rhs) -> BlockT { return lhs | rhs; },
866 *this,
868 return *this;
869 }

◆ operator~()

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

Definition at line 857 of file bitvector.h.

857 {
858 auto newbv = *this;
859 newbv.flip();
860 return newbv;
861 }
bitvector_base & flip(size_type pos)
Definition bitvector.h:681

◆ pop_back()

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

Definition at line 602 of file bitvector.h.

602 {
603 if(!empty()) {
604 resize(size() - 1);
605 }
606 }
bool empty() const
Definition bitvector.h:423

◆ push_back() [1/2]

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

Definition at line 590 of file bitvector.h.

590 {
591 const auto i = size();
592 resize(i + 1);
593 ref(i) = bit;
594 }

◆ push_back() [2/2]

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

Definition at line 596 of file bitvector.h.

596 {
597 const auto i = size();
598 resize(i + 1);
599 ref(i) = bit;
600 }

◆ reserve()

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

Definition at line 575 of file bitvector.h.

575{ 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 577 of file bitvector.h.

577 {
578 const auto new_number_of_blocks = ceil_toblocks(bits);
579 const auto old_number_of_blocks = m_blocks.size();
581 m_blocks.insert(m_blocks.end(), new_number_of_blocks - old_number_of_blocks, block_type(0));
583 m_blocks.erase(m_blocks.begin() + new_number_of_blocks, m_blocks.end());
584 }
585
586 m_bits = bits;
587 zero_unused_bits();
588 }

Referenced by Botan::bitvector_base< secure_allocator >::from_bytes(), Botan::bitvector_base< secure_allocator >::pop_back(), Botan::bitvector_base< secure_allocator >::push_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 647 of file bitvector.h.

647 {
648 full_range_operation(
649 [](std::unsigned_integral auto block) -> decltype(block) {
650 return static_cast<decltype(block)>(~static_cast<decltype(block)>(0));
651 },
652 *this);
653 zero_unused_bits();
654 return *this;
655 }

◆ 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 638 of file bitvector.h.

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

◆ size()

◆ subvector() [1/2]

template<template< typename > typename AllocatorT>
template<typename 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 786 of file bitvector.h.

786 {
788 constexpr size_t bits = sizeof(result_t) * 8;
789 BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to copy");
790 result_t out = 0;
791
792 if(pos % 8 == 0) {
793 out = load_le<result_t>(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(result_t)>());
794 } else {
795 const BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(
796 *this, pos, bits);
797 range_operation(
799 if constexpr(std::same_as<result_t, decltype(integer)>) {
800 out = integer;
801 }
802 },
803 op);
804 }
805
807 }

◆ 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 746 of file bitvector.h.

746 {
747 const size_type bitlen = length.value_or(size() - pos);
748 BOTAN_ARG_CHECK(pos + bitlen <= size(), "Not enough bits to copy");
749
751
752 // Handle bitvectors that are wrapped in strong types
754
755 if(bitlen > 0) {
756 if(pos % 8 == 0) {
757 copy_mem(
758 newvector_unwrapped.m_blocks,
759 std::span{m_blocks}.subspan(block_index(pos), block_index(pos + bitlen - 1) - block_index(pos) + 1));
760 } else {
761 const BitRangeOperator<const bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> from_op(
762 *this, pos, bitlen);
763 const BitRangeOperator<strong_type_wrapped_type<OutT>> to_op(
765 range_operation([](auto /* to */, auto from) { return from; }, to_op, from_op);
766 }
767
768 newvector_unwrapped.zero_unused_bits();
769 }
770
771 return newvector;
772 }

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

◆ subvector_replace()

template<template< typename > typename AllocatorT>
template<typename 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 823 of file bitvector.h.

823 {
825 constexpr size_t bits = sizeof(in_t) * 8;
826 BOTAN_ARG_CHECK(pos + bits <= size(), "Not enough bits to replace");
827
828 if(pos % 8 == 0) {
829 store_le(std::span{m_blocks}.subspan(block_index(pos)).template first<sizeof(in_t)>(),
831 } else {
832 const BitRangeOperator<bitvector_base<AllocatorT>, BitRangeAlignment::no_alignment> op(*this, pos, bits);
833 range_operation(
835 if constexpr(std::same_as<in_t, BlockT>) {
837 } else {
838 // This should never be reached. BOTAN_ASSERT_UNREACHABLE()
839 // caused warning "unreachable code" on MSVC, though. You
840 // don't say!
841 //
842 // Returning the given block back, is the most reasonable
843 // thing to do in this case, though.
844 return block;
845 }
846 },
847 op);
848 }
849 }

◆ 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 527 of file bitvector.h.

527 {
528 OutT out(ceil_tobytes(m_bits));
529 to_bytes(out);
530 return out;
531 }
OutT to_bytes() const
Definition bitvector.h:527

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 538 of file bitvector.h.

538 {
539 const auto bytes_needed = ceil_tobytes(m_bits);
540 BOTAN_ARG_CHECK(bytes_needed <= out.size_bytes(), "Not enough space to render bitvector");
541
542 // copy as much aligned data as possible
543 const auto verbatim_blocks = m_bits / block_size_bits;
545 if(verbatim_blocks > 0) {
546 typecast_copy(out.first(verbatim_bytes), std::span{m_blocks}.first(verbatim_blocks));
547 }
548
549 // copy remaining unaligned data
550 clear_mem(out.subspan(verbatim_bytes));
551 for(size_type i = verbatim_bytes * 8; i < m_bits; ++i) {
552 out[i >> 3] |= ref(i).template as<uint8_t>() << (i & 7);
553 }
554 }

◆ 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 560 of file bitvector.h.

560 {
562 for(size_type i = 0; i < size(); ++i) {
563 ss << ref(i);
564 }
565 return ss.str();
566 }

◆ unset() [1/2]

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

Unsets all currently allocated bits.

Definition at line 670 of file bitvector.h.

670 {
671 full_range_operation(
672 [](std::unsigned_integral auto block) -> decltype(block) { return static_cast<decltype(block)>(0); },
673 *this);
674 return *this;
675 }

◆ 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 661 of file bitvector.h.

661 {
662 check_offset(pos);
663 ref(pos).unset();
664 return *this;
665 }

◆ bitvector_base

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

Definition at line 248 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 243 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 242 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 244 of file bitvector.h.


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