Botan  2.4.0
Crypto and TLS for C++11
xmss_wots_privatekey.h
Go to the documentation of this file.
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
125  {
126  secure_vector<uint8_t> idx_bytes;
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  **/
160  {
161  secure_vector<uint8_t> result;
162  hash.prf(result, m_private_seed, adrs.bytes());
163  return generate(result, hash);
164  }
165 
167  {
168  return this->at(adrs, m_hash);
169  }
170 
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
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  **/
291  {
292  m_private_seed = std::move(private_seed);
293  }
294 
296  pkcs8_algorithm_identifier() const override
297  {
298  throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS.");
299  }
300 
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  **/
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 
const secure_vector< uint8_t > & public_seed() const
XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid, RandomNumberGenerator &rng)
void h(secure_vector< uint8_t > &result, const secure_vector< uint8_t > &key, const secure_vector< uint8_t > &data)
Definition: xmss_hash.cpp:36
XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid, const secure_vector< uint8_t > &public_seed, const secure_vector< uint8_t > &private_seed)
wots_keysig_t sign(const secure_vector< uint8_t > &msg, XMSS_Address &adrs)
wots_keysig_t operator[](const XMSS_Address &adrs)
XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid, const secure_vector< uint8_t > &public_seed)
wots_keysig_t at(size_t i, XMSS_Hash &hash)
void generate_public_key(XMSS_WOTS_PublicKey &pub_key, wots_keysig_t &&in_key_data, XMSS_Address &adrs)
AlgorithmIdentifier pkcs8_algorithm_identifier() const override
const secure_vector< uint8_t > & bytes() const
Definition: xmss_address.h:322
XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid, const secure_vector< uint8_t > &public_seed, RandomNumberGenerator &rng)
wots_keysig_t generate_private_key(const secure_vector< uint8_t > &priv_seed)
void prf(secure_vector< uint8_t > &result, const secure_vector< uint8_t > &key, const secure_vector< uint8_t > &data)
Definition: xmss_hash.h:33
XMSS_WOTS_PrivateKey(XMSS_WOTS_Parameters::ots_algorithm_t oid)
void set_private_seed(secure_vector< uint8_t > &&private_seed)
XMSS_WOTS_PublicKey generate_public_key(XMSS_Address &adrs)
Definition: alg_id.cpp:13
std::vector< secure_vector< uint8_t > > wots_keysig_t
static void concat(secure_vector< uint8_t > &target, const T &src)
Definition: xmss_tools.h:103
wots_keysig_t operator[](size_t i)
void set_key_data(const wots_keysig_t &key_data)
const secure_vector< uint8_t > & private_seed() const
secure_vector< uint8_t > private_key_bits() const override
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
void set_private_seed(const secure_vector< uint8_t > &private_seed)
wots_keysig_t at(const XMSS_Address &adrs, XMSS_Hash &hash)
MechanismType hash
XMSS_WOTS_Parameters m_wots_params