Coverage Report

Created: 2023-02-13 06:21

/src/botan/build/include/botan/xmss_wots.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * XMSS WOTS
3
 * (C) 2016,2018 Matthias Gierlings
4
 *
5
 * Botan is released under the Simplified BSD License (see license.txt)
6
 **/
7
8
#ifndef BOTAN_XMSS_WOTS_H_
9
#define BOTAN_XMSS_WOTS_H_
10
11
#include <botan/asn1_obj.h>
12
#include <botan/exceptn.h>
13
#include <botan/pk_keys.h>
14
#include <botan/rng.h>
15
#include <botan/secmem.h>
16
#include <botan/xmss_hash.h>
17
#include <map>
18
#include <memory>
19
#include <string>
20
#include <vector>
21
22
namespace Botan {
23
24
/**
25
 * Descibes a signature method for XMSS Winternitz One Time Signatures,
26
 * as defined in:
27
 * [1] XMSS: Extended Hash-Based Signatures,
28
 *     Request for Comments: 8391
29
 *     Release: May 2018.
30
 *     https://datatracker.ietf.org/doc/rfc8391/
31
 **/
32
class BOTAN_PUBLIC_API(2,0) XMSS_WOTS_Parameters final
33
   {
34
   public:
35
      enum ots_algorithm_t
36
         {
37
         WOTSP_SHA2_256 = 0x00000001,
38
         WOTSP_SHA2_512 = 0x00000002,
39
         WOTSP_SHAKE_256 = 0x00000003,
40
         WOTSP_SHAKE_512 = 0x00000004
41
         };
42
43
      XMSS_WOTS_Parameters(const std::string& algo_name);
44
      XMSS_WOTS_Parameters(ots_algorithm_t ots_spec);
45
46
      static ots_algorithm_t xmss_wots_id_from_string(const std::string& param_set);
47
48
      /**
49
       * Algorithm 1: convert input string to base.
50
       *
51
       * @param msg Input string (referred to as X in [1]).
52
       * @param out_size size of message in base w.
53
       *
54
       * @return Input string converted to the given base.
55
       **/
56
      secure_vector<uint8_t> base_w(const secure_vector<uint8_t>& msg, size_t out_size) const;
57
58
      secure_vector<uint8_t> base_w(size_t value) const;
59
60
      void append_checksum(secure_vector<uint8_t>& data) const;
61
62
      /**
63
       * @return XMSS WOTS registry name for the chosen parameter set.
64
       **/
65
      const std::string& name() const
66
0
         {
67
0
         return m_name;
68
0
         }
69
70
      /**
71
       * @return Botan name for the hash function used.
72
       **/
73
      const std::string& hash_function_name() const
74
0
         {
75
0
         return m_hash_name;
76
0
         }
77
78
      /**
79
       * Retrieves the uniform length of a message, and the size of
80
       * each node. This correlates to XMSS parameter "n" defined
81
       * in [1].
82
       *
83
       * @return element length in bytes.
84
       **/
85
0
      size_t element_size() const { return m_element_size; }
86
87
      /**
88
       * The Winternitz parameter.
89
       *
90
       * @return numeric base used for internal representation of
91
       *         data.
92
       **/
93
0
      size_t wots_parameter() const { return m_w; }
94
95
0
      size_t len() const { return m_len; }
96
97
0
      size_t len_1() const { return m_len_1; }
98
99
0
      size_t len_2() const { return m_len_2; }
100
101
0
      size_t lg_w() const { return m_lg_w; }
102
103
0
      ots_algorithm_t oid() const { return m_oid; }
104
105
0
      size_t estimated_strength() const { return m_strength; }
106
107
      bool operator==(const XMSS_WOTS_Parameters& p) const
108
0
         {
109
0
         return m_oid == p.m_oid;
110
0
         }
111
112
   private:
113
      static const std::map<std::string, ots_algorithm_t> m_oid_name_lut;
114
      ots_algorithm_t m_oid;
115
      std::string m_name;
116
      std::string m_hash_name;
117
      size_t m_element_size;
118
      size_t m_w;
119
      size_t m_len_1;
120
      size_t m_len_2;
121
      size_t m_len;
122
      size_t m_strength;
123
      uint8_t m_lg_w;
124
   };
125
126
class XMSS_Address;
127
128
typedef std::vector<secure_vector<uint8_t>> wots_keysig_t;
129
130
/**
131
 * A Winternitz One Time Signature public key for use with Extended Hash-Based
132
 * Signatures.
133
 **/
134
class BOTAN_PUBLIC_API(2,0) XMSS_WOTS_PublicKey : virtual public Public_Key
135
   {
136
   public:
137
      class TreeSignature final
138
         {
139
         public:
140
0
            TreeSignature() = default;
141
142
            TreeSignature(wots_keysig_t ots_sig,
143
                          wots_keysig_t auth_path)
144
               : m_ots_sig(std::move(ots_sig)),
145
                 m_auth_path(std::move(auth_path))
146
0
               {}
147
148
            const wots_keysig_t& ots_signature() const
149
0
               {
150
0
               return m_ots_sig;
151
0
               }
152
153
            wots_keysig_t& ots_signature()
154
0
               {
155
0
               return m_ots_sig;
156
0
               }
157
158
            const wots_keysig_t& authentication_path() const
159
0
               {
160
0
               return m_auth_path;
161
0
               }
162
163
            wots_keysig_t& authentication_path()
164
0
               {
165
0
               return m_auth_path;
166
0
               }
167
168
         private:
169
            wots_keysig_t m_ots_sig;
170
            wots_keysig_t m_auth_path;
171
         };
172
173
      /**
174
       * Creates a XMSS_WOTS_PublicKey for the signature method identified by
175
       * oid. The public seed for this key will be initialized with a
176
       * uniformly random n-byte value, where "n" is the element size of the
177
       * selected signature method.
178
       *
179
       * @param oid Identifier for the selected signature method.
180
       **/
181
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)
182
         : m_wots_params(oid),
183
0
           m_hash(m_wots_params.hash_function_name()) {}
184
185
      /**
186
       * Creates a XMSS_WOTS_PublicKey for the signature method identified by
187
       * oid. The public seed for this key will be initialized with a
188
       * uniformly random n-byte value, where "n" is the element size of the
189
       * selected signature method.
190
       *
191
       * @param oid Identifier for the selected signature method.
192
       * @param rng A random number generate used to generate the public seed.
193
       **/
194
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
195
                          RandomNumberGenerator& rng)
196
         : m_wots_params(oid),
197
           m_hash(m_wots_params.hash_function_name()),
198
0
           m_public_seed(rng.random_vec(m_wots_params.element_size())) {}
199
200
      /**
201
       * Creates a XMSS_WOTS_PrivateKey for the signature method identified by
202
       * oid, with a precomputed public seed.
203
       *
204
       * @param oid Identifier for the selected signature method.
205
       * @param public_seed A precomputed public seed of n-bytes length.
206
       **/
207
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
208
                          secure_vector<uint8_t> public_seed)
209
         : m_wots_params(oid),
210
           m_hash(m_wots_params.hash_function_name()),
211
0
           m_public_seed(std::move(public_seed)) {}
Unexecuted instantiation: Botan::XMSS_WOTS_PublicKey::XMSS_WOTS_PublicKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >)
Unexecuted instantiation: Botan::XMSS_WOTS_PublicKey::XMSS_WOTS_PublicKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >)
212
213
      /**
214
       * Creates a XMSS_WOTS_PublicKey for the signature method identified by
215
       * oid. The public seed will be initialized with a precomputed seed and
216
       * and precomputed key data which should be derived from a
217
       * XMSS_WOTS_PrivateKey.
218
       *
219
       * @param oid Ident:s/ifier for the selected signature methods.
220
       * @param public_seed A precomputed public seed of n-bytes length.
221
       * @param key Precomputed raw key data of the XMSS_WOTS_PublicKey.
222
       **/
223
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
224
                          secure_vector<uint8_t> public_seed,
225
                          wots_keysig_t key)
226
         : m_wots_params(oid),
227
           m_hash(m_wots_params.hash_function_name()),
228
           m_key(std::move(key)),
229
           m_public_seed(std::move(public_seed))
230
0
         {}
231
232
      /**
233
       * Creates a XMSS_WOTS_PublicKey from a message and signature using
234
       * Algorithm 6 WOTS_pkFromSig defined in the XMSS standard. This
235
       * overload is used to verify a message using a public key.
236
       *
237
       * @param oid WOTSP algorithm identifier.
238
       * @param msg A message.
239
       * @param sig A WOTS signature for msg.
240
       * @param adrs An XMSS_Address.
241
       * @param public_seed The public public_seed.
242
       **/
243
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
244
                          const secure_vector<uint8_t>& msg,
245
                          const wots_keysig_t& sig,
246
                          XMSS_Address& adrs,
247
                          const secure_vector<uint8_t>& public_seed)
248
         : m_wots_params(oid),
249
           m_hash(m_wots_params.hash_function_name()),
250
           m_key(pub_key_from_signature(msg,
251
                                        sig,
252
                                        adrs,
253
                                        public_seed)),
254
           m_public_seed(public_seed)
255
0
         {}
Unexecuted instantiation: Botan::XMSS_WOTS_PublicKey::XMSS_WOTS_PublicKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, std::__1::vector<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, std::__1::allocator<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > > > const&, Botan::XMSS_Address&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Unexecuted instantiation: Botan::XMSS_WOTS_PublicKey::XMSS_WOTS_PublicKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, std::__1::vector<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, std::__1::allocator<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > > > const&, Botan::XMSS_Address&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
256
257
      /**
258
       * Retrieves the i-th element out of the length len chain of
259
       * n-byte elements contained in the public key.
260
       *
261
       * @param i index of the element.
262
       * @returns n-byte element addressed by i.
263
       **/
264
0
      const secure_vector<uint8_t>& operator[](size_t i) const { return m_key[i]; }
265
0
      secure_vector<uint8_t>& operator[](size_t i) { return m_key[i]; }
266
267
      /**
268
       * Convert the key into the raw key data. The key becomes a length
269
       * len vector of n-byte elements.
270
       **/
271
0
      operator const wots_keysig_t& () const { return m_key; }
272
273
      /**
274
       * Convert the key into the raw key data. The key becomes a length
275
       * len vector of n-byte elements.
276
       **/
277
0
      operator wots_keysig_t& () { return m_key; }
278
279
0
      const secure_vector<uint8_t>& public_seed() const { return m_public_seed; }
280
281
0
      secure_vector<uint8_t>& public_seed() { return m_public_seed; }
282
283
      void set_public_seed(secure_vector<uint8_t> public_seed)
284
0
         {
285
0
         m_public_seed = std::move(public_seed);
286
0
         }
287
288
0
      const wots_keysig_t& key_data() const { return m_key; }
289
290
0
      wots_keysig_t& key_data() { return m_key; }
291
292
      void set_key_data(wots_keysig_t key_data)
293
0
         {
294
0
         m_key = std::move(key_data);
295
0
         }
296
297
      const XMSS_WOTS_Parameters& wots_parameters() const
298
0
         {
299
0
         return m_wots_params;
300
0
         }
301
302
      std::string algo_name() const override
303
0
         {
304
0
         return m_wots_params.name();
305
0
         }
306
307
      AlgorithmIdentifier algorithm_identifier() const override
308
0
         {
309
0
         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");
310
0
         }
311
312
      bool check_key(RandomNumberGenerator&, bool) const override
313
0
         {
314
0
         return true;
315
0
         }
316
317
      size_t estimated_strength() const override
318
0
         {
319
0
         return m_wots_params.estimated_strength();
320
0
         }
321
322
      size_t key_length() const override
323
0
         {
324
0
         return m_wots_params.estimated_strength();
325
0
         }
326
327
      std::vector<uint8_t> public_key_bits() const override
328
0
         {
329
0
         throw Not_Implemented("No key format defined for XMSS-WOTS");
330
0
         }
331
332
      bool operator==(const XMSS_WOTS_PublicKey& key)
333
0
         {
334
0
         return m_key == key.m_key;
335
0
         }
336
337
      bool operator!=(const XMSS_WOTS_PublicKey& key)
338
0
         {
339
0
         return !(*this == key);
340
0
         }
341
342
   protected:
343
      /**
344
       * Algorithm 2: Chaining Function.
345
       *
346
       * Takes an n-byte input string and transforms it into a the function
347
       * result iterating the cryptographic hash function "F" steps times on
348
       * the input x using the outputs of the PRNG "G".
349
       *
350
       * This overload is used in multithreaded scenarios, where it is
351
       * required to provide seperate instances of XMSS_Hash to each
352
       * thread.
353
       *
354
       * @param[out] x An n-byte input string, that will be transformed into
355
       *               the chaining function result.
356
       * @param start_idx The start index.
357
       * @param steps A number of steps.
358
       * @param adrs An OTS Hash Address.
359
       * @param public_seed A public seed.
360
       * @param hash Instance of XMSS_Hash, that may only by the thread
361
       *        executing chain.
362
       **/
363
      void chain(secure_vector<uint8_t>& x,
364
                 size_t start_idx,
365
                 size_t steps,
366
                 XMSS_Address& adrs,
367
                 const secure_vector<uint8_t>& public_seed,
368
                 XMSS_Hash& hash);
369
370
      /**
371
       * Algorithm 2: Chaining Function.
372
       *
373
       * Takes an n-byte input string and transforms it into a the function
374
       * result iterating the cryptographic hash function "F" steps times on
375
       * the input x using the outputs of the PRNG "G".
376
       *
377
       * @param[out] x An n-byte input string, that will be transformed into
378
       *               the chaining function result.
379
       * @param start_idx The start index.
380
       * @param steps A number of steps.
381
       * @param adrs An OTS Hash Address.
382
       * @param public_seed A public seed.
383
       **/
384
      inline void chain(secure_vector<uint8_t>& x,
385
                        size_t start_idx,
386
                        size_t steps,
387
                        XMSS_Address& adrs,
388
                        const secure_vector<uint8_t>& public_seed)
389
0
         {
390
0
         chain(x, start_idx, steps, adrs, public_seed, m_hash);
391
0
         }
392
393
      XMSS_WOTS_Parameters m_wots_params;
394
      XMSS_Hash m_hash;
395
      wots_keysig_t m_key;
396
      secure_vector<uint8_t> m_public_seed;
397
398
   private:
399
      /**
400
       * Algorithm 6: "WOTS_pkFromSig"
401
       * Computes a Winternitz One Time Signature+ public key from a message and
402
       * its signature.
403
       *
404
       * @param msg A message.
405
       * @param sig The signature for msg.
406
       * @param adrs An address.
407
       * @param public_seed A public_seed.
408
       *
409
       * @return Temporary WOTS+ public key.
410
       **/
411
      wots_keysig_t pub_key_from_signature(
412
         const secure_vector<uint8_t>& msg,
413
         const wots_keysig_t& sig,
414
         XMSS_Address& adrs,
415
         const secure_vector<uint8_t>& public_seed);
416
   };
417
418
/** A Winternitz One Time Signature private key for use with Extended Hash-Based
419
 * Signatures.
420
 **/
421
class BOTAN_PUBLIC_API(2,0) XMSS_WOTS_PrivateKey final : public virtual XMSS_WOTS_PublicKey,
422
   public virtual Private_Key
423
   {
424
   public:
425
      /**
426
       * Creates a WOTS private key for the chosen XMSS WOTS signature method.
427
       * Members need to be initialized manually.
428
       *
429
       * @param oid Identifier for the selected signature method.
430
       **/
431
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)
432
         : XMSS_WOTS_PublicKey(oid)
433
0
         {}
434
435
      /**
436
       * Creates a WOTS private key for the chosen XMSS WOTS signature method.
437
       *
438
       * @param oid Identifier for the selected signature method.
439
       * @param rng A random number generator to use for key generation.
440
       **/
441
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
442
                           RandomNumberGenerator& rng)
443
         : XMSS_WOTS_PublicKey(oid, rng),
444
           m_private_seed(rng.random_vec(m_wots_params.element_size()))
445
0
         {
446
0
         set_key_data(generate(m_private_seed));
447
0
         }
448
449
      /**
450
       * Constructs a WOTS private key. Chains will be generated on demand
451
       * applying a hash function to a unique value generated from a secret
452
       * seed and a counter. The secret seed of length n, will be
453
       * automatically generated using @p rng. "n" equals
454
       * the element size of the chosen WOTS security parameter set.
455
       *
456
       * @param oid Identifier for the selected signature method.
457
       * @param public_seed A public seed used for the pseudo random generation
458
       *        of public keys derived from this private key.
459
       * @param rng A random number generator to use for key generation.
460
       **/
461
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
462
                           secure_vector<uint8_t> public_seed,
463
                           RandomNumberGenerator& rng)
464
         : XMSS_WOTS_PublicKey(oid, std::move(public_seed)),
465
           m_private_seed(rng.random_vec(m_wots_params.element_size()))
466
0
         {
467
0
         set_key_data(generate(m_private_seed));
468
0
         }
Unexecuted instantiation: Botan::XMSS_WOTS_PrivateKey::XMSS_WOTS_PrivateKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::RandomNumberGenerator&)
Unexecuted instantiation: Botan::XMSS_WOTS_PrivateKey::XMSS_WOTS_PrivateKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, Botan::RandomNumberGenerator&)
469
470
      /**
471
       * Constructs a WOTS private key. Chains will be generated on demand
472
       * applying a hash function to a unique value generated from a secret
473
       * seed and a counter. The secret seed of length n, will be
474
       * automatically generated using AutoSeeded_RNG(). "n" equals
475
       * the element size of the chosen WOTS security parameter set.
476
       *
477
       * @param oid Identifier for the selected signature method.
478
       * @param public_seed A public seed used for the pseudo random generation
479
       *        of public keys derived from this private key.
480
       **/
481
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
482
                           secure_vector<uint8_t> public_seed)
483
         : XMSS_WOTS_PublicKey(oid, std::move(public_seed))
484
0
         {}
Unexecuted instantiation: Botan::XMSS_WOTS_PrivateKey::XMSS_WOTS_PrivateKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >)
Unexecuted instantiation: Botan::XMSS_WOTS_PrivateKey::XMSS_WOTS_PrivateKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >)
485
486
      /**
487
       * Constructs a WOTS private key. Chains will be generated on demand
488
       * applying a hash function to a unique value generated from the
489
       * secret seed and a counter.
490
       *
491
       * @param oid Identifier for the selected signature method.
492
       * @param public_seed A public seed used for the pseudo random generation
493
       *        of public keys derived from this private key.
494
       * @param private_seed A secret uniformly random n-byte value.
495
       **/
496
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
497
                           secure_vector<uint8_t> public_seed,
498
                           secure_vector<uint8_t> private_seed)
499
         : XMSS_WOTS_PublicKey(oid, std::move(public_seed)),
500
           m_private_seed(std::move(private_seed))
501
0
         {
502
0
         set_key_data(generate(private_seed));
503
0
         }
Unexecuted instantiation: Botan::XMSS_WOTS_PrivateKey::XMSS_WOTS_PrivateKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >)
Unexecuted instantiation: Botan::XMSS_WOTS_PrivateKey::XMSS_WOTS_PrivateKey(Botan::XMSS_WOTS_Parameters::ots_algorithm_t, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >)
504
505
      std::unique_ptr<Public_Key> public_key() const override
506
0
         {
507
0
         throw Not_Implemented("Not possible to derive WOTS public key from private key");
508
0
         }
509
510
      /**
511
       * Retrieves the i-th WOTS private key using pseudo random key
512
       * (re-)generation.
513
       *
514
       * This overload is used in multithreaded scenarios, where it is
515
       * required to provide seperate instances of XMSS_Hash to each
516
       * thread.
517
       *
518
       * @param i Index of the key to retrieve.
519
       * @param hash Instance of XMSS_Hash, that may only be used by the
520
       *        thread executing at.
521
       *
522
       * @return WOTS secret key.
523
       **/
524
      wots_keysig_t at(size_t i, XMSS_Hash& hash);
525
526
      /**
527
       * Retrieves the i-th WOTS private key using pseudo random key
528
       * (re-)generation.
529
       *
530
       * @param i Index of the key to retrieve.
531
       *
532
       * @return WOTS secret key.
533
       **/
534
      inline wots_keysig_t operator[](size_t i)
535
0
         {
536
0
         return this->at(i, m_hash);
537
0
         }
538
539
      /**
540
       * Retrieves the i-th WOTS private key using pseudo random key
541
       * (re-)generation.
542
       *
543
       * This overload is used in multithreaded scenarios, where it is
544
       * required to provide seperate instances of XMSS_Hash to each
545
       * thread.
546
       *
547
       * @param adrs The address of the key to retrieve.
548
       * @param hash Instance of XMSS_Hash, that may only be used by the
549
       *        thread executing at.
550
       *
551
       * @return WOTS secret key.
552
       **/
553
      wots_keysig_t at(const XMSS_Address& adrs, XMSS_Hash& hash);
554
555
      inline wots_keysig_t operator[](const XMSS_Address& adrs)
556
0
         {
557
0
         return this->at(adrs, m_hash);
558
0
         }
559
560
      wots_keysig_t generate_private_key(const secure_vector<uint8_t>& priv_seed);
561
562
      /**
563
       * Algorithm 4: "WOTS_genPK"
564
       * Generates a Winternitz One Time Signature+ (WOTS+) Public Key from a
565
       * given private key.
566
       *
567
       * @param adrs Hash function address encoding the address of the WOTS+
568
       *             key pair within a greater structure.
569
       *
570
       * @return A XMSS_WOTS_PublicKey.
571
       **/
572
      XMSS_WOTS_PublicKey generate_public_key(XMSS_Address& adrs);
573
574
      /**
575
       * Algorithm 4: "WOTS_genPK"
576
       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's
577
       * key_data() member, with data derived from in_key_data using the
578
       * WOTS chaining function.
579
       *
580
       * This overload is used in multithreaded scenarios, where it is
581
       * required to provide seperate instances of XMSS_Hash to each
582
       * thread.
583
       *
584
       * @param[out] pub_key Public key to initialize key_data() member on.
585
       * @param in_key_data Input key material from private key used for
586
       *        public key generation.
587
       * @param adrs Hash function address encoding the address of
588
       *        the WOTS+ key pair within a greater structure.
589
       * @param hash Instance of XMSS_Hash, that may only by the thread
590
       *        executing generate_public_key.
591
       **/
592
      void generate_public_key(XMSS_WOTS_PublicKey& pub_key,
593
                               wots_keysig_t in_key_data,
594
                               XMSS_Address& adrs,
595
                               XMSS_Hash& hash);
596
      /**
597
       * Algorithm 4: "WOTS_genPK"
598
       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's
599
       * key_data() member, with data derived from in_key_data using the
600
       * WOTS chaining function.
601
       *
602
       * @param[out] pub_key Public key to initialize key_data() member on.
603
       * @param in_key_data Input key material from private key used for
604
       *        public key generation.
605
       * @param adrs Hash function address encoding the address of
606
       *        the WOTS+ key pair within a greater structure.
607
       **/
608
      inline void generate_public_key(XMSS_WOTS_PublicKey& pub_key,
609
                                      wots_keysig_t in_key_data,
610
                                      XMSS_Address& adrs)
611
0
         {
612
0
         generate_public_key(pub_key, std::move(in_key_data), adrs, m_hash);
613
0
         }
614
615
      /**
616
       * Algorithm 5: "WOTS_sign"
617
       * Generates a signature from a private key and a message.
618
       *
619
       * @param msg A message to sign.
620
       * @param adrs An OTS hash address identifying the WOTS+ key pair
621
       *        used for signing.
622
       *
623
       * @return signature for msg.
624
       **/
625
      inline wots_keysig_t sign(const secure_vector<uint8_t>& msg,
626
                                XMSS_Address& adrs)
627
0
         {
628
0
         return sign(msg, adrs, m_hash);
629
0
         }
630
631
      /**
632
       * Algorithm 5: "WOTS_sign"
633
       * Generates a signature from a private key and a message.
634
       *
635
       * This overload is used in multithreaded scenarios, where it is
636
       * required to provide seperate instances of XMSS_Hash to each
637
       * thread.
638
       *
639
       * @param msg A message to sign.
640
       * @param adrs An OTS hash address identifying the WOTS+ key pair
641
       *        used for signing.
642
       * @param hash Instance of XMSS_Hash, that may only be used by the
643
       *        thread executing sign.
644
       *
645
       * @return signature for msg.
646
       **/
647
      wots_keysig_t sign(const secure_vector<uint8_t>& msg,
648
                         XMSS_Address& adrs,
649
                         XMSS_Hash& hash);
650
651
      /**
652
       * Retrieves the secret seed used to generate WOTS+ chains. The seed
653
       * should be a uniformly random n-byte value.
654
       *
655
       * @return secret seed.
656
       **/
657
      const secure_vector<uint8_t>& private_seed() const
658
0
         {
659
0
         return m_private_seed;
660
0
         }
661
662
      /**
663
       * Sets the secret seed used to generate WOTS+ chains. The seed
664
       * should be a uniformly random n-byte value.
665
       *
666
       * @param private_seed Uniformly random n-byte value.
667
       **/
668
      void set_private_seed(secure_vector<uint8_t> private_seed)
669
0
         {
670
0
         m_private_seed = std::move(private_seed);
671
0
         }
672
673
      AlgorithmIdentifier
674
      pkcs8_algorithm_identifier() const override
675
0
         {
676
0
         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");
677
0
         }
678
679
      secure_vector<uint8_t> private_key_bits() const override
680
0
         {
681
0
         throw Not_Implemented("No PKCS8 key format defined for XMSS-WOTS.");
682
0
         }
683
684
   private:
685
      /**
686
       * Algorithm 3: "Generating a WOTS+ Private Key".
687
       * Generates a private key.
688
       *
689
       * This overload is used in multithreaded scenarios, where it is
690
       * required to provide seperate instances of XMSS_Hash to each thread.
691
       *
692
       * @param private_seed Uniformly random n-byte value.
693
       * @param[in] hash Instance of XMSS_Hash, that may only be used by the
694
       *            thread executing generate.
695
       *
696
       * @returns a vector of length key_size() of vectors of n bytes length
697
       *          containing uniformly random data.
698
       **/
699
      wots_keysig_t generate(const secure_vector<uint8_t>& private_seed,
700
                             XMSS_Hash& hash);
701
702
      inline wots_keysig_t generate(const secure_vector<uint8_t>& private_seed)
703
0
         {
704
0
         return generate(private_seed, m_hash);
705
0
         }
706
707
      secure_vector<uint8_t> m_private_seed;
708
   };
709
710
}
711
712
#endif