11#ifndef BOTAN_PQ_CRYSTALS_ENCODING_H_ 
   12#define BOTAN_PQ_CRYSTALS_ENCODING_H_ 
   18#include <botan/internal/loadstor.h> 
   19#include <botan/internal/pqcrystals.h> 
   20#include <botan/internal/pqcrystals_helpers.h> 
   21#include <botan/internal/stl_util.h> 
   23#if defined(BOTAN_HAS_XOF) 
   24   #include <botan/xof.h> 
   31   return [&](std::span<uint8_t> out) { slicer.
copy_into(out); };
 
 
   34#if defined(BOTAN_HAS_XOF) 
   36   return [&](std::span<uint8_t> out) { xof.
output(out); };
 
   46template <
typename T, 
typename PolyCoeffT>
 
   47concept coeff_map_fn = std::signed_integral<PolyCoeffT> && 
requires(T fn, PolyCoeffT coeff) {
 
   48   { fn(coeff) } -> std::same_as<std::make_unsigned_t<PolyCoeffT>>;
 
 
   51template <
typename T, 
typename PolyCoeffT>
 
   53   std::signed_integral<PolyCoeffT> && 
requires(T fn, std::make_unsigned_t<PolyCoeffT> coeff_value) {
 
   54      { fn(coeff_value) } -> std::same_as<PolyCoeffT>;
 
 
   65template <
int32_t range, crystals_trait PolyTrait>
 
   67      using T = 
typename PolyTrait::T;
 
   71      static_assert(range <= std::numeric_limits<T>::max());
 
   78         size_t smallest_aligned_pack = std::lcm(
bits_per_coeff, 
size_t(8));
 
   81                   : smallest_aligned_pack;
 
 
 
  115template <
int32_t range, crystals_trait PolyTrait, Domain D, coeff_map_fn<
typename PolyTrait::T> MapFnT>
 
  133   for(
size_t i = 0; i < p.
size(); i += trait::coeffs_per_pack) {
 
  137      typename trait::collector_array collectors = {0};
 
  138      for(
size_t j = 0, bit_offset = 0, c = 0; j < trait::coeffs_per_pack; ++j) {
 
  140         const typename trait::unsigned_T mapped_coeff = map(p[i + j]);
 
  141         const auto coeff_value = 
static_cast<typename trait::sink_t
>(mapped_coeff);
 
  150         collectors[c] |= coeff_value << bit_offset;
 
  151         bit_offset += trait::bits_per_coeff;
 
  156         if(bit_offset > trait::bits_in_collector) {
 
  157            bit_offset = bit_offset - trait::bits_in_collector;
 
  158            collectors[++c] = coeff_value >> (trait::bits_per_coeff - bit_offset);
 
  165      const auto bytes = 
store_le(collectors);
 
  166      stuffer.
append(std::span{bytes}.template first<trait::bytes_per_pack>());
 
 
  185template <int32_t range,
 
  186          byte_source ByteSourceT,
 
  187          crystals_trait PolyTrait,
 
  189          coeff_unmap_fn<typename PolyTrait::T> UnmapFnT>
 
  194   typename trait::collector_bytearray bytes = {0};
 
  198   for(
size_t i = 0; i < p.
size(); i += trait::coeffs_per_pack) {
 
  199      get_bytes(std::span{bytes}.template first<trait::bytes_per_pack>());
 
  202      for(
size_t j = 0, bit_offset = 0, c = 0; j < trait::coeffs_per_pack; ++j) {
 
  203         typename trait::sink_t coeff_value = collectors[c] >> bit_offset;
 
  204         bit_offset += trait::bits_per_coeff;
 
  205         if(bit_offset > trait::bits_in_collector) {
 
  206            bit_offset = bit_offset - trait::bits_in_collector;
 
  207            coeff_value |= collectors[++c] << (trait::bits_per_coeff - bit_offset);
 
  215         p[i + j] = unmap(
static_cast<typename trait::unsigned_T
>(coeff_value & trait::value_mask));
 
 
  221template <
int32_t range, crystals_trait PolyTrait, Domain D>
 
  223   using unsigned_T = std::make_unsigned_t<typename PolyTrait::T>;
 
  224   pack<range>(p, stuffer, [](
typename PolyTrait::T x) { 
return static_cast<unsigned_T
>(x); });
 
 
  228template <
int32_t range, 
byte_source ByteSourceT, crystals_trait PolyTrait, Domain D>
 
  230   using unsigned_T = std::make_unsigned_t<typename PolyTrait::T>;
 
 
#define BOTAN_DEBUG_ASSERT(expr)
 
void copy_into(std::span< uint8_t > sink)
 
Helper class to ease in-place marshalling of concatenated fixed-length values.
 
constexpr void append(std::span< const uint8_t > buffer)
 
constexpr size_t remaining_capacity() const
 
constexpr size_t size() const
 
constexpr auto as_byte_source(BufferSlicer &slicer)
 
constexpr void unpack(Polynomial< PolyTrait, D > &p, ByteSourceT &byte_source, UnmapFnT unmap)
 
constexpr void pack(const Polynomial< PolyTrait, D > &p, BufferStuffer &stuffer, MapFnT map)
 
constexpr auto store_le(ParamTs &&... params)
 
constexpr auto load_le(ParamTs &&... params)
 
constexpr auto bitlen(size_t x)
 
static constexpr size_t coeffs_per_pack
 
static constexpr size_t collectors_per_pack
 
static constexpr size_t bits_per_pack
 
static constexpr size_t bits_in_collector
 
static constexpr size_t bits_per_coeff
 
std::array< sink_t, collectors_per_pack > collector_array
 
static constexpr sink_t value_mask
 
std::array< uint8_t, collector_bytes_per_pack > collector_bytearray
 
std::make_unsigned_t< T > unsigned_T
 
static constexpr size_t bytes_per_pack
 
static constexpr size_t collector_bytes_per_pack