8#include <botan/internal/skein_512.h> 
   10#include <botan/exceptn.h> 
   11#include <botan/internal/fmt.h> 
   12#include <botan/internal/loadstor.h> 
   13#include <botan/internal/mem_utils.h> 
   19      m_personalization(arg_personalization),
 
   20      m_output_bits(arg_output_bits),
 
   23   if(m_output_bits == 0 || m_output_bits % 8 != 0 || m_output_bits > 512) {
 
 
   31   if(m_personalization.empty()) {
 
   32      return fmt(
"Skein-512({})", m_output_bits);
 
   34      return fmt(
"Skein-512({},{})", m_output_bits, m_personalization);
 
 
   39   return std::make_unique<Skein_512>(m_output_bits, m_personalization);
 
 
   43   auto copy = std::make_unique<Skein_512>(m_output_bits, m_personalization);
 
   44   copy->m_threefish->m_K = this->m_threefish->m_K;
 
   45   copy->m_T = this->m_T;
 
   46   copy->m_buffer = this->m_buffer;
 
 
   56void Skein_512::reset_tweak(type_code type, 
bool is_final) {
 
   60      (
static_cast<uint64_t
>(type) << 56) | (
static_cast<uint64_t
>(1) << 62) | (
static_cast<uint64_t
>(is_final) << 63);
 
   63void Skein_512::initial_block() {
 
   64   const uint8_t zeros[64] = {0};
 
   66   m_threefish->set_key(zeros, 
sizeof(zeros));
 
   69   uint8_t config_str[32] = {0x53, 0x48, 0x41, 0x33, 0x01, 0x00, 0};
 
   70   store_le(uint32_t(m_output_bits), config_str + 8);
 
   72   reset_tweak(SKEIN_CONFIG, 
true);
 
   73   ubi_512(std::span{config_str});
 
   75   if(!m_personalization.empty()) {
 
   81      if(m_personalization.length() > 64) {
 
   82         throw Invalid_Argument(
"Skein personalization must be less than 64 bytes");
 
   85      reset_tweak(SKEIN_PERSONALIZATION, 
true);
 
   89   reset_tweak(SKEIN_MSG, 
false);
 
   92void Skein_512::ubi_512(std::span<const uint8_t> msg) {
 
   97      const size_t to_proc = std::min<size_t>(msg.size(), 64);
 
  100      load_le(M.data(), msg.data(), to_proc / 8);
 
  102      if(to_proc % 8 > 0) {
 
  103         for(
size_t j = 0; j != to_proc % 8; ++j) {
 
  104            M[to_proc / 8] |= 
static_cast<uint64_t
>(msg[8 * (to_proc / 8) + j]) << (8 * j);
 
  108      m_threefish->skein_feedfwd(M, m_T);
 
  111      m_T[1] &= ~(
static_cast<uint64_t
>(1) << 62);
 
  113      msg = msg.subspan(to_proc);
 
  114   } 
while(!msg.empty());
 
  117void Skein_512::add_data(std::span<const uint8_t> input) {
 
  118   BufferSlicer in(input);
 
  121      if(
const auto one_block = m_buffer.handle_unaligned_data(in)) {
 
  122         ubi_512(one_block->data(), one_block->size());
 
  125      if(m_buffer.in_alignment()) {
 
  126         const auto [aligned_data, full_blocks] = m_buffer.aligned_data_to_process(in);
 
  127         if(full_blocks > 0) {
 
  128            ubi_512(aligned_data.data(), aligned_data.size());
 
  134void Skein_512::final_result(std::span<uint8_t> out) {
 
  135   m_T[1] |= (
static_cast<uint64_t
>(1) << 63);  
 
  137   const auto pos = m_buffer.elements_in_buffer();
 
  138   m_buffer.fill_up_with_zeros();
 
  139   ubi_512(m_buffer.consume().data(), pos);
 
  141   std::array<uint8_t, 8> counter{};  
 
  143   reset_tweak(SKEIN_OUTPUT, 
true);
 
  146   copy_out_le(out.first(m_output_bits / 8), m_threefish->m_K);
 
std::unique_ptr< HashFunction > copy_state() const override
 
std::unique_ptr< HashFunction > new_object() const override
 
std::string name() const override
 
Skein_512(size_t output_bits=512, std::string_view personalization="")
 
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
 
std::string fmt(std::string_view format, const T &... args)
 
void copy_out_le(std::span< uint8_t > out, const InR &in)
 
constexpr auto store_le(ParamTs &&... params)
 
constexpr auto load_le(ParamTs &&... params)
 
std::vector< T, secure_allocator< T > > secure_vector