Botan  2.1.0
Crypto and TLS for C++11
xmss_privatekey.h
Go to the documentation of this file.
1 /*
2  * XMSS_PrivateKey.h
3  * (C) 2016 Matthias Gierlings
4  *
5  * Botan is released under the Simplified BSD License (see license.txt)
6  **/
7 
8 #ifndef BOTAN_XMSS_PRIVATEKEY_H__
9 #define BOTAN_XMSS_PRIVATEKEY_H__
10 
11 #include <cstddef>
12 #include <iterator>
13 #include <memory>
14 #include <botan/alg_id.h>
15 #include <botan/assert.h>
16 #include <botan/exceptn.h>
17 #include <botan/pk_keys.h>
18 #include <botan/rng.h>
19 #include <botan/types.h>
20 #include <botan/xmss_parameters.h>
21 #include <botan/xmss_publickey.h>
22 #include <botan/atomic.h>
23 #include <botan/xmss_common_ops.h>
24 #include <botan/xmss_wots_privatekey.h>
25 #include <botan/xmss_index_registry.h>
26 
27 namespace Botan {
28 
29 /**
30  * An XMSS: Extended Hash-Based Signature private key.
31  * The XMSS private key does not support the X509 and PKCS7 standard. Instead
32  * the raw format described in [1] is used.
33  *
34  * [1] XMSS: Extended Hash-Based Signatures,
35  * draft-itrf-cfrg-xmss-hash-based-signatures-06
36  * Release: July 2016.
37  * https://datatracker.ietf.org/doc/
38  * draft-irtf-cfrg-xmss-hash-based-signatures/?include_text=1
39  **/
40 class BOTAN_DLL XMSS_PrivateKey : public virtual XMSS_PublicKey,
41  public XMSS_Common_Ops,
42  public virtual Private_Key
43  {
44  public:
45  /**
46  * Creates a new XMSS private key for the chosen XMSS signature method.
47  * New seeds for public/private key and pseudo random function input are
48  * generated using the provided RNG. The appropriate WOTS signature method
49  * will be automatically set based on the chosen XMSS signature method.
50  *
51  * @param xmss_algo_id Identifier for the selected XMSS signature method.
52  * @param rng A random number generator to use for key generation.
53  **/
56 
57  /**
58  * Creates an XMSS_PrivateKey from a byte sequence produced by
59  * raw_private_key().
60  *
61  * @param raw_key An XMSS private key serialized using raw_private_key().
62  **/
64 
65  /**
66  * Creates a new XMSS private key for the chosen XMSS signature method
67  * using precomputed seeds for public/private keys and pseudo random
68  * function input. The appropriate WOTS signature method will be
69  * automatically set, based on the chosen XMSS signature method.
70  *
71  * @param xmss_algo_id Identifier for the selected XMSS signature method.
72  * @param idx_leaf Index of the next unused leaf.
73  * @param wots_priv_seed A seed to generate a Winternitz-One-Time-
74  * Signature private key from.
75  * @param prf a secret n-byte key sourced from a secure source
76  * of uniformly random data.
77  * @param root Root node of the binary hash tree.
78  * @param public_seed The public seed.
79  **/
81  size_t idx_leaf,
82  const secure_vector<uint8_t>& wots_priv_seed,
83  const secure_vector<uint8_t>& prf,
84  const secure_vector<uint8_t>& root,
85  const secure_vector<uint8_t>& public_seed)
86  : XMSS_PublicKey(xmss_algo_id, root, public_seed),
87  XMSS_Common_Ops(xmss_algo_id),
88  m_wots_priv_key(XMSS_PublicKey::m_xmss_params.ots_oid(),
89  public_seed,
90  wots_priv_seed),
91  m_prf(prf),
92  m_index_reg(XMSS_Index_Registry::get_instance())
93  {
94  set_unused_leaf_index(idx_leaf);
95  }
96 
97  /**
98  * Retrieves the last unused leaf index of the private key. Reusing a leaf
99  * by utilizing leaf indices lower than the last unused leaf index will
100  * compromise security.
101  *
102  * @return Index of the last unused leaf.
103  **/
104  size_t unused_leaf_index() const
105  {
106  return *recover_global_leaf_index();
107  }
108 
109  /**
110  * Sets the last unused leaf index of the private key. The leaf index
111  * will be updated automatically during every signing operation, and
112  * should not be set manually.
113  *
114  * @param idx Index of the last unused leaf.
115  **/
116  void set_unused_leaf_index(size_t idx)
117  {
118  if(idx >= (1ull << (XMSS_PublicKey::m_xmss_params.tree_height() - 1)))
119  {
120  throw Integrity_Failure("XMSS private key leaf index out of "
121  "bounds.");
122  }
123  else
124  {
125  std::atomic<size_t>& index =
126  static_cast<std::atomic<size_t>&>(*recover_global_leaf_index());
127  size_t current = 0;
128 
129  do
130  {
131  current = index.load();
132  if(current > idx)
133  return;
134  }
135  while(!index.compare_exchange_strong(current, idx));
136  }
137  }
138 
140  {
141  size_t idx = (static_cast<std::atomic<size_t>&>(
142  *recover_global_leaf_index())).fetch_add(1);
143  if(idx >= (1ull << (XMSS_PublicKey::m_xmss_params.tree_height() - 1)))
144  {
145  throw Integrity_Failure("XMSS private key, one time signatures "
146  "exhausted.");
147  }
148  return idx;
149  }
150 
151  /**
152  * Winternitz One Time Signature Scheme key utilized for signing
153  * operations.
154  *
155  * @return WOTS+ private key.
156  **/
158  {
159  return m_wots_priv_key;
160  }
161 
162  /**
163  * Winternitz One Time Signature Scheme key utilized for signing
164  * operations.
165  *
166  * @return WOTS+ private key.
167  **/
169  {
170  return m_wots_priv_key;
171  }
172 
174  {
175  return m_prf;
176  }
177 
179  {
180  return m_prf;
181  }
182 
183  virtual void set_public_seed(
184  const secure_vector<uint8_t>& public_seed) override
185  {
186  m_public_seed = public_seed;
187  m_wots_priv_key.set_public_seed(public_seed);
188  }
189 
190  virtual void set_public_seed(secure_vector<uint8_t>&& public_seed) override
191  {
192  m_public_seed = std::move(public_seed);
193  m_wots_priv_key.set_public_seed(m_public_seed);
194  }
195 
196  virtual const secure_vector<uint8_t>& public_seed() const override
197  {
198  return m_public_seed;
199  }
200 
201  virtual std::unique_ptr<PK_Ops::Signature>
202  create_signature_op(RandomNumberGenerator&,
203  const std::string&,
204  const std::string& provider) const override;
205 
206  virtual secure_vector<uint8_t> private_key_bits() const override
207  {
208  return raw_private_key();
209  }
210 
211  virtual size_t size() const override
212  {
213  return XMSS_PublicKey::size() +
214  sizeof(uint64_t) +
215  2 * XMSS_PublicKey::m_xmss_params.element_size();
216  }
217 
218  /**
219  * Generates a non standartized byte sequence representing the XMSS
220  * private key.
221  *
222  * @return byte sequence consisting of the following elements in order:
223  * 4-byte OID, n-byte root node, n-byte public seed,
224  * 8-byte unused leaf index, n-byte prf seed, n-byte private seed.
225  **/
226  virtual secure_vector<uint8_t> raw_private_key() const;
227  /**
228  * Algorithm 9: "treeHash"
229  * Computes the internal n-byte nodes of a Merkle tree.
230  *
231  * @param start_idx The start index.
232  * @param target_node_height Height of the target node.
233  * @param adrs Address of the tree containing the target node.
234  *
235  * @return The root node of a tree of height target_node height with the
236  * leftmost leaf being the hash of the WOTS+ pk with index
237  * start_idx.
238  **/
239  secure_vector<uint8_t> tree_hash(
240  size_t start_idx,
241  size_t target_node_height,
242  XMSS_Address& adrs);
243 
244  private:
245  /**
246  * Fetches shared unused leaf index fromt the index registry
247  **/
248  std::shared_ptr<Atomic<size_t>> recover_global_leaf_index() const;
249 
250  XMSS_WOTS_PrivateKey m_wots_priv_key;
252  XMSS_Index_Registry& m_index_reg;
253  };
254 
255 }
256 
257 #endif
258 
virtual void set_public_seed(const secure_vector< uint8_t > &public_seed) override
virtual const secure_vector< uint8_t > & public_seed() const override
void set_unused_leaf_index(size_t idx)
virtual secure_vector< uint8_t > private_key_bits() const override
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
virtual size_t size() const
XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id, size_t idx_leaf, const secure_vector< uint8_t > &wots_priv_seed, const secure_vector< uint8_t > &prf, const secure_vector< uint8_t > &root, const secure_vector< uint8_t > &public_seed)
Definition: alg_id.cpp:13
virtual size_t size() const override
const secure_vector< uint8_t > & prf() const
XMSS_Parameters m_xmss_params
virtual void set_public_seed(secure_vector< uint8_t > &&public_seed) override
XMSS_WOTS_PrivateKey & wots_private_key()
size_t unused_leaf_index() const
const XMSS_WOTS_PrivateKey & wots_private_key() const
secure_vector< uint8_t > & prf()