• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 22188254170

19 Feb 2026 03:30PM UTC coverage: 90.233% (-1.7%) from 91.974%
22188254170

Pull #5358

github

web-flow
Merge 4cbc0b843 into b4032cdd8
Pull Request #5358: Implementation of XMSS^MT

104032 of 115293 relevant lines covered (90.23%)

15818763.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.66
/src/lib/pubkey/pk_algs.cpp
1
/*
2
* PK Key
3
* (C) 1999-2010,2016 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/pk_algs.h>
9

10
#include <botan/asn1_obj.h>
11
#include <botan/assert.h>
12
#include <botan/pk_keys.h>
13
#include <botan/internal/fmt.h>
14
#include <botan/internal/parsing.h>
15

16
#if defined(BOTAN_HAS_RSA)
17
   #include <botan/rsa.h>
18
#endif
19

20
#if defined(BOTAN_HAS_CLASSICMCELIECE)
21
   #include <botan/cmce.h>
22
#endif
23

24
#if defined(BOTAN_HAS_DSA)
25
   #include <botan/dsa.h>
26
#endif
27

28
#if defined(BOTAN_HAS_DL_GROUP)
29
   #include <botan/dl_group.h>
30
#endif
31

32
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
33
   #include <botan/dh.h>
34
#endif
35

36
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
37
   #include <botan/ecc_key.h>
38
#endif
39

40
#if defined(BOTAN_HAS_ECC_GROUP)
41
   #include <botan/ec_group.h>
42
#endif
43

44
#if defined(BOTAN_HAS_ECDSA)
45
   #include <botan/ecdsa.h>
46
#endif
47

48
#if defined(BOTAN_HAS_ECGDSA)
49
   #include <botan/ecgdsa.h>
50
#endif
51

52
#if defined(BOTAN_HAS_ECKCDSA)
53
   #include <botan/eckcdsa.h>
54
#endif
55

56
#if defined(BOTAN_HAS_ED25519)
57
   #include <botan/ed25519.h>
58
#endif
59

60
#if defined(BOTAN_HAS_ED448)
61
   #include <botan/ed448.h>
62
#endif
63

64
#if defined(BOTAN_HAS_GOST_34_10_2001)
65
   #include <botan/gost_3410.h>
66
#endif
67

68
#if defined(BOTAN_HAS_ELGAMAL)
69
   #include <botan/elgamal.h>
70
#endif
71

72
#if defined(BOTAN_HAS_ECDH)
73
   #include <botan/ecdh.h>
74
#endif
75

76
#if defined(BOTAN_HAS_X25519)
77
   #include <botan/x25519.h>
78
#endif
79

80
#if defined(BOTAN_HAS_X448)
81
   #include <botan/x448.h>
82
#endif
83

84
#if defined(BOTAN_HAS_MCELIECE)
85
   #include <botan/mceliece.h>
86
#endif
87

88
#if defined(BOTAN_HAS_FRODOKEM)
89
   #include <botan/frodokem.h>
90
#endif
91

92
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
93
   #include <botan/kyber.h>
94
#endif
95

96
#if defined(BOTAN_HAS_ML_KEM)
97
   #include <botan/ml_kem.h>
98
#endif
99

100
#if defined(BOTAN_HAS_HSS_LMS)
101
   #include <botan/hss_lms.h>
102
#endif
103

104
#if defined(BOTAN_HAS_XMSS_RFC8391)
105
   #include <botan/xmss.h>
106
#endif
107

108
#if defined(BOTAN_HAS_XMSSMT_RFC8391)
109
   #include <botan/xmssmt.h>
110
#endif
111

112
#if defined(BOTAN_HAS_SM2)
113
   #include <botan/sm2.h>
114
#endif
115

116
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
117
   #include <botan/dilithium.h>
118
#endif
119

120
#if defined(BOTAN_HAS_ML_DSA)
121
   #include <botan/ml_dsa.h>
122
#endif
123

124
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
125
   #include <botan/sphincsplus.h>
126
#endif
127

128
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
129
   #include <botan/slh_dsa.h>
130
#endif
131

132
namespace Botan {
133

134
std::unique_ptr<Public_Key> load_public_key(const AlgorithmIdentifier& alg_id,
28,452✔
135
                                            [[maybe_unused]] std::span<const uint8_t> key_bits) {
136
   const std::string oid_str = alg_id.oid().to_formatted_string();
28,452✔
137
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
28,452✔
138
   const std::string_view alg_name = alg_info[0];
28,452✔
139

140
#if defined(BOTAN_HAS_RSA)
141
   if(alg_name == "RSA") {
28,452✔
142
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
37,672✔
143
   }
144
#endif
145

146
#if defined(BOTAN_HAS_X25519)
147
   if(alg_name == "X25519" || alg_name == "Curve25519") {
9,463✔
148
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
78✔
149
   }
150
#endif
151

152
#if defined(BOTAN_HAS_X448)
153
   if(alg_name == "X448") {
9,155✔
154
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
4✔
155
   }
156
#endif
157

158
#if defined(BOTAN_HAS_MCELIECE)
159
   if(alg_name == "McEliece") {
9,153✔
160
      return std::make_unique<McEliece_PublicKey>(key_bits);
2✔
161
   }
162
#endif
163

164
#if defined(BOTAN_HAS_FRODOKEM)
165
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
9,153✔
166
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
632✔
167
   }
168
#endif
169

170
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
171
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
15,624✔
172
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
324✔
173
   }
174
#endif
175

176
#if defined(BOTAN_HAS_ML_KEM)
177
   if(alg_name.starts_with("ML-KEM-")) {
8,674✔
178
      return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
197✔
179
   }
180
#endif
181

182
#if defined(BOTAN_HAS_ECDSA)
183
   if(alg_name == "ECDSA") {
8,575✔
184
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
13,099✔
185
   }
186
#endif
187

188
#if defined(BOTAN_HAS_ECDH)
189
   if(alg_name == "ECDH") {
1,861✔
190
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
35✔
191
   }
192
#endif
193

194
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
195
   if(alg_name == "DH") {
1,843✔
196
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
11✔
197
   }
198
#endif
199

200
#if defined(BOTAN_HAS_DSA)
201
   if(alg_name == "DSA") {
1,835✔
202
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
355✔
203
   }
204
#endif
205

206
#if defined(BOTAN_HAS_ELGAMAL)
207
   if(alg_name == "ElGamal") {
1,601✔
208
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
209
   }
210
#endif
211

212
#if defined(BOTAN_HAS_ECGDSA)
213
   if(alg_name == "ECGDSA") {
1,597✔
214
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
146✔
215
   }
216
#endif
217

218
#if defined(BOTAN_HAS_ECKCDSA)
219
   if(alg_name == "ECKCDSA") {
1,524✔
220
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
144✔
221
   }
222
#endif
223

224
#if defined(BOTAN_HAS_ED25519)
225
   if(alg_name == "Ed25519") {
1,452✔
226
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,528✔
227
   }
228
#endif
229

230
#if defined(BOTAN_HAS_ED448)
231
   if(alg_name == "Ed448") {
688✔
232
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
146✔
233
   }
234
#endif
235

236
#if defined(BOTAN_HAS_GOST_34_10_2001)
237
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
747✔
238
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
132✔
239
   }
240
#endif
241

242
#if defined(BOTAN_HAS_SM2)
243
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
617✔
244
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
30✔
245
   }
246
#endif
247

248
#if defined(BOTAN_HAS_XMSS_RFC8391)
249
   if(alg_name == "XMSS") {
534✔
250
      return std::make_unique<XMSS_PublicKey>(key_bits);
70✔
251
   }
252
#endif
253

254
#if defined(BOTAN_HAS_XMSSMT_RFC8391)
255
   if(alg_name == "XMSSMT") {
499✔
256
      return std::make_unique<XMSSMT_PublicKey>(key_bits);
314✔
257
   }
258
#endif
259

260
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
261
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
344✔
262
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
168✔
263
   }
264
#endif
265

266
#if defined(BOTAN_HAS_ML_DSA)
267
   if(alg_name.starts_with("ML-DSA-")) {
258✔
268
      return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
120✔
269
   }
270
#endif
271

272
#if defined(BOTAN_HAS_HSS_LMS)
273
   if(alg_name == "HSS-LMS") {
198✔
274
      return std::make_unique<HSS_LMS_PublicKey>(key_bits);
106✔
275
   }
276
#endif
277

278
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
279
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
146✔
280
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
48✔
281
   }
282
#endif
283

284
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
285
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
121✔
286
      return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
86✔
287
   }
288
#endif
289

290
#if defined(BOTAN_HAS_CLASSICMCELIECE)
291
   if(alg_name.starts_with("ClassicMcEliece")) {
78✔
292
      return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
40✔
293
   }
294
#endif
295

296
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
116✔
297
}
28,452✔
298

299
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
5,062✔
300
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
301
   const std::string oid_str = alg_id.oid().to_formatted_string();
5,062✔
302
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
5,062✔
303
   const std::string_view alg_name = alg_info[0];
5,062✔
304

305
#if defined(BOTAN_HAS_RSA)
306
   if(alg_name == "RSA") {
5,062✔
307
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
1,023✔
308
   }
309
#endif
310

311
#if defined(BOTAN_HAS_X25519)
312
   if(alg_name == "X25519" || alg_name == "Curve25519") {
4,157✔
313
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
54✔
314
   }
315
#endif
316

317
#if defined(BOTAN_HAS_X448)
318
   if(alg_name == "X448") {
4,011✔
319
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
320
   }
321
#endif
322

323
#if defined(BOTAN_HAS_ECDSA)
324
   if(alg_name == "ECDSA") {
4,005✔
325
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
4,101✔
326
   }
327
#endif
328

329
#if defined(BOTAN_HAS_ECDH)
330
   if(alg_name == "ECDH") {
1,656✔
331
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
226✔
332
   }
333
#endif
334

335
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
336
   if(alg_name == "DH") {
1,526✔
337
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
79✔
338
   }
339
#endif
340

341
#if defined(BOTAN_HAS_DSA)
342
   if(alg_name == "DSA") {
1,480✔
343
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
373✔
344
   }
345
#endif
346

347
#if defined(BOTAN_HAS_FRODOKEM)
348
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
1,168✔
349
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
348✔
350
   }
351
#endif
352

353
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
354
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
834✔
355
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
219✔
356
   }
357
#endif
358

359
#if defined(BOTAN_HAS_ML_KEM)
360
   if(alg_name.starts_with("ML-KEM-")) {
597✔
361
      return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
93✔
362
   }
363
#endif
364

365
#if defined(BOTAN_HAS_MCELIECE)
366
   if(alg_name == "McEliece") {
504✔
367
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
368
   }
369
#endif
370

371
#if defined(BOTAN_HAS_ECGDSA)
372
   if(alg_name == "ECGDSA") {
500✔
373
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
374
   }
375
#endif
376

377
#if defined(BOTAN_HAS_ECKCDSA)
378
   if(alg_name == "ECKCDSA") {
482✔
379
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
380
   }
381
#endif
382

383
#if defined(BOTAN_HAS_ED25519)
384
   if(alg_name == "Ed25519") {
464✔
385
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
386
   }
387
#endif
388

389
#if defined(BOTAN_HAS_ED448)
390
   if(alg_name == "Ed448") {
454✔
391
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
36✔
392
   }
393
#endif
394

395
#if defined(BOTAN_HAS_GOST_34_10_2001)
396
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
481✔
397
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
398
   }
399
#endif
400

401
#if defined(BOTAN_HAS_SM2)
402
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
458✔
403
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
404
   }
405
#endif
406

407
#if defined(BOTAN_HAS_ELGAMAL)
408
   if(alg_name == "ElGamal") {
404✔
409
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
410
   }
411
#endif
412

413
#if defined(BOTAN_HAS_XMSS_RFC8391)
414
   if(alg_name == "XMSS") {
390✔
415
      return std::make_unique<XMSS_PrivateKey>(key_bits);
12✔
416
   }
417
#endif
418

419
#if defined(BOTAN_HAS_XMSSMT_RFC8391)
420
   if(alg_name == "XMSSMT") {
378✔
421
      return std::make_unique<XMSSMT_PrivateKey>(key_bits);
72✔
422
   }
423
#endif
424

425
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
426
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
316✔
427
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
55✔
428
   }
429
#endif
430

431
#if defined(BOTAN_HAS_ML_DSA)
432
   if(alg_name.starts_with("ML-DSA-")) {
251✔
433
      return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
24✔
434
   }
435
#endif
436

437
#if defined(BOTAN_HAS_HSS_LMS)
438
   if(alg_name == "HSS-LMS-Private-Key") {
227✔
439
      return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
6✔
440
   }
441
#endif
442

443
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
444
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
221✔
445
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
72✔
446
   }
447
#endif
448

449
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
450
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
149✔
451
      return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
72✔
452
   }
453
#endif
454

455
#if defined(BOTAN_HAS_CLASSICMCELIECE)
456
   if(alg_name.starts_with("ClassicMcEliece")) {
77✔
457
      return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
28✔
458
   }
459
#endif
460

461
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
98✔
462
}
5,062✔
463

464
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
411✔
465
                                                   const EC_Group& ec_group,
466
                                                   RandomNumberGenerator& rng) {
467
   // Potentially unused if all EC algorithms are disabled
468
   BOTAN_UNUSED(alg_name, ec_group, rng);
411✔
469

470
#if defined(BOTAN_HAS_ECDSA)
471
   if(alg_name == "ECDSA") {
411✔
472
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
472✔
473
   }
474
#endif
475

476
#if defined(BOTAN_HAS_ECDH)
477
   if(alg_name == "ECDH") {
175✔
478
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
106✔
479
   }
480
#endif
481

482
#if defined(BOTAN_HAS_ECKCDSA)
483
   if(alg_name == "ECKCDSA") {
122✔
484
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
90✔
485
   }
486
#endif
487

488
#if defined(BOTAN_HAS_GOST_34_10_2001)
489
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
89✔
490
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
24✔
491
   }
492
#endif
493

494
#if defined(BOTAN_HAS_SM2)
495
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
86✔
496
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
40✔
497
   }
498
#endif
499

500
#if defined(BOTAN_HAS_ECGDSA)
501
   if(alg_name == "ECGDSA") {
45✔
502
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
90✔
503
   }
504
#endif
505

506
   return nullptr;
×
507
}
508

509
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
1,520✔
510
                                                RandomNumberGenerator& rng,
511
                                                std::string_view params,
512
                                                std::string_view provider) {
513
   /*
514
   * Default parameters are chosen for work factor > 2**128 where possible
515
   */
516

517
#if defined(BOTAN_HAS_X25519)
518
   if(alg_name == "X25519" || alg_name == "Curve25519") {
1,836✔
519
      return std::make_unique<X25519_PrivateKey>(rng);
96✔
520
   }
521
#endif
522

523
#if defined(BOTAN_HAS_X448)
524
   if(alg_name == "X448") {
1,472✔
525
      return std::make_unique<X448_PrivateKey>(rng);
36✔
526
   }
527
#endif
528

529
#if defined(BOTAN_HAS_RSA)
530
   if(alg_name == "RSA") {
1,454✔
531
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
54✔
532
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
54✔
533
   }
534
#endif
535

536
#if defined(BOTAN_HAS_MCELIECE)
537
   if(alg_name == "McEliece") {
1,400✔
538
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
3✔
539
         if(params.empty()) {
3✔
540
            return {2960, 57};
×
541
         }
542

543
         const auto mce_params = split_on(params, ',');
3✔
544

545
         if(mce_params.size() != 2) {
3✔
546
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
547
         }
548

549
         const size_t mce_n = to_u32bit(mce_params[0]);
3✔
550
         const size_t mce_t = to_u32bit(mce_params[1]);
3✔
551
         return {mce_n, mce_t};
3✔
552
      }();
6✔
553

554
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
3✔
555
   }
556
#endif
557
#if defined(BOTAN_HAS_CLASSICMCELIECE)
558
   if(alg_name == "ClassicMcEliece") {
1,397✔
559
      auto cmce_params_set = params.empty() ? Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119f
51✔
560
                                            : Classic_McEliece_Parameter_Set::from_string(params);
51✔
561
      return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
51✔
562
   }
563
#endif
564

565
#if defined(BOTAN_HAS_FRODOKEM)
566
   if(alg_name == "FrodoKEM") {
1,346✔
567
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
322✔
568
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
322✔
569
   }
570
#endif
571

572
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
573
   if(alg_name == "Kyber") {
1,024✔
574
      const auto mode = [&]() -> KyberMode {
477✔
575
         if(params.empty()) {
159✔
576
            return KyberMode::Kyber1024_R3;
1✔
577
         }
578
         return KyberMode(params);
158✔
579
      }();
159✔
580

581
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
159✔
582
   }
583
#endif
584

585
#if defined(BOTAN_HAS_ML_KEM)
586
   if(alg_name == "ML-KEM") {
865✔
587
      const auto mode = [&]() -> ML_KEM_Mode {
567✔
588
         if(params.empty()) {
189✔
589
            return ML_KEM_Mode::ML_KEM_768;
1✔
590
         }
591
         return ML_KEM_Mode(params);
188✔
592
      }();
189✔
593

594
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
189✔
595
   }
596
#endif
597

598
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
599
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
695✔
600
      const auto mode = [&]() -> DilithiumMode {
19✔
601
         if(params.empty()) {
19✔
602
            return DilithiumMode::Dilithium6x5;
603
         }
604
         return DilithiumMode(params);
11✔
605
      }();
19✔
606

607
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
19✔
608
   }
609
#endif
610

611
#if defined(BOTAN_HAS_ML_DSA)
612
   if(alg_name == "ML-DSA") {
657✔
613
      const auto mode = [&]() -> ML_DSA_Mode {
19✔
614
         if(params.empty()) {
19✔
615
            return ML_DSA_Mode::ML_DSA_6x5;
616
         }
617
         return ML_DSA_Mode(params);
11✔
618
      }();
19✔
619

620
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
19✔
621
   }
622
#endif
623

624
#if defined(BOTAN_HAS_HSS_LMS)
625
   if(alg_name == "HSS-LMS") {
638✔
626
      const auto hss_params = [&]() -> std::string {
81✔
627
         if(params.empty()) {
27✔
628
            return "SHA-256,HW(10,1)";
×
629
         } else {
630
            return std::string(params);
27✔
631
         }
632
      }();
27✔
633
      return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
27✔
634
   }
27✔
635
#endif
636

637
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
638
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
611✔
639
      auto sphincs_params = Sphincs_Parameters::create(params);
×
640

641
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
×
642
   }
643
#endif
644

645
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
646
   if(alg_name == "SLH-DSA") {
611✔
647
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
52✔
648

649
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
52✔
650
   }
651
#endif
652

653
#if defined(BOTAN_HAS_XMSS_RFC8391)
654
   if(alg_name == "XMSS") {
559✔
655
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
15✔
656
         if(params.empty()) {
5✔
657
            return XMSS_Parameters::XMSS_SHA2_10_512;
658
         }
659
         return XMSS_Parameters(params).oid();
10✔
660
      }();
5✔
661

662
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
5✔
663
   }
664
#endif
665

666
#if defined(BOTAN_HAS_XMSSMT_RFC8391)
667
   if(alg_name == "XMSSMT") {
554✔
668
      const auto xmssmt_oid = [&]() -> XMSSMT_Parameters::xmssmt_algorithm_t {
45✔
669
         if(params.empty()) {
15✔
670
            return XMSSMT_Parameters::XMSSMT_SHA2_20_2_256;
671
         }
672
         return XMSSMT_Parameters(params).oid();
30✔
673
      }();
15✔
674

675
      return std::make_unique<XMSSMT_PrivateKey>(xmssmt_oid, rng);
15✔
676
   }
677
#endif
678

679
#if defined(BOTAN_HAS_ED25519)
680
   if(alg_name == "Ed25519") {
539✔
681
      return std::make_unique<Ed25519_PrivateKey>(rng);
72✔
682
   }
683
#endif
684

685
#if defined(BOTAN_HAS_ED448)
686
   if(alg_name == "Ed448") {
503✔
687
      return std::make_unique<Ed448_PrivateKey>(rng);
50✔
688
   }
689
#endif
690

691
   // ECC crypto
692
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
693

694
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
916✔
695
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
120✔
696
      alg_name == "GOST-34.10-2012-512") {
69✔
697
      const std::string group_id = [&]() -> std::string {
1,227✔
698
         if(!params.empty()) {
409✔
699
            return std::string(params);
400✔
700
         }
701
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
702
            return "sm2p256v1";
×
703
         }
704
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
705
            return "gost_256A";
×
706
         }
707
         if(alg_name == "GOST-34.10-2012-512") {
9✔
708
            return "gost_512A";
×
709
         }
710
         if(alg_name == "ECGDSA") {
9✔
711
            return "brainpool256r1";
×
712
         }
713
         return "secp256r1";
9✔
714
      }();
409✔
715

716
      if(EC_Group::supports_named_group(group_id)) {
409✔
717
         auto ec_group = EC_Group::from_name(group_id);
409✔
718
         return create_ec_private_key(alg_name, ec_group, rng);
409✔
719
      } else {
409✔
720
         return {};
×
721
      }
722
   }
409✔
723
#endif
724

725
   // DL crypto
726
#if defined(BOTAN_HAS_DL_GROUP)
727
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
138✔
728
      const std::string group_id = [&]() -> std::string {
207✔
729
         if(!params.empty()) {
69✔
730
            return std::string(params);
59✔
731
         }
732
         if(alg_name == "DSA") {
10✔
733
            return "dsa/botan/2048";
8✔
734
         }
735
         return "modp/ietf/2048";
2✔
736
      }();
69✔
737

738
      auto modp_group = DL_Group::from_name(group_id);
69✔
739

740
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
741
      if(alg_name == "DH") {
69✔
742
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
56✔
743
      }
744
   #endif
745

746
   #if defined(BOTAN_HAS_DSA)
747
      if(alg_name == "DSA") {
41✔
748
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
60✔
749
      }
750
   #endif
751

752
   #if defined(BOTAN_HAS_ELGAMAL)
753
      if(alg_name == "ElGamal") {
11✔
754
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
22✔
755
      }
756
   #endif
757
   }
69✔
758
#endif
759

760
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
761

762
   return std::unique_ptr<Private_Key>();
×
763
}
764

765
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
124✔
766
                                                    const std::vector<std::string>& possible) {
767
   std::vector<std::string> providers;
124✔
768

769
   for(auto&& prov : possible) {
620✔
770
      if(prov == "base") {
496✔
771
         providers.push_back(prov);
124✔
772
      }
773
   }
774

775
   BOTAN_UNUSED(alg_name);
124✔
776

777
   return providers;
124✔
778
}
×
779
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc