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

randombit / botan / 23591805450

26 Mar 2026 11:25AM UTC coverage: 89.514% (+0.02%) from 89.49%
23591805450

Pull #5451

github

web-flow
Merge d4d4afeab into f42220269
Pull Request #5451: MLDSA-composite

106304 of 118757 relevant lines covered (89.51%)

12472589.86 hits per line

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

95.45
/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
#include <memory>
16

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

109
#if defined(BOTAN_HAS_SM2)
110
   #include <botan/sm2.h>
111
#endif
112

113
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
114
   #include <botan/dilithium.h>
115
#endif
116

117
#if defined(BOTAN_HAS_ML_DSA)
118
   #include <botan/ml_dsa.h>
119
#endif
120

121
#if defined(BOTAN_HAS_MLDSA_COMPOSITE)
122
   #include <botan/mldsa_comp.h>
123
#endif
124

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

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

133
namespace Botan {
134

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

141
#if defined(BOTAN_HAS_RSA)
142
   if(alg_name == "RSA") {
30,158✔
143
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
40,263✔
144
   }
145
#endif
146

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

255
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
256
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
401✔
257
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
168✔
258
   }
259
#endif
260

261
#if defined(BOTAN_HAS_ML_DSA)
262
   if(alg_name.starts_with("ML-DSA-")) {
315✔
263
      return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
120✔
264
   }
265
#endif
266

267
#if defined(BOTAN_HAS_MLDSA_COMPOSITE)
268
   if(alg_name.starts_with("MLDSA")) {
255✔
269
      auto comp_parm = MLDSA_Composite_Param::from_id_str(alg_name);
57✔
270
      if(comp_parm.has_value()) {
57✔
271
         return std::make_unique<MLDSA_Composite_PublicKey>(comp_parm->id(), key_bits);
114✔
272
      }
273
      // we continue the search as there might be other algorithms defined with leading "MLDSA"
274
   }
275
#endif
276

277
#if defined(BOTAN_HAS_HSS_LMS)
278
   if(alg_name == "HSS-LMS") {
198✔
279
      return std::make_unique<HSS_LMS_PublicKey>(key_bits);
106✔
280
   }
281
#endif
282

283
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
284
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
146✔
285
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
48✔
286
   }
287
#endif
288

289
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
290
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
121✔
291
      return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
86✔
292
   }
293
#endif
294

295
#if defined(BOTAN_HAS_CLASSICMCELIECE)
296
   if(alg_name.starts_with("ClassicMcEliece")) {
78✔
297
      return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
40✔
298
   }
299
#endif
300

301
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
116✔
302
}
30,158✔
303

304
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
6,229✔
305
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
306
   const std::string oid_str = alg_id.oid().to_formatted_string();
6,229✔
307
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
6,229✔
308
   const std::string_view alg_name = alg_info[0];
6,229✔
309

310
#if defined(BOTAN_HAS_RSA)
311
   if(alg_name == "RSA") {
6,229✔
312
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
2,241✔
313
   }
314
#endif
315

316
#if defined(BOTAN_HAS_X25519)
317
   if(alg_name == "X25519" || alg_name == "Curve25519") {
4,034✔
318
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
54✔
319
   }
320
#endif
321

322
#if defined(BOTAN_HAS_X448)
323
   if(alg_name == "X448") {
3,960✔
324
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
325
   }
326
#endif
327

328
#if defined(BOTAN_HAS_ECDSA)
329
   if(alg_name == "ECDSA") {
3,954✔
330
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
4,102✔
331
   }
332
#endif
333

334
#if defined(BOTAN_HAS_ECDH)
335
   if(alg_name == "ECDH") {
1,603✔
336
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
226✔
337
   }
338
#endif
339

340
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
341
   if(alg_name == "DH") {
1,473✔
342
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
79✔
343
   }
344
#endif
345

346
#if defined(BOTAN_HAS_DSA)
347
   if(alg_name == "DSA") {
1,427✔
348
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
373✔
349
   }
350
#endif
351

352
#if defined(BOTAN_HAS_FRODOKEM)
353
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
1,115✔
354
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
348✔
355
   }
356
#endif
357

358
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
359
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
781✔
360
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
219✔
361
   }
362
#endif
363

364
#if defined(BOTAN_HAS_ML_KEM)
365
   if(alg_name.starts_with("ML-KEM-")) {
544✔
366
      return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
93✔
367
   }
368
#endif
369

370
#if defined(BOTAN_HAS_MCELIECE)
371
   if(alg_name == "McEliece") {
451✔
372
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
373
   }
374
#endif
375

376
#if defined(BOTAN_HAS_ECGDSA)
377
   if(alg_name == "ECGDSA") {
447✔
378
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
379
   }
380
#endif
381

382
#if defined(BOTAN_HAS_ECKCDSA)
383
   if(alg_name == "ECKCDSA") {
429✔
384
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
385
   }
386
#endif
387

388
#if defined(BOTAN_HAS_ED25519)
389
   if(alg_name == "Ed25519") {
411✔
390
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
391
   }
392
#endif
393

394
#if defined(BOTAN_HAS_ED448)
395
   if(alg_name == "Ed448") {
401✔
396
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
36✔
397
   }
398
#endif
399

400
#if defined(BOTAN_HAS_GOST_34_10_2001)
401
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
428✔
402
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
403
   }
404
#endif
405

406
#if defined(BOTAN_HAS_SM2)
407
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
405✔
408
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
409
   }
410
#endif
411

412
#if defined(BOTAN_HAS_ELGAMAL)
413
   if(alg_name == "ElGamal") {
351✔
414
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
415
   }
416
#endif
417

418
#if defined(BOTAN_HAS_XMSS_RFC8391)
419
   if(alg_name == "XMSS") {
337✔
420
      return std::make_unique<XMSS_PrivateKey>(key_bits);
12✔
421
   }
422
#endif
423

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

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

436
#if defined(BOTAN_HAS_MLDSA_COMPOSITE)
437
   if(alg_name.starts_with("MLDSA")) {
246✔
438
      auto comp_parm = MLDSA_Composite_Param::from_id_str(alg_name);
19✔
439
      if(comp_parm.has_value()) {
19✔
440
         return std::make_unique<MLDSA_Composite_PrivateKey>(comp_parm->id(), key_bits);
19✔
441
      }
442
      // we continue the search as there might be other algorithms defined with leading "MLDSA"
443
   }
444
#endif
445

446
#if defined(BOTAN_HAS_HSS_LMS)
447
   if(alg_name == "HSS-LMS-Private-Key") {
227✔
448
      return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
6✔
449
   }
450
#endif
451

452
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
453
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
221✔
454
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
72✔
455
   }
456
#endif
457

458
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
459
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
149✔
460
      return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
72✔
461
   }
462
#endif
463

464
#if defined(BOTAN_HAS_CLASSICMCELIECE)
465
   if(alg_name.starts_with("ClassicMcEliece")) {
77✔
466
      return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
28✔
467
   }
468
#endif
469

470
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
98✔
471
}
6,229✔
472

473
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
421✔
474
                                                   const EC_Group& ec_group,
475
                                                   RandomNumberGenerator& rng) {
476
   // Potentially unused if all EC algorithms are disabled
477
   BOTAN_UNUSED(alg_name, ec_group, rng);
421✔
478

479
#if defined(BOTAN_HAS_ECDSA)
480
   if(alg_name == "ECDSA") {
421✔
481
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
474✔
482
   }
483
#endif
484

485
#if defined(BOTAN_HAS_ECDH)
486
   if(alg_name == "ECDH") {
184✔
487
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
114✔
488
   }
489
#endif
490

491
#if defined(BOTAN_HAS_ECKCDSA)
492
   if(alg_name == "ECKCDSA") {
127✔
493
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
96✔
494
   }
495
#endif
496

497
#if defined(BOTAN_HAS_GOST_34_10_2001)
498
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
91✔
499
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
24✔
500
   }
501
#endif
502

503
#if defined(BOTAN_HAS_SM2)
504
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
88✔
505
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
40✔
506
   }
507
#endif
508

509
#if defined(BOTAN_HAS_ECGDSA)
510
   if(alg_name == "ECGDSA") {
47✔
511
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
94✔
512
   }
513
#endif
514

515
   return nullptr;
×
516
}
517

518
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
1,580✔
519
                                                RandomNumberGenerator& rng,
520
                                                std::string_view params,
521
                                                std::string_view provider) {
522
   /*
523
   * Default parameters are chosen for work factor > 2**128 where possible
524
   */
525

526
#if defined(BOTAN_HAS_X25519)
527
   if(alg_name == "X25519" || alg_name == "Curve25519") {
1,885✔
528
      return std::make_unique<X25519_PrivateKey>(rng);
96✔
529
   }
530
#endif
531

532
#if defined(BOTAN_HAS_X448)
533
   if(alg_name == "X448") {
1,532✔
534
      return std::make_unique<X448_PrivateKey>(rng);
36✔
535
   }
536
#endif
537

538
#if defined(BOTAN_HAS_RSA)
539
   if(alg_name == "RSA") {
1,514✔
540
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
72✔
541
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
72✔
542
   }
543
#endif
544

545
#if defined(BOTAN_HAS_MCELIECE)
546
   if(alg_name == "McEliece") {
1,442✔
547
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
3✔
548
         if(params.empty()) {
3✔
549
            return {2960, 57};
×
550
         }
551

552
         const auto mce_params = split_on(params, ',');
3✔
553

554
         if(mce_params.size() != 2) {
3✔
555
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
556
         }
557

558
         const size_t mce_n = to_u32bit(mce_params[0]);
3✔
559
         const size_t mce_t = to_u32bit(mce_params[1]);
3✔
560
         return {mce_n, mce_t};
3✔
561
      }();
6✔
562

563
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
3✔
564
   }
565
#endif
566
#if defined(BOTAN_HAS_CLASSICMCELIECE)
567
   if(alg_name == "ClassicMcEliece") {
1,439✔
568
      auto cmce_params_set = params.empty() ? Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119f
51✔
569
                                            : Classic_McEliece_Parameter_Set::from_string(params);
51✔
570
      return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
51✔
571
   }
572
#endif
573

574
#if defined(BOTAN_HAS_FRODOKEM)
575
   if(alg_name == "FrodoKEM") {
1,388✔
576
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
324✔
577
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
324✔
578
   }
579
#endif
580

581
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
582
   if(alg_name == "Kyber") {
1,064✔
583
      const auto mode = [&]() -> KyberMode {
483✔
584
         if(params.empty()) {
161✔
585
            return KyberMode::Kyber1024_R3;
1✔
586
         }
587
         return KyberMode(params);
160✔
588
      }();
161✔
589

590
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
161✔
591
   }
592
#endif
593

594
#if defined(BOTAN_HAS_ML_KEM)
595
   if(alg_name == "ML-KEM") {
903✔
596
      const auto mode = [&]() -> ML_KEM_Mode {
570✔
597
         if(params.empty()) {
190✔
598
            return ML_KEM_Mode::ML_KEM_768;
1✔
599
         }
600
         return ML_KEM_Mode(params);
189✔
601
      }();
190✔
602

603
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
190✔
604
   }
605
#endif
606

607
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
608
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
734✔
609
      const auto mode = [&]() -> DilithiumMode {
21✔
610
         if(params.empty()) {
21✔
611
            return DilithiumMode::Dilithium6x5;
612
         }
613
         return DilithiumMode(params);
13✔
614
      }();
21✔
615

616
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
21✔
617
   }
618
#endif
619

620
#if defined(BOTAN_HAS_ML_DSA)
621
   if(alg_name == "ML-DSA") {
692✔
622
      const auto mode = [&]() -> ML_DSA_Mode {
20✔
623
         if(params.empty()) {
20✔
624
            return ML_DSA_Mode::ML_DSA_6x5;
625
         }
626
         return ML_DSA_Mode(params);
12✔
627
      }();
20✔
628

629
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
20✔
630
   }
631
#endif
632

633
#if defined(BOTAN_HAS_MLDSA_COMPOSITE)
634

635
   if(alg_name.starts_with("MLDSA")) {
672✔
636
      auto comp_parm = MLDSA_Composite_Param::from_id_str(alg_name);
30✔
637
      if(comp_parm.has_value()) {
30✔
638
         return std::make_unique<MLDSA_Composite_PrivateKey>(rng, comp_parm.value());
29✔
639
      }
640
      // we continue, there might be other algorithms defined with leading "MLDSA"
641
   }
642
#endif
643

644
#if defined(BOTAN_HAS_HSS_LMS)
645
   if(alg_name == "HSS-LMS") {
643✔
646
      const auto hss_params = [&]() -> std::string {
81✔
647
         if(params.empty()) {
27✔
648
            return "SHA-256,HW(10,1)";
×
649
         } else {
650
            return std::string(params);
27✔
651
         }
652
      }();
27✔
653
      return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
27✔
654
   }
27✔
655
#endif
656

657
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
658
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
616✔
659
      auto sphincs_params = Sphincs_Parameters::create(params);
×
660

661
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
×
662
   }
663
#endif
664

665
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
666
   if(alg_name == "SLH-DSA") {
616✔
667
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
52✔
668

669
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
52✔
670
   }
671
#endif
672

673
#if defined(BOTAN_HAS_XMSS_RFC8391)
674
   if(alg_name == "XMSS") {
564✔
675
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
18✔
676
         if(params.empty()) {
6✔
677
            return XMSS_Parameters::XMSS_SHA2_10_512;
678
         }
679
         return XMSS_Parameters(params).oid();
12✔
680
      }();
6✔
681

682
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
6✔
683
   }
684
#endif
685

686
#if defined(BOTAN_HAS_ED25519)
687
   if(alg_name == "Ed25519") {
558✔
688
      return std::make_unique<Ed25519_PrivateKey>(rng);
80✔
689
   }
690
#endif
691

692
#if defined(BOTAN_HAS_ED448)
693
   if(alg_name == "Ed448") {
518✔
694
      return std::make_unique<Ed448_PrivateKey>(rng);
58✔
695
   }
696
#endif
697

698
   // ECC crypto
699
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
700

701
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
937✔
702
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
124✔
703
      alg_name == "GOST-34.10-2012-512") {
71✔
704
      const std::string group_id = [&]() -> std::string {
1,254✔
705
         if(!params.empty()) {
418✔
706
            return std::string(params);
409✔
707
         }
708
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
709
            return "sm2p256v1";
×
710
         }
711
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
712
            return "gost_256A";
×
713
         }
714
         if(alg_name == "GOST-34.10-2012-512") {
9✔
715
            return "gost_512A";
×
716
         }
717
         if(alg_name == "ECGDSA") {
9✔
718
            return "brainpool256r1";
×
719
         }
720
         return "secp256r1";
9✔
721
      }();
418✔
722

723
      if(EC_Group::supports_named_group(group_id)) {
418✔
724
         auto ec_group = EC_Group::from_name(group_id);
418✔
725
         return create_ec_private_key(alg_name, ec_group, rng);
418✔
726
      } else {
418✔
727
         return {};
×
728
      }
729
   }
418✔
730
#endif
731

732
   // DL crypto
733
#if defined(BOTAN_HAS_DL_GROUP)
734
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
141✔
735
      const std::string group_id = [&]() -> std::string {
210✔
736
         if(!params.empty()) {
70✔
737
            return std::string(params);
60✔
738
         }
739
         if(alg_name == "DSA") {
10✔
740
            return "dsa/botan/2048";
8✔
741
         }
742
         return "modp/ietf/2048";
2✔
743
      }();
70✔
744

745
      auto modp_group = DL_Group::from_name(group_id);
70✔
746

747
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
748
      if(alg_name == "DH") {
70✔
749
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
56✔
750
      }
751
   #endif
752

753
   #if defined(BOTAN_HAS_DSA)
754
      if(alg_name == "DSA") {
42✔
755
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
60✔
756
      }
757
   #endif
758

759
   #if defined(BOTAN_HAS_ELGAMAL)
760
      if(alg_name == "ElGamal") {
12✔
761
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
24✔
762
      }
763
   #endif
764
   }
70✔
765
#endif
766

767
   BOTAN_UNUSED(alg_name, rng, params, provider);
1✔
768

769
   return std::unique_ptr<Private_Key>();
1✔
770
}
771

772
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
112✔
773
                                                    const std::vector<std::string>& possible) {
774
   std::vector<std::string> providers;
112✔
775

776
   for(auto&& prov : possible) {
560✔
777
      if(prov == "base") {
448✔
778
         providers.push_back(prov);
112✔
779
      }
780
   }
781

782
   BOTAN_UNUSED(alg_name);
112✔
783

784
   return providers;
112✔
785
}
×
786
}  // 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