Botan 3.6.1
Crypto and TLS for C&
xof.h
Go to the documentation of this file.
1/*
2* Extendable Output Function Base Class
3* (C) 2023 Jack Lloyd
4* 2023 Fabian Albert, René Meusel - Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_XOF_BASE_CLASS_H_
10#define BOTAN_XOF_BASE_CLASS_H_
11
12#include <botan/concepts.h>
13#include <botan/secmem.h>
14#include <botan/sym_algo.h>
15
16#include <memory>
17#include <string>
18#include <string_view>
19
20namespace Botan {
21
22/**
23 * This class represents an eXtendable Output Function (XOF) objects
24 *
25 * A XOF transforms an arbitrary length input message into an indefinite
26 * stream of output bits. Typically, it is illegal to call `update()` after
27 * the first call to `output()`.
28 */
29class BOTAN_PUBLIC_API(3, 2) XOF {
30 public:
31 XOF() : m_xof_started(false) {}
32
33 virtual ~XOF() = default;
34
35 /**
36 * Create an instance based on a name, or return null if the
37 * algo/provider combination cannot be found. If provider is
38 * empty then best available is chosen.
39 */
40 static std::unique_ptr<XOF> create(std::string_view algo_spec, std::string_view provider = "");
41
42 /**
43 * Create an instance based on a name
44 * If provider is empty then best available is chosen.
45 * @param algo_spec algorithm name
46 * @param provider provider implementation to use
47 * Throws Lookup_Error if not found.
48 */
49 static std::unique_ptr<XOF> create_or_throw(std::string_view algo_spec, std::string_view provider = "");
50
51 /**
52 * @return list of available providers for this algorithm, empty if not available
53 * @param algo_spec algorithm name
54 */
55 static std::vector<std::string> providers(std::string_view algo_spec);
56
57 /**
58 * @return provider information about this implementation. Default is "base",
59 * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
60 */
61 virtual std::string provider() const;
62
63 /**
64 * Reset the state.
65 */
66 void clear() {
67 m_xof_started = false;
68 reset();
69 }
70
71 /**
72 * @return the hash function name
73 */
74 virtual std::string name() const = 0;
75
76 /**
77 * Some XOFs can be parameterized with a @p salt and/or @p key. If required,
78 * this must be called before calling XOF::update().
79 *
80 * @sa XOF::valid_salt_length()
81 * @sa XOF::key_spec()
82 *
83 * @param salt a salt value to parameterize the XOF
84 * @param key a key to parameterize the XOF
85 */
86 void start(std::span<const uint8_t> salt = {}, std::span<const uint8_t> key = {});
87
88 /**
89 * @returns true if salt length is acceptable, false otherwise
90 */
91 virtual bool valid_salt_length(size_t salt_len) const {
92 // Salts are not supported by default
93 return salt_len == 0;
94 }
95
96 /**
97 * @returns an object describing limits on the key size
98 */
100 // Keys are not supported by default
101 return Key_Length_Specification(0);
102 }
103
104 /**
105 * @return the intrinsic processing block size of this XOF
106 */
107 virtual size_t block_size() const = 0;
108
109 /**
110 * Return a new XOF object with the same state as *this.
111 *
112 * If the XOF is not yet in the output phase, it efficiently allows
113 * using several messages with a common prefix.
114 * Otherwise, the copied state will produce the same output
115 * bit stream as the original object at the time of this invocation.
116 *
117 * This function should be called `clone` but for consistency with
118 * other classes it is called `copy_state`.
119 *
120 * @return new XOF object
121 */
122 virtual std::unique_ptr<XOF> copy_state() const = 0;
123
124 /**
125 * @return new object representing the same algorithm as *this
126 */
127 virtual std::unique_ptr<XOF> new_object() const = 0;
128
129 /**
130 * Typically, this is `true` for new objects and becomes `false`
131 * once `output()` was called for the first time.
132 *
133 * @returns true iff calling `update()` is legal in the current object state
134 */
135 virtual bool accepts_input() const = 0;
136
137 /**
138 * Add @p input data to the XOF's internal state
139 *
140 * @param input the data that shall be
141 */
142 void update(std::span<const uint8_t> input) {
143 if(!m_xof_started) {
144 // If the user didn't start() before the first input, we enforce
145 // it with a default value, here.
146 start();
147 }
148 add_data(input);
149 }
150
151 /**
152 * @return the next @p bytes output bytes as the specified container type @p T.
153 */
154 template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
155 T output(size_t bytes) {
156 T out(bytes);
157 generate_bytes(out);
158 return out;
159 }
160
161 /**
162 * @return the next @p count output bytes as a std::array<>.
163 */
164 template <size_t count>
165 std::array<uint8_t, count> output() {
166 std::array<uint8_t, count> out;
167 generate_bytes(out);
168 return out;
169 }
170
171 /**
172 * Convenience overload to generate a std::vector<uint8_t>. Same as calling
173 * `XOF::output<std::vector<uint8_t>>()`.
174 *
175 * @return the next @p bytes output bytes as a byte vector.
176 */
177 std::vector<uint8_t> output_stdvec(size_t bytes) { return output<std::vector<uint8_t>>(bytes); }
178
179 /**
180 * Fill @p output with the next output bytes. The number of bytes
181 * depends on the size of @p output.
182 */
183 void output(std::span<uint8_t> output) { generate_bytes(output); }
184
185 /**
186 * @return the next single output byte
187 */
189 uint8_t out;
190 generate_bytes({&out, 1});
191 return out;
192 }
193
194 private:
195 /**
196 * Take @p salt and/or @p key to pre-parameterize the XOF. This must be called
197 * before calling XOF::update().
198 *
199 * @param salt a salt value to parameterize the XOF
200 * @param key a key to parameterize the XOF
201 */
202 virtual void start_msg(std::span<const uint8_t> salt, std::span<const uint8_t> key);
203
204 /**
205 * Consume @p input data bytes into the XOF's internal state
206 *
207 * Typically, XOFs may consume an arbitrary length of input data but
208 * should refuse accepting more input once the first output bit was
209 * generated. Implementations should throw `Invalid_State` in this
210 * case.
211 *
212 * @param input the span to be consumed entirely into the internal state
213 * @throws Invalid_State if input is added after generating output
214 */
215 virtual void add_data(std::span<const uint8_t> input) = 0;
216
217 /**
218 * Fill the entire @p output span with the next bytes in their output
219 * stream.
220 *
221 * The first invocation to `generate_bytes()` should typically transition
222 * the XOF's state to "output mode" and prevent any further calls to
223 * `XOF::add_data()`.
224 *
225 * @param output the span to be filled entirely with output bytes
226 */
227 virtual void generate_bytes(std::span<uint8_t> output) = 0;
228
229 /**
230 * Clear the XOF's internal state and allow for new input.
231 */
232 virtual void reset() = 0;
233
234 private:
235 bool m_xof_started;
236};
237
238} // namespace Botan
239
240#endif
void clear()
Definition xof.h:66
virtual std::unique_ptr< XOF > new_object() const =0
XOF()
Definition xof.h:31
T output(size_t bytes)
Definition xof.h:155
void output(std::span< uint8_t > output)
Definition xof.h:183
std::array< uint8_t, count > output()
Definition xof.h:165
uint8_t output_next_byte()
Definition xof.h:188
virtual bool valid_salt_length(size_t salt_len) const
Definition xof.h:91
std::vector< uint8_t > output_stdvec(size_t bytes)
Definition xof.h:177
virtual Key_Length_Specification key_spec() const
Definition xof.h:99
virtual ~XOF()=default
virtual size_t block_size() const =0
virtual std::string name() const =0
virtual std::unique_ptr< XOF > copy_state() const =0
void update(std::span< const uint8_t > input)
Definition xof.h:142
virtual bool accepts_input() const =0
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
FE_25519 T
Definition ge.cpp:34