Botan  2.19.1
Crypto and TLS for C++11
xmss.h
Go to the documentation of this file.
1 /*
2  * XMSS Keys
3  * (C) 2016,2017 Matthias Gierlings
4  * (C) 2019 RenĂ© Korthaus, Rohde & Schwarz Cybersecurity
5  *
6  * Botan is released under the Simplified BSD License (see license.txt)
7  **/
8 
9 #ifndef BOTAN_XMSS_H_
10 #define BOTAN_XMSS_H_
11 
12 #include <botan/pk_keys.h>
13 #include <botan/exceptn.h>
14 #include <botan/xmss_parameters.h>
15 #include <botan/xmss_wots.h>
16 
17 namespace Botan {
18 
19 class RandomNumberGenerator;
20 class XMSS_Verification_Operation;
21 
22 /**
23  * An XMSS: Extended Hash-Based Signature public key.
24  *
25  * [1] XMSS: Extended Hash-Based Signatures,
26  * Request for Comments: 8391
27  * Release: May 2018.
28  * https://datatracker.ietf.org/doc/rfc8391/
29  **/
30 class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
31  {
32  public:
33  /**
34  * Creates a new XMSS public key for the chosen XMSS signature method.
35  * New public and prf seeds are generated using rng. The appropriate WOTS
36  * signature method will be automatically set based on the chosen XMSS
37  * signature method.
38  *
39  * @param xmss_oid Identifier for the selected XMSS signature method.
40  * @param rng A random number generator to use for key generation.
41  **/
44 
45  /**
46  * Loads a public key.
47  *
48  * Public key must be encoded as in RFC
49  * draft-vangeest-x509-hash-sigs-03.
50  *
51  * @param key_bits DER encoded public key bits
52  */
53  XMSS_PublicKey(const std::vector<uint8_t>& key_bits);
54 
55  /**
56  * Creates a new XMSS public key for a chosen XMSS signature method as
57  * well as pre-computed root node and public_seed values.
58  *
59  * @param xmss_oid Identifier for the selected XMSS signature method.
60  * @param root Root node value.
61  * @param public_seed Public seed value.
62  **/
64  const secure_vector<uint8_t>& root,
65  const secure_vector<uint8_t>& public_seed)
66  : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),
67  m_root(root), m_public_seed(public_seed) {}
68 
69  /**
70  * Creates a new XMSS public key for a chosen XMSS signature method as
71  * well as pre-computed root node and public_seed values.
72  *
73  * @param xmss_oid Identifier for the selected XMSS signature method.
74  * @param root Root node value.
75  * @param public_seed Public seed value.
76  **/
79  secure_vector<uint8_t>&& public_seed)
80  : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),
81  m_root(std::move(root)), m_public_seed(std::move(public_seed)) {}
82 
83  /**
84  * Retrieves the chosen XMSS signature method.
85  *
86  * @return XMSS signature method identifier.
87  **/
89  {
90  return m_xmss_params.oid();
91  }
92 
93  /**
94  * Sets the chosen XMSS signature method
95  **/
97  {
98  m_xmss_params = XMSS_Parameters(xmss_oid);
99  m_wots_params = XMSS_WOTS_Parameters(m_xmss_params.ots_oid());
100  }
101 
102  /**
103  * Retrieves the XMSS parameters determined by the chosen XMSS Signature
104  * method.
105  *
106  * @return XMSS parameters.
107  **/
109  {
110  return m_xmss_params;
111  }
112 
113  /**
114  * Retrieves the XMSS parameters determined by the chosen XMSS Signature
115  * method.
116  *
117  * @return XMSS parameters.
118  **/
119  std::string xmss_hash_function() const
120  {
121  return m_xmss_params.hash_function_name();
122  }
123 
124  /**
125  * Retrieves the Winternitz One Time Signature (WOTS) method,
126  * corresponding to the chosen XMSS signature method.
127  *
128  * @return XMSS WOTS signature method identifier.
129  **/
131  {
132  return m_wots_params.oid();
133  }
134 
135  /**
136  * Retrieves the Winternitz One Time Signature (WOTS) parameters
137  * corresponding to the chosen XMSS signature method.
138  *
139  * @return XMSS WOTS signature method parameters.
140  **/
142  {
143  return m_wots_params;
144  }
145 
147  {
148  return m_root;
149  }
150 
152  {
153  m_root = root;
154  }
155 
157  {
158  m_root = std::move(root);
159  }
160 
162  {
163  return m_root;
164  }
165 
167  {
168  return m_public_seed;
169  }
170 
171  virtual void set_public_seed(const secure_vector<uint8_t>& public_seed)
172  {
173  m_public_seed = public_seed;
174  }
175 
176  virtual void set_public_seed(secure_vector<uint8_t>&& public_seed)
177  {
178  m_public_seed = std::move(public_seed);
179  }
180 
181  virtual const secure_vector<uint8_t>& public_seed() const
182  {
183  return m_public_seed;
184  }
185 
186  std::string algo_name() const override
187  {
188  return "XMSS";
189  }
190 
192  {
194  }
195 
196  bool check_key(RandomNumberGenerator&, bool) const override
197  {
198  return true;
199  }
200 
201  std::unique_ptr<PK_Ops::Verification>
202  create_verification_op(const std::string&,
203  const std::string& provider) const override;
204 
205  size_t estimated_strength() const override
206  {
207  return m_xmss_params.estimated_strength();
208  }
209 
210  size_t key_length() const override
211  {
212  return m_xmss_params.estimated_strength();
213  }
214 
215  /**
216  * Returns the encoded public key as defined in RFC
217  * draft-vangeest-x509-hash-sigs-03.
218  *
219  * @return encoded public key bits
220  **/
221  std::vector<uint8_t> public_key_bits() const override;
222 
223  /**
224  * Size in bytes of the serialized XMSS public key produced by
225  * raw_public_key().
226  *
227  * @return size in bytes of serialized Public Key.
228  **/
229  virtual size_t size() const
230  {
231  return sizeof(uint32_t) + 2 * m_xmss_params.element_size();
232  }
233 
234  /**
235  * Generates a byte sequence representing the XMSS
236  * public key, as defined in [1] (p. 23, "XMSS Public Key")
237  *
238  * @return 4-byte OID, followed by n-byte root node, followed by
239  * public seed.
240  **/
241  virtual std::vector<uint8_t> raw_public_key() const;
242 
243  protected:
244  std::vector<uint8_t> m_raw_key;
249 
250  private:
251  XMSS_Parameters::xmss_algorithm_t deserialize_xmss_oid(
252  const std::vector<uint8_t>& raw_key);
253  };
254 
255 template<typename> class Atomic;
256 
257 class XMSS_Index_Registry;
258 
259 /**
260  * An XMSS: Extended Hash-Based Signature private key.
261  * The XMSS private key does not support the X509 and PKCS7 standard. Instead
262  * the raw format described in [1] is used.
263  *
264  * [1] XMSS: Extended Hash-Based Signatures,
265  * Request for Comments: 8391
266  * Release: May 2018.
267  * https://datatracker.ietf.org/doc/rfc8391/
268  **/
270  public virtual Private_Key
271  {
272  public:
273  /**
274  * Creates a new XMSS private key for the chosen XMSS signature method.
275  * New seeds for public/private key and pseudo random function input are
276  * generated using the provided RNG. The appropriate WOTS signature method
277  * will be automatically set based on the chosen XMSS signature method.
278  *
279  * @param xmss_algo_id Identifier for the selected XMSS signature method.
280  * @param rng A random number generator to use for key generation.
281  **/
283  RandomNumberGenerator& rng);
284 
285  /**
286  * Creates an XMSS_PrivateKey from a byte sequence produced by
287  * raw_private_key().
288  *
289  * @param raw_key An XMSS private key serialized using raw_private_key().
290  **/
291  XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key);
292 
293  /**
294  * Creates a new XMSS private key for the chosen XMSS signature method
295  * using precomputed seeds for public/private keys and pseudo random
296  * function input. The appropriate WOTS signature method will be
297  * automatically set, based on the chosen XMSS signature method.
298  *
299  * @param xmss_algo_id Identifier for the selected XMSS signature method.
300  * @param idx_leaf Index of the next unused leaf.
301  * @param wots_priv_seed A seed to generate a Winternitz-One-Time-
302  * Signature private key from.
303  * @param prf a secret n-byte key sourced from a secure source
304  * of uniformly random data.
305  * @param root Root node of the binary hash tree.
306  * @param public_seed The public seed.
307  **/
309  size_t idx_leaf,
310  const secure_vector<uint8_t>& wots_priv_seed,
311  const secure_vector<uint8_t>& prf,
312  const secure_vector<uint8_t>& root,
313  const secure_vector<uint8_t>& public_seed);
314 
315  bool stateful_operation() const override { return true; }
316 
317  /**
318  * Retrieves the last unused leaf index of the private key. Reusing a leaf
319  * by utilizing leaf indices lower than the last unused leaf index will
320  * compromise security.
321  *
322  * @return Index of the last unused leaf.
323  **/
324  size_t unused_leaf_index() const;
325 
326  /**
327  * Sets the last unused leaf index of the private key. The leaf index
328  * will be updated automatically during every signing operation, and
329  * should not be set manually.
330  *
331  * @param idx Index of the last unused leaf.
332  **/
333  void set_unused_leaf_index(size_t idx);
334 
335  size_t reserve_unused_leaf_index();
336 
337  /**
338  * Winternitz One Time Signature Scheme key utilized for signing
339  * operations.
340  *
341  * @return WOTS+ private key.
342  **/
344  {
345  return m_wots_priv_key;
346  }
347 
348  /**
349  * Winternitz One Time Signature Scheme key utilized for signing
350  * operations.
351  *
352  * @return WOTS+ private key.
353  **/
355  {
356  return m_wots_priv_key;
357  }
358 
360  {
361  return m_prf;
362  }
363 
365  {
366  return m_prf;
367  }
368 
370  const secure_vector<uint8_t>& public_seed) override
371  {
372  m_public_seed = public_seed;
373  m_wots_priv_key.set_public_seed(public_seed);
374  }
375 
376  void set_public_seed(secure_vector<uint8_t>&& public_seed) override
377  {
378  m_public_seed = std::move(public_seed);
379  m_wots_priv_key.set_public_seed(m_public_seed);
380  }
381 
382  const secure_vector<uint8_t>& public_seed() const override
383  {
384  return m_public_seed;
385  }
386 
387  std::unique_ptr<PK_Ops::Signature>
388  create_signature_op(RandomNumberGenerator&,
389  const std::string&,
390  const std::string& provider) const override;
391 
392  secure_vector<uint8_t> private_key_bits() const override;
393 
394  size_t size() const override
395  {
396  return XMSS_PublicKey::size() +
397  sizeof(uint32_t) +
398  2 * XMSS_PublicKey::m_xmss_params.element_size();
399  }
400 
401  /**
402  * Generates a non standartized byte sequence representing the XMSS
403  * private key.
404  *
405  * @return byte sequence consisting of the following elements in order:
406  * 4-byte OID, n-byte root node, n-byte public seed,
407  * 8-byte unused leaf index, n-byte prf seed, n-byte private seed.
408  **/
409  secure_vector<uint8_t> raw_private_key() const;
410  /**
411  * Algorithm 9: "treeHash"
412  * Computes the internal n-byte nodes of a Merkle tree.
413  *
414  * @param start_idx The start index.
415  * @param target_node_height Height of the target node.
416  * @param adrs Address of the tree containing the target node.
417  *
418  * @return The root node of a tree of height target_node height with the
419  * leftmost leaf being the hash of the WOTS+ pk with index
420  * start_idx.
421  **/
422  secure_vector<uint8_t> tree_hash(
423  size_t start_idx,
424  size_t target_node_height,
425  XMSS_Address& adrs);
426 
427  private:
428  /**
429  * Fetches shared unused leaf index from the index registry
430  **/
431  std::shared_ptr<Atomic<size_t>> recover_global_leaf_index() const;
432 
433  inline void tree_hash_subtree(secure_vector<uint8_t>& result,
434  size_t start_idx,
435  size_t target_node_height,
436  XMSS_Address& adrs)
437  {
438  return tree_hash_subtree(result, start_idx, target_node_height, adrs, m_hash);
439  }
440 
441 
442  /**
443  * Helper for multithreaded tree hashing.
444  */
445  void tree_hash_subtree(secure_vector<uint8_t>& result,
446  size_t start_idx,
447  size_t target_node_height,
448  XMSS_Address& adrs,
449  XMSS_Hash& hash);
450 
451  XMSS_WOTS_PrivateKey m_wots_priv_key;
452  XMSS_Hash m_hash;
453  secure_vector<uint8_t> m_prf;
454  XMSS_Index_Registry& m_index_reg;
455  };
456 
457 }
458 
459 #endif
const secure_vector< uint8_t > & public_seed() const override
Definition: xmss.h:382
secure_vector< uint8_t > m_public_seed
Definition: xmss.h:248
XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid, const secure_vector< uint8_t > &root, const secure_vector< uint8_t > &public_seed)
Definition: xmss.h:63
virtual void set_public_seed(const secure_vector< uint8_t > &public_seed)
Definition: xmss.h:171
std::string xmss_hash_function() const
Definition: xmss.h:119
secure_vector< uint8_t > m_root
Definition: xmss.h:247
void set_public_seed(const secure_vector< uint8_t > &public_seed) override
Definition: xmss.h:369
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
void set_root(const secure_vector< uint8_t > &root)
Definition: xmss.h:151
Definition: bigint.h:1143
void set_root(secure_vector< uint8_t > &&root)
Definition: xmss.h:156
virtual void set_public_seed(secure_vector< uint8_t > &&public_seed)
Definition: xmss.h:176
const XMSS_Parameters & xmss_parameters() const
Definition: xmss.h:108
const secure_vector< uint8_t > & root() const
Definition: xmss.h:161
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
size_t size() const override
Definition: xmss.h:394
void set_public_seed(secure_vector< uint8_t > &&public_seed) override
Definition: xmss.h:376
void set_xmss_oid(XMSS_Parameters::xmss_algorithm_t xmss_oid)
Definition: xmss.h:96
secure_vector< uint8_t > & root()
Definition: xmss.h:146
virtual size_t size() const
Definition: xmss.h:229
size_t key_length() const override
Definition: xmss.h:210
virtual const secure_vector< uint8_t > & public_seed() const
Definition: xmss.h:181
Definition: alg_id.cpp:13
XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid, secure_vector< uint8_t > &&root, secure_vector< uint8_t > &&public_seed)
Definition: xmss.h:77
bool stateful_operation() const override
Definition: xmss.h:315
const XMSS_WOTS_Parameters & wots_parameters() const
Definition: xmss.h:141
const secure_vector< uint8_t > & prf() const
Definition: xmss.h:359
AlgorithmIdentifier algorithm_identifier() const override
Definition: xmss.h:191
std::string algo_name() const override
Definition: xmss.h:186
size_t estimated_strength() const override
Definition: xmss.h:205
XMSS_Parameters::xmss_algorithm_t xmss_oid() const
Definition: xmss.h:88
XMSS_WOTS_Parameters m_wots_params
Definition: xmss.h:246
virtual secure_vector< uint8_t > & public_seed()
Definition: xmss.h:166
XMSS_Parameters m_xmss_params
Definition: xmss.h:245
std::unique_ptr< HashFunction > m_hash
Definition: tpm.cpp:446
XMSS_WOTS_Parameters::ots_algorithm_t wots_oid() const
Definition: xmss.h:130
std::vector< uint8_t > m_raw_key
Definition: xmss.h:244
XMSS_WOTS_PrivateKey & wots_private_key()
Definition: xmss.h:354
const XMSS_WOTS_PrivateKey & wots_private_key() const
Definition: xmss.h:343
bool check_key(RandomNumberGenerator &, bool) const override
Definition: xmss.h:196
MechanismType hash
secure_vector< uint8_t > & prf()
Definition: xmss.h:364