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