7#include <botan/internal/xmd.h>
9#include <botan/exceptn.h>
10#include <botan/hash.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/fmt.h>
18 std::span<uint8_t> output,
19 std::span<const uint8_t> input,
20 std::span<const uint8_t> domain_sep) {
21 if(domain_sep.size() > 0xFF) {
23 throw Not_Implemented(
"XMD does not currently implement oversize DST handling");
26 if(domain_sep.empty()) {
28 throw Invalid_Argument(
"expand_message_xmd requires a non-empty domain separation tag");
31 const uint8_t domain_sep_len =
static_cast<uint8_t
>(domain_sep.size());
41 if(hash_output_size > block_size) {
45 if(output.size() > 255 * hash_output_size || output.size() > 0xFFFF) {
46 throw Invalid_Argument(
"expand_message_xmd requested output length too long");
51 hash.
update(std::vector<uint8_t>(block_size));
53 hash.
update_be(
static_cast<uint16_t
>(output.size()));
56 hash.
update(domain_sep_len);
65 hash.
update(domain_sep_len);
71 const size_t produced = std::min(output.size(), hash_output_size);
73 copy_mem(output.data(), b_i.data(), produced);
74 output = output.subspan(produced);
86 hash.
update(domain_sep_len);
void update(const uint8_t in[], size_t length)
virtual size_t output_length() const =0
void update_be(uint16_t val)
void final(uint8_t out[])
virtual size_t hash_block_size() const
virtual std::string name() const =0
std::string fmt(std::string_view format, const T &... args)
constexpr void copy_mem(T *out, const T *in, size_t n)
void expand_message_xmd(HashFunction &hash, std::span< uint8_t > output, std::span< const uint8_t > input, std::span< const uint8_t > domain_sep)
std::vector< T, secure_allocator< T > > secure_vector