/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 | | |