~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/lib/pubkey/xmss/xmss_wots_privatekey.h

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
         {}
 
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
         {
 
51
         set_key_data(generate(m_private_seed));
 
52
         }
 
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
         {
 
72
         set_key_data(generate(m_private_seed));
 
73
         }
 
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
         {}
 
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
         {
 
107
         set_key_data(generate(private_seed));
 
108
         }
 
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
         {
 
126
         secure_vector<uint8_t> idx_bytes;
 
127
         XMSS_Tools::concat(idx_bytes, i, m_wots_params.element_size());
 
128
         hash.h(idx_bytes, m_private_seed, idx_bytes);
 
129
         return generate(idx_bytes, hash);
 
130
         }
 
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
         {
 
142
         return this->at(i, m_hash);
 
143
         }
 
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
         {
 
161
         secure_vector<uint8_t> result;
 
162
         hash.prf(result, m_private_seed, adrs.bytes());
 
163
         return generate(result, hash);
 
164
         }
 
165
 
 
166
      inline wots_keysig_t operator[](const XMSS_Address& adrs)
 
167
         {
 
168
         return this->at(adrs, m_hash);
 
169
         }
 
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
         {
 
223
         generate_public_key(pub_key, std::forward<wots_keysig_t>(in_key_data), adrs, m_hash);
 
224
         }
 
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
         {
 
239
         return sign(msg, adrs, m_hash);
 
240
         }
 
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
         {
 
270
         return m_private_seed;
 
271
         }
 
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
         {
 
281
         m_private_seed = private_seed;
 
282
         }
 
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
         {
 
292
         m_private_seed = std::move(private_seed);
 
293
         }
 
294
 
 
295
      AlgorithmIdentifier
 
296
      pkcs8_algorithm_identifier() const override
 
297
         {
 
298
         throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");
 
299
         }
 
300
 
 
301
      secure_vector<uint8_t> private_key_bits() const override
 
302
         {
 
303
         throw Not_Implemented("No PKCS8 key format defined for XMSS-WOTS.");
 
304
         }
 
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
         {
 
326
         return generate(private_seed, m_hash);
 
327
         }
 
328
 
 
329
      secure_vector<uint8_t> m_private_seed;
 
330
   };
 
331
 
 
332
}
 
333
 
 
334
#endif
 
335