Coverage Report

Created: 2020-08-01 06:18

/src/botan/build/include/botan/xmss_wots_privatekey.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * XMSS WOTS Private Key
3
 * (C) 2016,2017 Matthias Gierlings
4
 *
5
 * Botan is released under the Simplified BSD License (see license.txt)
6
 **/
7
8
#ifndef BOTAN_XMSS_WOTS_PRIVATEKEY_H_
9
#define BOTAN_XMSS_WOTS_PRIVATEKEY_H_
10
11
#include <cstddef>
12
#include <memory>
13
#include <botan/alg_id.h>
14
#include <botan/exceptn.h>
15
#include <botan/pk_keys.h>
16
#include <botan/rng.h>
17
#include <botan/xmss_wots_parameters.h>
18
#include <botan/xmss_address.h>
19
#include <botan/xmss_wots_publickey.h>
20
21
namespace Botan {
22
23
/** A Winternitz One Time Signature private key for use with Extended Hash-Based
24
 * Signatures.
25
 **/
26
class XMSS_WOTS_PrivateKey final : public virtual XMSS_WOTS_PublicKey,
27
   public virtual Private_Key
28
   {
29
   public:
30
      /**
31
       * Creates a WOTS private key for the chosen XMSS WOTS signature method.
32
       * Members need to be initialized manually.
33
       *
34
       * @param oid Identifier for the selected signature method.
35
       **/
36
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)
37
         : XMSS_WOTS_PublicKey(oid)
38
0
         {}
39
40
      /**
41
       * Creates a WOTS private key for the chosen XMSS WOTS signature method.
42
       *
43
       * @param oid Identifier for the selected signature method.
44
       * @param rng A random number generator to use for key generation.
45
       **/
46
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
47
                           RandomNumberGenerator& rng)
48
         : XMSS_WOTS_PublicKey(oid, rng),
49
           m_private_seed(rng.random_vec(m_wots_params.element_size()))
50
0
         {
51
0
         set_key_data(generate(m_private_seed));
52
0
         }
53
54
      /**
55
       * Constructs a WOTS private key. Chains will be generated on demand
56
       * applying a hash function to a unique value generated from a secret
57
       * seed and a counter. The secret seed of length n, will be
58
       * automatically generated using AutoSeeded_RNG(). "n" equals
59
       * the element size of the chosen WOTS security parameter set.
60
       *
61
       * @param oid Identifier for the selected signature method.
62
       * @param public_seed A public seed used for the pseudo random generation
63
       *        of public keys derived from this private key.
64
       * @param rng A random number generator to use for key generation.
65
       **/
66
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
67
                           const secure_vector<uint8_t>& public_seed,
68
                           RandomNumberGenerator& rng)
69
         : XMSS_WOTS_PublicKey(oid, public_seed),
70
           m_private_seed(rng.random_vec(m_wots_params.element_size()))
71
0
         {
72
0
         set_key_data(generate(m_private_seed));
73
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&)
74
75
      /**
76
       * Constructs a WOTS private key. Chains will be generated on demand
77
       * applying a hash function to a unique value generated from a secret
78
       * seed and a counter. The secret seed of length n, will be
79
       * automatically generated using AutoSeeded_RNG(). "n" equals
80
       * the element size of the chosen WOTS security parameter set.
81
       *
82
       * @param oid Identifier for the selected signature method.
83
       * @param public_seed A public seed used for the pseudo random generation
84
       *        of public keys derived from this private key.
85
       **/
86
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
87
                           const secure_vector<uint8_t>& public_seed)
88
         : XMSS_WOTS_PublicKey(oid, public_seed)
89
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&)
90
91
      /**
92
       * Constructs a WOTS private key. Chains will be generated on demand
93
       * applying a hash function to a unique value generated from the
94
       * secret seed and a counter.
95
       *
96
       * @param oid Identifier for the selected signature method.
97
       * @param public_seed A public seed used for the pseudo random generation
98
       *        of public keys derived from this private key.
99
       * @param private_seed A secret uniformly random n-byte value.
100
       **/
101
      XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid,
102
                           const secure_vector<uint8_t>& public_seed,
103
                           const secure_vector<uint8_t>& private_seed)
104
         : XMSS_WOTS_PublicKey(oid, public_seed),
105
           m_private_seed(private_seed)
106
0
         {
107
0
         set_key_data(generate(private_seed));
108
0
         }
109
110
      /**
111
       * Retrieves the i-th WOTS private key using pseudo random key
112
       * (re-)generation.
113
       *
114
       * This overload is used in multithreaded scenarios, where it is
115
       * required to provide seperate instances of XMSS_Hash to each
116
       * thread.
117
       *
118
       * @param i Index of the key to retrieve.
119
       * @param hash Instance of XMSS_Hash, that may only be used by the
120
       *        thead executing at.
121
       *
122
       * @return WOTS secret key.
123
       **/
124
      wots_keysig_t at(size_t i, XMSS_Hash& hash)
125
0
         {
126
0
         secure_vector<uint8_t> idx_bytes;
127
0
         XMSS_Tools::concat(idx_bytes, i, m_wots_params.element_size());
128
0
         hash.h(idx_bytes, m_private_seed, idx_bytes);
129
0
         return generate(idx_bytes, hash);
130
0
         }
131
132
      /**
133
       * Retrieves the i-th WOTS private key using pseudo random key
134
       * (re-)generation.
135
       *
136
       * @param i Index of the key to retrieve.
137
       *
138
       * @return WOTS secret key.
139
       **/
140
      inline wots_keysig_t operator[](size_t i)
141
0
         {
142
0
         return this->at(i, m_hash);
143
0
         }
144
145
      /**
146
       * Retrieves the i-th WOTS private key using pseudo random key
147
       * (re-)generation.
148
       *
149
       * This overload is used in multithreaded scenarios, where it is
150
       * required to provide seperate instances of XMSS_Hash to each
151
       * thread.
152
       *
153
       * @param adrs The address of the key to retrieve.
154
       * @param hash Instance of XMSS_Hash, that may only be used by the
155
       *        thead executing at.
156
       *
157
       * @return WOTS secret key.
158
       **/
159
      wots_keysig_t at(const XMSS_Address& adrs, XMSS_Hash& hash)
160
0
         {
161
0
         secure_vector<uint8_t> result;
162
0
         hash.prf(result, m_private_seed, adrs.bytes());
163
0
         return generate(result, hash);
164
0
         }
165
166
      inline wots_keysig_t operator[](const XMSS_Address& adrs)
167
0
         {
168
0
         return this->at(adrs, m_hash);
169
0
         }
170
171
      wots_keysig_t generate_private_key(const secure_vector<uint8_t>& priv_seed);
172
173
      /**
174
       * Algorithm 4: "WOTS_genPK"
175
       * Generates a Winternitz One Time Signature+ (WOTS+) Public Key from a
176
       * given private key.
177
       *
178
       * @param adrs Hash function address encoding the address of the WOTS+
179
       *             key pair within a greater structure.
180
       *
181
       * @return A XMSS_WOTS_PublicKey.
182
       **/
183
      XMSS_WOTS_PublicKey generate_public_key(XMSS_Address& adrs);
184
185
      /**
186
       * Algorithm 4: "WOTS_genPK"
187
       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's
188
       * key_data() member, with data derived from in_key_data using the
189
       * WOTS chaining function.
190
       *
191
       * This overload is used in multithreaded scenarios, where it is
192
       * required to provide seperate instances of XMSS_Hash to each
193
       * thread.
194
       *
195
       * @param[out] pub_key Public key to initialize key_data() member on.
196
       * @param in_key_data Input key material from private key used for
197
       *        public key generation.
198
       * @param adrs Hash function address encoding the address of
199
       *        the WOTS+ key pair within a greater structure.
200
       * @param hash Instance of XMSS_Hash, that may only by the thead
201
       *        executing generate_public_key.
202
       **/
203
      void generate_public_key(XMSS_WOTS_PublicKey& pub_key,
204
                               wots_keysig_t&& in_key_data,
205
                               XMSS_Address& adrs,
206
                               XMSS_Hash& hash);
207
      /**
208
       * Algorithm 4: "WOTS_genPK"
209
       * Initializes a Winternitz One Time Signature+ (WOTS+) Public Key's
210
       * key_data() member, with data derived from in_key_data using the
211
       * WOTS chaining function.
212
       *
213
       * @param[out] pub_key Public key to initialize key_data() member on.
214
       * @param in_key_data Input key material from private key used for
215
       *        public key generation.
216
       * @param adrs Hash function address encoding the address of
217
       *        the WOTS+ key pair within a greater structure.
218
       **/
219
      inline void generate_public_key(XMSS_WOTS_PublicKey& pub_key,
220
                                      wots_keysig_t&& in_key_data,
221
                                      XMSS_Address& adrs)
222
0
         {
223
0
         generate_public_key(pub_key, std::forward<wots_keysig_t>(in_key_data), adrs, m_hash);
224
0
         }
225
226
      /**
227
       * Algorithm 5: "WOTS_sign"
228
       * Generates a signature from a private key and a message.
229
       *
230
       * @param msg A message to sign.
231
       * @param adrs An OTS hash address identifying the WOTS+ key pair
232
       *        used for signing.
233
       *
234
       * @return signature for msg.
235
       **/
236
      inline wots_keysig_t sign(const secure_vector<uint8_t>& msg,
237
                                XMSS_Address& adrs)
238
0
         {
239
0
         return sign(msg, adrs, m_hash);
240
0
         }
241
242
      /**
243
       * Algorithm 5: "WOTS_sign"
244
       * Generates a signature from a private key and a message.
245
       *
246
       * This overload is used in multithreaded scenarios, where it is
247
       * required to provide seperate instances of XMSS_Hash to each
248
       * thread.
249
       *
250
       * @param msg A message to sign.
251
       * @param adrs An OTS hash address identifying the WOTS+ key pair
252
       *        used for signing.
253
       * @param hash Instance of XMSS_Hash, that may only be used by the
254
       *        thead executing sign.
255
       *
256
       * @return signature for msg.
257
       **/
258
      wots_keysig_t sign(const secure_vector<uint8_t>& msg,
259
                         XMSS_Address& adrs,
260
                         XMSS_Hash& hash);
261
262
      /**
263
       * Retrieves the secret seed used to generate WOTS+ chains. The seed
264
       * should be a uniformly random n-byte value.
265
       *
266
       * @return secret seed.
267
       **/
268
      const secure_vector<uint8_t>& private_seed() const
269
0
         {
270
0
         return m_private_seed;
271
0
         }
272
273
      /**
274
       * Sets the secret seed used to generate WOTS+ chains. The seed
275
       * should be a uniformly random n-byte value.
276
       *
277
       * @param private_seed Uniformly random n-byte value.
278
       **/
279
      void set_private_seed(const secure_vector<uint8_t>& private_seed)
280
0
         {
281
0
         m_private_seed = private_seed;
282
0
         }
283
284
      /**
285
       * Sets the secret seed used to generate WOTS+ chains. The seed
286
       * should be a uniformly random n-byte value.
287
       *
288
       * @param private_seed Uniformly random n-byte value.
289
       **/
290
      void set_private_seed(secure_vector<uint8_t>&& private_seed)
291
0
         {
292
0
         m_private_seed = std::move(private_seed);
293
0
         }
294
295
      AlgorithmIdentifier
296
      pkcs8_algorithm_identifier() const override
297
0
         {
298
0
         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");
299
0
         }
300
301
      secure_vector<uint8_t> private_key_bits() const override
302
0
         {
303
0
         throw Not_Implemented("No PKCS8 key format defined for XMSS-WOTS.");
304
0
         }
305
306
   private:
307
      /**
308
       * Algorithm 3: "Generating a WOTS+ Private Key".
309
       * Generates a private key.
310
       *
311
       * This overload is used in multithreaded scenarios, where it is
312
       * required to provide seperate instances of XMSS_Hash to each thread.
313
       *
314
       * @param private_seed Uniformly random n-byte value.
315
       * @param[in] hash Instance of XMSS_Hash, that may only be used by the
316
       *            thead executing generate.
317
       *
318
       * @returns a vector of length key_size() of vectors of n bytes length
319
       *          containing uniformly random data.
320
       **/
321
      wots_keysig_t generate(const secure_vector<uint8_t>& private_seed,
322
                             XMSS_Hash& hash);
323
324
      inline wots_keysig_t generate(const secure_vector<uint8_t>& private_seed)
325
0
         {
326
0
         return generate(private_seed, m_hash);
327
0
         }
328
329
      secure_vector<uint8_t> m_private_seed;
330
   };
331
332
}
333
334
#endif
335