Coverage Report

Created: 2021-10-13 08:49

/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 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);
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 XMSS_WOTS_PublicKey : virtual public Public_Key
135
   {
136
   public:
137
      class TreeSignature final
138
         {
139
         public:
140
0
            TreeSignature() = default;
141
142
            TreeSignature(const wots_keysig_t& ots_sig,
143
                          const wots_keysig_t& auth_path)
144
               : m_ots_sig(ots_sig), m_auth_path(auth_path)
145
0
               {}
146
147
            TreeSignature(wots_keysig_t&& ots_sig,
148
                          wots_keysig_t&& auth_path)
149
               : m_ots_sig(std::move(ots_sig)),
150
                 m_auth_path(std::move(auth_path))
151
0
               {}
152
153
            const wots_keysig_t& ots_signature() const
154
0
               {
155
0
               return m_ots_sig;
156
0
               }
157
158
            wots_keysig_t& ots_signature()
159
0
               {
160
0
               return m_ots_sig;
161
0
               }
162
163
            const wots_keysig_t& authentication_path() const
164
0
               {
165
0
               return m_auth_path;
166
0
               }
167
168
            wots_keysig_t& authentication_path()
169
0
               {
170
0
               return m_auth_path;
171
0
               }
172
173
         private:
174
            wots_keysig_t m_ots_sig;
175
            wots_keysig_t m_auth_path;
176
         };
177
178
      /**
179
       * Creates a XMSS_WOTS_PublicKey for the signature method identified by
180
       * oid. The public seed for this key will be initialized with a
181
       * uniformly random n-byte value, where "n" is the element size of the
182
       * selected signature method.
183
       *
184
       * @param oid Identifier for the selected signature method.
185
       **/
186
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)
187
         : m_wots_params(oid),
188
0
           m_hash(m_wots_params.hash_function_name()) {}
189
190
      /**
191
       * Creates a XMSS_WOTS_PublicKey for the signature method identified by
192
       * oid. The public seed for this key will be initialized with a
193
       * uniformly random n-byte value, where "n" is the element size of the
194
       * selected signature method.
195
       *
196
       * @param oid Identifier for the selected signature method.
197
       * @param rng A random number generate used to generate the public seed.
198
       **/
199
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
200
                          RandomNumberGenerator& rng)
201
         : m_wots_params(oid),
202
           m_hash(m_wots_params.hash_function_name()),
203
0
           m_public_seed(rng.random_vec(m_wots_params.element_size())) {}
204
205
      /**
206
       * Creates a XMSS_WOTS_PrivateKey for the signature method identified by
207
       * oid, with a precomputed public seed.
208
       *
209
       * @param oid Identifier for the selected signature method.
210
       * @param public_seed A precomputed public seed of n-bytes length.
211
       **/
212
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
213
                          secure_vector<uint8_t> public_seed)
214
         : m_wots_params(oid),
215
           m_hash(m_wots_params.hash_function_name()),
216
0
           m_public_seed(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> >)
217
218
      /**
219
       * Creates a XMSS_WOTS_PublicKey for the signature method identified by
220
       * oid. The public seed will be initialized with a precomputed seed and
221
       * and precomputed key data which should be derived from a
222
       * XMSS_WOTS_PrivateKey.
223
       *
224
       * @param oid Ident:s/ifier for the selected signature methods.
225
       * @param public_seed A precomputed public seed of n-bytes length.
226
       * @param key Precomputed raw key data of the XMSS_WOTS_PublicKey.
227
       **/
228
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
229
                          secure_vector<uint8_t>&& public_seed,
230
                          wots_keysig_t&& key)
231
         : m_wots_params(oid),
232
           m_hash(m_wots_params.hash_function_name()),
233
           m_key(std::move(key)),
234
           m_public_seed(std::move(public_seed))
235
0
         {}
236
237
      /**
238
       * Creates a XMSS_WOTS_PublicKey for the signature method identified by
239
       * oid. The public seed will be initialized with a precomputed seed and
240
       * and precomputed key data which should be derived from a
241
       * XMSS_WOTS_PrivateKey.
242
       *
243
       * @param oid Identifier for the selected signature methods.
244
       * @param public_seed A precomputed public seed of n-bytes length.
245
       * @param key Precomputed raw key data of the XMSS_WOTS_PublicKey.
246
       **/
247
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
248
                          const secure_vector<uint8_t>& public_seed,
249
                          const wots_keysig_t& key)
250
         : m_wots_params(oid),
251
           m_hash(m_wots_params.hash_function_name()),
252
           m_key(key),
253
           m_public_seed(public_seed)
254
0
         {}
255
256
      /**
257
       * Creates a XMSS_WOTS_PublicKey form a message and signature using
258
       * Algorithm 6 WOTS_pkFromSig defined in the XMSS standard. This
259
       * overload is used to verify a message using a public key.
260
       *
261
       * @param oid WOTSP algorithm identifier.
262
       * @param msg A message.
263
       * @param sig A WOTS signature for msg.
264
       * @param adrs An XMSS_Address.
265
       * @param public_seed The public public_seed.
266
       **/
267
      XMSS_WOTS_PublicKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
268
                          const secure_vector<uint8_t>& msg,
269
                          const wots_keysig_t& sig,
270
                          XMSS_Address& adrs,
271
                          const secure_vector<uint8_t>& public_seed)
272
         : m_wots_params(oid),
273
           m_hash(m_wots_params.hash_function_name()),
274
           m_key(pub_key_from_signature(msg,
275
                                        sig,
276
                                        adrs,
277
                                        public_seed)),
278
           m_public_seed(public_seed)
279
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&)
280
281
      /**
282
       * Retrieves the i-th element out of the length len chain of
283
       * n-byte elements contained in the public key.
284
       *
285
       * @param i index of the element.
286
       * @returns n-byte element addressed by i.
287
       **/
288
0
      const secure_vector<uint8_t>& operator[](size_t i) const { return m_key[i]; }
289
0
      secure_vector<uint8_t>& operator[](size_t i) { return m_key[i]; }
290
291
      /**
292
       * Convert the key into the raw key data. The key becomes a length
293
       * len vector of n-byte elements.
294
       **/
295
0
      operator const wots_keysig_t& () const { return m_key; }
296
297
      /**
298
       * Convert the key into the raw key data. The key becomes a length
299
       * len vector of n-byte elements.
300
       **/
301
0
      operator wots_keysig_t& () { return m_key; }
302
303
0
      const secure_vector<uint8_t>& public_seed() const { return m_public_seed; }
304
305
0
      secure_vector<uint8_t>& public_seed() { return m_public_seed; }
306
307
      void set_public_seed(const secure_vector<uint8_t>& public_seed)
308
0
         {
309
0
         m_public_seed = public_seed;
310
0
         }
311
312
      void set_public_seed(secure_vector<uint8_t>&& public_seed)
313
0
         {
314
0
         m_public_seed = std::move(public_seed);
315
0
         }
316
317
0
      const wots_keysig_t& key_data() const { return m_key; }
318
319
0
      wots_keysig_t& key_data() { return m_key; }
320
321
      void set_key_data(const wots_keysig_t& key_data)
322
0
         {
323
0
         m_key = key_data;
324
0
         }
325
326
      void set_key_data(wots_keysig_t&& key_data)
327
0
         {
328
0
         m_key = std::move(key_data);
329
0
         }
330
331
      const XMSS_WOTS_Parameters& wots_parameters() const
332
0
         {
333
0
         return m_wots_params;
334
0
         }
335
336
      std::string algo_name() const override
337
0
         {
338
0
         return m_wots_params.name();
339
0
         }
340
341
      AlgorithmIdentifier algorithm_identifier() const override
342
0
         {
343
0
         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");
344
0
         }
345
346
      bool check_key(RandomNumberGenerator&, bool) const override
347
0
         {
348
0
         return true;
349
0
         }
350
351
      size_t estimated_strength() const override
352
0
         {
353
0
         return m_wots_params.estimated_strength();
354
0
         }
355
356
      size_t key_length() const override
357
0
         {
358
0
         return m_wots_params.estimated_strength();
359
0
         }
360
361
      std::vector<uint8_t> public_key_bits() const override
362
0
         {
363
0
         throw Not_Implemented("No key format defined for XMSS-WOTS");
364
0
         }
365
366
      bool operator==(const XMSS_WOTS_PublicKey& key)
367
0
         {
368
0
         return m_key == key.m_key;
369
0
         }
370
371
      bool operator!=(const XMSS_WOTS_PublicKey& key)
372
0
         {
373
0
         return !(*this == key);
374
0
         }
375
376
   protected:
377
      /**
378
       * Algorithm 2: Chaining Function.
379
       *
380
       * Takes an n-byte input string and transforms it into a the function
381
       * result iterating the cryptographic hash function "F" steps times on
382
       * the input x using the outputs of the PRNG "G".
383
       *
384
       * This overload is used in multithreaded scenarios, where it is
385
       * required to provide seperate instances of XMSS_Hash to each
386
       * thread.
387
       *
388
       * @param[out] x An n-byte input string, that will be transformed into
389
       *               the chaining function result.
390
       * @param start_idx The start index.
391
       * @param steps A number of steps.
392
       * @param adrs An OTS Hash Address.
393
       * @param public_seed A public seed.
394
       * @param hash Instance of XMSS_Hash, that may only by the thead
395
       *        executing chain.
396
       **/
397
      void chain(secure_vector<uint8_t>& x,
398
                 size_t start_idx,
399
                 size_t steps,
400
                 XMSS_Address& adrs,
401
                 const secure_vector<uint8_t>& public_seed,
402
                 XMSS_Hash& hash);
403
404
      /**
405
       * Algorithm 2: Chaining Function.
406
       *
407
       * Takes an n-byte input string and transforms it into a the function
408
       * result iterating the cryptographic hash function "F" steps times on
409
       * the input x using the outputs of the PRNG "G".
410
       *
411
       * @param[out] x An n-byte input string, that will be transformed into
412
       *               the chaining function result.
413
       * @param start_idx The start index.
414
       * @param steps A number of steps.
415
       * @param adrs An OTS Hash Address.
416
       * @param public_seed A public seed.
417
       **/
418
      inline void chain(secure_vector<uint8_t>& x,
419
                        size_t start_idx,
420
                        size_t steps,
421
                        XMSS_Address& adrs,
422
                        const secure_vector<uint8_t>& public_seed)
423
0
         {
424
0
         chain(x, start_idx, steps, adrs, public_seed, m_hash);
425
0
         }
426
427
      XMSS_WOTS_Parameters m_wots_params;
428
      XMSS_Hash m_hash;
429
      wots_keysig_t m_key;
430
      secure_vector<uint8_t> m_public_seed;
431
432
   private:
433
      /**
434
       * Algorithm 6: "WOTS_pkFromSig"
435
       * Computes a Winternitz One Time Signature+ public key from a message and
436
       * its signature.
437
       *
438
       * @param msg A message.
439
       * @param sig The signature for msg.
440
       * @param adrs An address.
441
       * @param public_seed A public_seed.
442
       *
443
       * @return Temporary WOTS+ public key.
444
       **/
445
      wots_keysig_t pub_key_from_signature(
446
         const secure_vector<uint8_t>& msg,
447
         const wots_keysig_t& sig,
448
         XMSS_Address& adrs,
449
         const secure_vector<uint8_t>& public_seed);
450
   };
451
452
/** A Winternitz One Time Signature private key for use with Extended Hash-Based
453
 * Signatures.
454
 **/
455
class XMSS_WOTS_PrivateKey final : public virtual XMSS_WOTS_PublicKey,
456
   public virtual Private_Key
457
   {
458
   public:
459
      /**
460
       * Creates a WOTS private key for the chosen XMSS WOTS signature method.
461
       * Members need to be initialized manually.
462
       *
463
       * @param oid Identifier for the selected signature method.
464
       **/
465
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)
466
         : XMSS_WOTS_PublicKey(oid)
467
0
         {}
468
469
      /**
470
       * Creates a WOTS private key for the chosen XMSS WOTS signature method.
471
       *
472
       * @param oid Identifier for the selected signature method.
473
       * @param rng A random number generator to use for key generation.
474
       **/
475
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
476
                           RandomNumberGenerator& rng)
477
         : XMSS_WOTS_PublicKey(oid, rng),
478
           m_private_seed(rng.random_vec(m_wots_params.element_size()))
479
0
         {
480
0
         set_key_data(generate(m_private_seed));
481
0
         }
482
483
      /**
484
       * Constructs a WOTS private key. Chains will be generated on demand
485
       * applying a hash function to a unique value generated from a secret
486
       * seed and a counter. The secret seed of length n, will be
487
       * automatically generated using AutoSeeded_RNG(). "n" equals
488
       * the element size of the chosen WOTS security parameter set.
489
       *
490
       * @param oid Identifier for the selected signature method.
491
       * @param public_seed A public seed used for the pseudo random generation
492
       *        of public keys derived from this private key.
493
       * @param rng A random number generator to use for key generation.
494
       **/
495
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
496
                           const secure_vector<uint8_t>& public_seed,
497
                           RandomNumberGenerator& rng)
498
         : XMSS_WOTS_PublicKey(oid, public_seed),
499
           m_private_seed(rng.random_vec(m_wots_params.element_size()))
500
0
         {
501
0
         set_key_data(generate(m_private_seed));
502
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> > const&, 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> > const&, Botan::RandomNumberGenerator&)
503
504
      /**
505
       * Constructs a WOTS private key. Chains will be generated on demand
506
       * applying a hash function to a unique value generated from a secret
507
       * seed and a counter. The secret seed of length n, will be
508
       * automatically generated using AutoSeeded_RNG(). "n" equals
509
       * the element size of the chosen WOTS security parameter set.
510
       *
511
       * @param oid Identifier for the selected signature method.
512
       * @param public_seed A public seed used for the pseudo random generation
513
       *        of public keys derived from this private key.
514
       **/
515
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
516
                           const secure_vector<uint8_t>& public_seed)
517
         : XMSS_WOTS_PublicKey(oid, public_seed)
518
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> > const&)
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> > const&)
519
520
      /**
521
       * Constructs a WOTS private key. Chains will be generated on demand
522
       * applying a hash function to a unique value generated from the
523
       * secret seed and a counter.
524
       *
525
       * @param oid Identifier for the selected signature method.
526
       * @param public_seed A public seed used for the pseudo random generation
527
       *        of public keys derived from this private key.
528
       * @param private_seed A secret uniformly random n-byte value.
529
       **/
530
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
531
                           const secure_vector<uint8_t>& public_seed,
532
                           const secure_vector<uint8_t>& private_seed)
533
         : XMSS_WOTS_PublicKey(oid, public_seed),
534
           m_private_seed(private_seed)
535
0
         {
536
0
         set_key_data(generate(private_seed));
537
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> > const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
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> > const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
538
539
      std::unique_ptr<Public_Key> public_key() const override
540
0
         {
541
0
         throw Not_Implemented("Not possible to derive WOTS public key from private key");
542
0
         }
543
544
      /**
545
       * Retrieves the i-th WOTS private key using pseudo random key
546
       * (re-)generation.
547
       *
548
       * This overload is used in multithreaded scenarios, where it is
549
       * required to provide seperate instances of XMSS_Hash to each
550
       * thread.
551
       *
552
       * @param i Index of the key to retrieve.
553
       * @param hash Instance of XMSS_Hash, that may only be used by the
554
       *        thead executing at.
555
       *
556
       * @return WOTS secret key.
557
       **/
558
      wots_keysig_t at(size_t i, XMSS_Hash& hash);
559
560
      /**
561
       * Retrieves the i-th WOTS private key using pseudo random key
562
       * (re-)generation.
563
       *
564
       * @param i Index of the key to retrieve.
565
       *
566
       * @return WOTS secret key.
567
       **/
568
      inline wots_keysig_t operator[](size_t i)
569
0
         {
570
0
         return this->at(i, m_hash);
571
0
         }
572
573
      /**
574
       * Retrieves the i-th WOTS private key using pseudo random key
575
       * (re-)generation.
576
       *
577
       * This overload is used in multithreaded scenarios, where it is
578
       * required to provide seperate instances of XMSS_Hash to each
579
       * thread.
580
       *
581
       * @param adrs The address of the key to retrieve.
582
       * @param hash Instance of XMSS_Hash, that may only be used by the
583
       *        thead executing at.
584
       *
585
       * @return WOTS secret key.
586
       **/
587
      wots_keysig_t at(const XMSS_Address& adrs, XMSS_Hash& hash);
588
589
      inline wots_keysig_t operator[](const XMSS_Address& adrs)
590
0
         {
591
0
         return this->at(adrs, m_hash);
592
0
         }
593
594
      wots_keysig_t generate_private_key(const secure_vector<uint8_t>& priv_seed);
595
596
      /**
597
       * Algorithm 4: "WOTS_genPK"
598
       * Generates a Winternitz One Time Signature+ (WOTS+) Public Key from a
599
       * given private key.
600
       *
601
       * @param adrs Hash function address encoding the address of the WOTS+
602
       *             key pair within a greater structure.
603
       *
604
       * @return A XMSS_WOTS_PublicKey.
605
       **/
606
      XMSS_WOTS_PublicKey generate_public_key(XMSS_Address& adrs);
607
608
      /**
609
       * Algorithm 4: "WOTS_genPK"
610
       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's
611
       * key_data() member, with data derived from in_key_data using the
612
       * WOTS chaining function.
613
       *
614
       * This overload is used in multithreaded scenarios, where it is
615
       * required to provide seperate instances of XMSS_Hash to each
616
       * thread.
617
       *
618
       * @param[out] pub_key Public key to initialize key_data() member on.
619
       * @param in_key_data Input key material from private key used for
620
       *        public key generation.
621
       * @param adrs Hash function address encoding the address of
622
       *        the WOTS+ key pair within a greater structure.
623
       * @param hash Instance of XMSS_Hash, that may only by the thead
624
       *        executing generate_public_key.
625
       **/
626
      void generate_public_key(XMSS_WOTS_PublicKey& pub_key,
627
                               wots_keysig_t&& in_key_data,
628
                               XMSS_Address& adrs,
629
                               XMSS_Hash& hash);
630
      /**
631
       * Algorithm 4: "WOTS_genPK"
632
       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's
633
       * key_data() member, with data derived from in_key_data using the
634
       * WOTS chaining function.
635
       *
636
       * @param[out] pub_key Public key to initialize key_data() member on.
637
       * @param in_key_data Input key material from private key used for
638
       *        public key generation.
639
       * @param adrs Hash function address encoding the address of
640
       *        the WOTS+ key pair within a greater structure.
641
       **/
642
      inline void generate_public_key(XMSS_WOTS_PublicKey& pub_key,
643
                                      wots_keysig_t&& in_key_data,
644
                                      XMSS_Address& adrs)
645
0
         {
646
0
         generate_public_key(pub_key, std::forward<wots_keysig_t>(in_key_data), adrs, m_hash);
647
0
         }
648
649
      /**
650
       * Algorithm 5: "WOTS_sign"
651
       * Generates a signature from a private key and a message.
652
       *
653
       * @param msg A message to sign.
654
       * @param adrs An OTS hash address identifying the WOTS+ key pair
655
       *        used for signing.
656
       *
657
       * @return signature for msg.
658
       **/
659
      inline wots_keysig_t sign(const secure_vector<uint8_t>& msg,
660
                                XMSS_Address& adrs)
661
0
         {
662
0
         return sign(msg, adrs, m_hash);
663
0
         }
664
665
      /**
666
       * Algorithm 5: "WOTS_sign"
667
       * Generates a signature from a private key and a message.
668
       *
669
       * This overload is used in multithreaded scenarios, where it is
670
       * required to provide seperate instances of XMSS_Hash to each
671
       * thread.
672
       *
673
       * @param msg A message to sign.
674
       * @param adrs An OTS hash address identifying the WOTS+ key pair
675
       *        used for signing.
676
       * @param hash Instance of XMSS_Hash, that may only be used by the
677
       *        thead executing sign.
678
       *
679
       * @return signature for msg.
680
       **/
681
      wots_keysig_t sign(const secure_vector<uint8_t>& msg,
682
                         XMSS_Address& adrs,
683
                         XMSS_Hash& hash);
684
685
      /**
686
       * Retrieves the secret seed used to generate WOTS+ chains. The seed
687
       * should be a uniformly random n-byte value.
688
       *
689
       * @return secret seed.
690
       **/
691
      const secure_vector<uint8_t>& private_seed() const
692
0
         {
693
0
         return m_private_seed;
694
0
         }
695
696
      /**
697
       * Sets the secret seed used to generate WOTS+ chains. The seed
698
       * should be a uniformly random n-byte value.
699
       *
700
       * @param private_seed Uniformly random n-byte value.
701
       **/
702
      void set_private_seed(const secure_vector<uint8_t>& private_seed)
703
0
         {
704
0
         m_private_seed = private_seed;
705
0
         }
706
707
      /**
708
       * Sets the secret seed used to generate WOTS+ chains. The seed
709
       * should be a uniformly random n-byte value.
710
       *
711
       * @param private_seed Uniformly random n-byte value.
712
       **/
713
      void set_private_seed(secure_vector<uint8_t>&& private_seed)
714
0
         {
715
0
         m_private_seed = std::move(private_seed);
716
0
         }
717
718
      AlgorithmIdentifier
719
      pkcs8_algorithm_identifier() const override
720
0
         {
721
0
         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");
722
0
         }
723
724
      secure_vector<uint8_t> private_key_bits() const override
725
0
         {
726
0
         throw Not_Implemented("No PKCS8 key format defined for XMSS-WOTS.");
727
0
         }
728
729
   private:
730
      /**
731
       * Algorithm 3: "Generating a WOTS+ Private Key".
732
       * Generates a private key.
733
       *
734
       * This overload is used in multithreaded scenarios, where it is
735
       * required to provide seperate instances of XMSS_Hash to each thread.
736
       *
737
       * @param private_seed Uniformly random n-byte value.
738
       * @param[in] hash Instance of XMSS_Hash, that may only be used by the
739
       *            thead executing generate.
740
       *
741
       * @returns a vector of length key_size() of vectors of n bytes length
742
       *          containing uniformly random data.
743
       **/
744
      wots_keysig_t generate(const secure_vector<uint8_t>& private_seed,
745
                             XMSS_Hash& hash);
746
747
      inline wots_keysig_t generate(const secure_vector<uint8_t>& private_seed)
748
0
         {
749
0
         return generate(private_seed, m_hash);
750
0
         }
751
752
      secure_vector<uint8_t> m_private_seed;
753
   };
754
755
}
756
757
#endif