Botan 3.5.0
Crypto and TLS for C&
lms.h
Go to the documentation of this file.
1/**
2 * LMS - Leighton-Micali Hash-Based Signatures (RFC 8554)
3 * (C) 2023 Jack Lloyd
4 * 2023 Fabian Albert, Philippe Lieser - Rohde & Schwarz Cybersecurity GmbH
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9#ifndef BOTAN_LMS_H_
10#define BOTAN_LMS_H_
11
12#include <botan/internal/lm_ots.h>
13
14#include <optional>
15#include <string_view>
16#include <utility>
17#include <vector>
18
19namespace Botan {
20
21/**
22 * @brief Enum of available LMS algorithm types.
23 *
24 * The supported parameter sets are defined in RFC 8554 Section 5.1. and
25 * draft-fluhrer-lms-more-parm-sets-11 Section 5. HSS/LMS typecodes are
26 * introduced in RFC 8554 Section 3.2. and their format specified in
27 * Section 3.3.
28 */
29enum class LMS_Algorithm_Type : uint32_t {
30 // --- RFC 8554 ---
31 RESERVED = 0x00,
32
33 // SHA-256 based
34 SHA256_M32_H5 = 0x05,
35 SHA256_M32_H10 = 0x06,
36 SHA256_M32_H15 = 0x07,
37 SHA256_M32_H20 = 0x08,
38 SHA256_M32_H25 = 0x09,
39
40 // --- draft-fluhrer-lms-more-parm-sets-11 ---
41 // SHA-256/192 based
42 SHA256_M24_H5 = 0x0a,
43 SHA256_M24_H10 = 0x0b,
44 SHA256_M24_H15 = 0x0c,
45 SHA256_M24_H20 = 0x0d,
46 SHA256_M24_H25 = 0x0e,
47
48 // SHAKE-256/256 based
49 SHAKE_M32_H5 = 0x0f,
50 SHAKE_M32_H10 = 0x10,
51 SHAKE_M32_H15 = 0x11,
52 SHAKE_M32_H20 = 0x12,
53 SHAKE_M32_H25 = 0x13,
54
55 // SHAKE-256/192 based
56 SHAKE_M24_H5 = 0x14,
57 SHAKE_M24_H10 = 0x15,
58 SHAKE_M24_H15 = 0x16,
59 SHAKE_M24_H20 = 0x17,
60 SHAKE_M24_H25 = 0x18
61};
62
63/**
64 * @brief The length in bytes of the LMS identifier (I).
65 */
66constexpr size_t LMS_IDENTIFIER_LEN = 16;
67
68/**
69 * @brief The authentication path of an LMS signature
70 */
71using LMS_AuthenticationPath = Strong<std::vector<uint8_t>, struct LMS_AuthenticationPath_>;
72
73/**
74 * @brief A node with the LMS tree
75 */
76using LMS_Tree_Node = Strong<std::vector<uint8_t>, struct LMS_Tree_Node_>;
77
78/**
79 * @brief Raw bytes of an LMS signature
80 */
81using LMS_Signature_Bytes = Strong<std::vector<uint8_t>, struct LMS_Signature_Bytes_>;
82
83/**
84 * @brief The LMS parameters.
85 *
86 * See RFC 8554 Section 5.1.
87 */
89 public:
90 /**
91 * @brief Create the LMS parameters from a known algorithm type.
92 * @throws Decoding_Error If the algorithm type is unknown
93 */
94 static LMS_Params create_or_throw(LMS_Algorithm_Type type);
95
96 /**
97 * @brief Create the LMS parameters from a hash function and tree height.
98 *
99 * @param hash_name The name of the hash function to use.
100 * @param h The height of the tree.
101 * @throws Decoding_Error If the algorithm type is unknown
102 */
103 static LMS_Params create_or_throw(std::string_view hash_name, uint8_t h);
104
105 /**
106 * @brief Retuns the LMS algorithm type.
107 */
108 LMS_Algorithm_Type algorithm_type() const { return m_algorithm_type; }
109
110 /**
111 * @brief Returns the height of the LMS tree.
112 */
113 uint8_t h() const { return m_h; }
114
115 /**
116 * @brief Returns the number of bytes associated with each node.
117 */
118 size_t m() const { return m_m; }
119
120 /**
121 * @brief Returns the name of the hash function to use.
122 */
123 const std::string& hash_name() const { return m_hash_name; }
124
125 /**
126 * @brief Construct a new hash instance for the LMS instance.
127 */
128 std::unique_ptr<HashFunction> hash() const { return HashFunction::create_or_throw(hash_name()); }
129
130 private:
131 /**
132 * @brief Construct a new LMS parameter object.
133 *
134 * @param algorithm_type The algorithm type.
135 * @param hash_name The name of the hash function to use.
136 * @param h The height of the tree.
137 */
138 LMS_Params(LMS_Algorithm_Type algorithm_type, std::string_view hash_name, uint8_t h);
139
140 LMS_Algorithm_Type m_algorithm_type;
141 uint8_t m_h;
142 size_t m_m;
143 std::string m_hash_name;
144};
145
146/**
147 * @brief Base class for LMS private and public key. Contains public data associated with this
148 * LMS instance.
149 */
151 public:
152 /**
153 * @brief Constructor storing the provided LMS data.
154 */
155 LMS_Instance(LMS_Params lms_params, LMOTS_Params lmots_params, LMS_Identifier identifier) :
156 m_lms_params(std::move(lms_params)),
157 m_lmots_params(std::move(lmots_params)),
158 m_identifier(std::move(identifier)) {}
159
160 /**
161 * @brief The LMS parameters for this LMS instance.
162 */
163 const LMS_Params& lms_params() const { return m_lms_params; }
164
165 /**
166 * @brief The LMOTS parameters used for OTS instances of this LMS instance.
167 */
168 const LMOTS_Params& lmots_params() const { return m_lmots_params; }
169
170 /**
171 * @brief The identifier of this LMS tree ('I' in RFC 8554)
172 */
173 const LMS_Identifier& identifier() const { return m_identifier; }
174
175 private:
176 LMS_Params m_lms_params;
177 LMOTS_Params m_lmots_params;
178 LMS_Identifier m_identifier;
179};
180
181class LMS_PublicKey;
182
183/**
184 * @brief Representation of an LMS Private key
185 *
186 * Contains the secret seed used for OTS key derivation
187 * as described in RFC 8554 Appendix A.
188 */
190 public:
191 /**
192 * @brief Construct storing the LMS instance data and the secret seed
193 */
194 LMS_PrivateKey(LMS_Params lms_params, LMOTS_Params lmots_params, LMS_Identifier I, LMS_Seed seed) :
195 LMS_Instance(std::move(lms_params), std::move(lmots_params), std::move(I)), m_seed(std::move(seed)) {}
196
197 /**
198 * @brief The secret seed used for LMOTS' WOTS chain input creation (RFC 8554 Appendix A)
199 */
200 const LMS_Seed& seed() const { return m_seed; }
201
202 /**
203 * @brief Sign a message using an LMS_PrivateKey and the used leaf index (RFC 8554 5.4.1).
204 *
205 * The signature is written in the provided buffer. The LMS_PublicKey
206 * associated with the given private key is returned.
207 */
208 LMS_PublicKey sign_and_get_pk(StrongSpan<LMS_Signature_Bytes> out_sig,
210 const LMS_Message& msg) const;
211
212 private:
213 LMS_Seed m_seed;
214};
215
216class LMS_Signature;
217
218/**
219 * @brief The LMS public key.
220 *
221 * Format according to RFC 8554:
222 * u32str(type) || u32str(otstype) || I || T[1]
223 */
225 public:
226 /**
227 * @brief Parse a public LMS key.
228 *
229 * @param slicer The BufferSlicer at the public key bytes' position
230 * @return The LMS public key.
231 * @throws Decoding_Error If parsing the public key fails.
232 */
233 static LMS_PublicKey from_bytes_or_throw(BufferSlicer& slicer);
234
235 /**
236 * @brief Construct a public key for given public key data
237 */
238 LMS_PublicKey(LMS_Params lms_params, LMOTS_Params lmots_params, LMS_Identifier I, LMS_Tree_Node lms_root);
239
240 /**
241 * @brief Construct a new public key from a given LMS private key (RFC 8554 5.3).
242 */
243 LMS_PublicKey(const LMS_PrivateKey& sk);
244
245 /**
246 * @brief Bytes of the full lms public key according to 8554 5.3
247 *
248 * pub_key_bytes = u32str(type) || u32str(otstype) || I || T[1]
249 */
250 std::vector<uint8_t> to_bytes() const;
251
252 /**
253 * @brief The expected size of an LMS public key for given @p lms_params
254 */
255 static size_t size(const LMS_Params& lms_params);
256
257 /**
258 * @brief Verify a LMS signature.
259 *
260 * See RFC 8554 5.4.2 - Algorithm 6.
261 *
262 * @param msg The signed message.
263 * @param sig The already parsed LMS signature.
264 * @return True if the signature is valid, false otherwise.
265 */
266 bool verify_signature(const LMS_Message& msg, const LMS_Signature& sig) const;
267
268 private:
269 /**
270 * @brief Compute an lms public key candidate.
271 *
272 * Given the LMS public key, a LMS-Signature-LMS_Message pair, compute
273 * an LMS public key candidate as described in RFC 8554 5.4.2 Algorithm 6a.
274 */
275 std::optional<LMS_Tree_Node> lms_compute_root_from_sig(const LMS_Message& msg, const LMS_Signature& sig) const;
276
277 /**
278 * @brief Root node of the LMS tree ('T[1]' in RFC 8554 5.3)
279 */
280 const LMS_Tree_Node& lms_root() const { return m_lms_root; }
281
282 LMS_Tree_Node m_lms_root;
283};
284
285/**
286 * @brief Container for LMS Signature data.
287 *
288 * Contains a method for secure signature parsing.
289 */
291 public:
292 /**
293 * @brief Parse the bytes of a lms signature into a LMS Signature object
294 *
295 * @param slicer A BufferSlicer object at the position of the LMS_Signature to parse
296 * @return LMS_Signature object
297 * @throws Decoding_Error If parsing the signature fails.
298 */
299 static LMS_Signature from_bytes_or_throw(BufferSlicer& slicer);
300
301 /**
302 * @brief The index of the signing leaf given by the signature
303 */
304 LMS_Tree_Node_Idx q() const { return m_q; }
305
306 /**
307 * @brief The LMOTS signature object containing the parsed LMOTS signature bytes
308 * contained in the LMS signature
309 */
310 const LMOTS_Signature& lmots_sig() const { return m_lmots_sig; }
311
312 /**
313 * @brief The LMS algorithm type given by the signature
314 */
315 LMS_Algorithm_Type lms_type() const { return m_lms_type; }
316
317 /**
318 * @brief The authentication path bytes given by the signature
319 *
320 * ('path[0] || ... || path[h-1]' in RFC 8554 5.4)
321 */
323
324 /**
325 * @return size_t The expected size of the signature.
326 */
327 static size_t size(const LMS_Params& lms_params, const LMOTS_Params& lmots_params);
328
329 private:
330 /**
331 * @brief Private constructor storing the data fields individually
332 */
334 LMOTS_Signature lmots_sig,
335 LMS_Algorithm_Type lms_type,
336 LMS_AuthenticationPath auth_path) :
337 m_q(q), m_lmots_sig(std::move(lmots_sig)), m_lms_type(lms_type), m_auth_path(std::move(auth_path)) {}
338
339 LMS_Tree_Node_Idx m_q;
340 LMOTS_Signature m_lmots_sig;
341 LMS_Algorithm_Type m_lms_type;
342 LMS_AuthenticationPath m_auth_path;
343};
344
345} // namespace Botan
346
347#endif
The LM-OTS parameters.
Definition lm_ots.h:100
Representation of a LM-OTS signature.
Definition lm_ots.h:178
Base class for LMS private and public key. Contains public data associated with this LMS instance.
Definition lms.h:150
const LMS_Params & lms_params() const
The LMS parameters for this LMS instance.
Definition lms.h:163
const LMOTS_Params & lmots_params() const
The LMOTS parameters used for OTS instances of this LMS instance.
Definition lms.h:168
const LMS_Identifier & identifier() const
The identifier of this LMS tree ('I' in RFC 8554)
Definition lms.h:173
LMS_Instance(LMS_Params lms_params, LMOTS_Params lmots_params, LMS_Identifier identifier)
Constructor storing the provided LMS data.
Definition lms.h:155
The LMS parameters.
Definition lms.h:88
const std::string & hash_name() const
Returns the name of the hash function to use.
Definition lms.h:123
size_t m() const
Returns the number of bytes associated with each node.
Definition lms.h:118
std::unique_ptr< HashFunction > hash() const
Construct a new hash instance for the LMS instance.
Definition lms.h:128
LMS_Algorithm_Type algorithm_type() const
Retuns the LMS algorithm type.
Definition lms.h:108
uint8_t h() const
Returns the height of the LMS tree.
Definition lms.h:113
Representation of an LMS Private key.
Definition lms.h:189
LMS_PrivateKey(LMS_Params lms_params, LMOTS_Params lmots_params, LMS_Identifier I, LMS_Seed seed)
Construct storing the LMS instance data and the secret seed.
Definition lms.h:194
const LMS_Seed & seed() const
The secret seed used for LMOTS' WOTS chain input creation (RFC 8554 Appendix A)
Definition lms.h:200
The LMS public key.
Definition lms.h:224
Container for LMS Signature data.
Definition lms.h:290
const LMOTS_Signature & lmots_sig() const
The LMOTS signature object containing the parsed LMOTS signature bytes contained in the LMS signature...
Definition lms.h:310
LMS_Tree_Node_Idx q() const
The index of the signing leaf given by the signature.
Definition lms.h:304
LMS_Algorithm_Type lms_type() const
The LMS algorithm type given by the signature.
Definition lms.h:315
StrongSpan< const LMS_AuthenticationPath > auth_path() const
The authentication path bytes given by the signature.
Definition lms.h:322
#define BOTAN_TEST_API
Definition compiler.h:51
LMS_Algorithm_Type
Enum of available LMS algorithm types.
Definition lms.h:29
constexpr size_t LMS_IDENTIFIER_LEN
The length in bytes of the LMS identifier (I).
Definition lms.h:66
bool verify_signature(std::span< const uint8_t, ED448_LEN > pk, bool phflag, std::span< const uint8_t > context, std::span< const uint8_t > sig, std::span< const uint8_t > msg)
Verify a signature(RFC 8032 5.2.7)