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

randombit / botan / 21753596263

06 Feb 2026 02:13PM UTC coverage: 90.063% (-0.01%) from 90.073%
21753596263

Pull #5289

github

web-flow
Merge 587099284 into 8ea0ca252
Pull Request #5289: Further misc header reductions, forward declarations, etc

102237 of 113517 relevant lines covered (90.06%)

11402137.11 hits per line

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

94.44
/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_SM2)
109
   #include <botan/sm2.h>
110
#endif
111

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

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

120
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
121
   #include <botan/sphincsplus.h>
122
#endif
123

124
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
125
   #include <botan/slh_dsa.h>
126
#endif
127

128
namespace Botan {
129

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

136
#if defined(BOTAN_HAS_RSA)
137
   if(alg_name == "RSA") {
28,303✔
138
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
37,680✔
139
   }
140
#endif
141

142
#if defined(BOTAN_HAS_X25519)
143
   if(alg_name == "X25519" || alg_name == "Curve25519") {
9,153✔
144
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
78✔
145
   }
146
#endif
147

148
#if defined(BOTAN_HAS_X448)
149
   if(alg_name == "X448") {
9,002✔
150
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
4✔
151
   }
152
#endif
153

154
#if defined(BOTAN_HAS_MCELIECE)
155
   if(alg_name == "McEliece") {
9,000✔
156
      return std::make_unique<McEliece_PublicKey>(key_bits);
2✔
157
   }
158
#endif
159

160
#if defined(BOTAN_HAS_FRODOKEM)
161
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
9,000✔
162
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
632✔
163
   }
164
#endif
165

166
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
167
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
15,475✔
168
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
324✔
169
   }
170
#endif
171

172
#if defined(BOTAN_HAS_ML_KEM)
173
   if(alg_name.starts_with("ML-KEM-")) {
8,521✔
174
      return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
197✔
175
   }
176
#endif
177

178
#if defined(BOTAN_HAS_ECDSA)
179
   if(alg_name == "ECDSA") {
8,422✔
180
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
13,107✔
181
   }
182
#endif
183

184
#if defined(BOTAN_HAS_ECDH)
185
   if(alg_name == "ECDH") {
1,704✔
186
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
35✔
187
   }
188
#endif
189

190
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
191
   if(alg_name == "DH") {
1,686✔
192
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
11✔
193
   }
194
#endif
195

196
#if defined(BOTAN_HAS_DSA)
197
   if(alg_name == "DSA") {
1,678✔
198
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
355✔
199
   }
200
#endif
201

202
#if defined(BOTAN_HAS_ELGAMAL)
203
   if(alg_name == "ElGamal") {
1,444✔
204
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
205
   }
206
#endif
207

208
#if defined(BOTAN_HAS_ECGDSA)
209
   if(alg_name == "ECGDSA") {
1,440✔
210
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
146✔
211
   }
212
#endif
213

214
#if defined(BOTAN_HAS_ECKCDSA)
215
   if(alg_name == "ECKCDSA") {
1,367✔
216
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
144✔
217
   }
218
#endif
219

220
#if defined(BOTAN_HAS_ED25519)
221
   if(alg_name == "Ed25519") {
1,295✔
222
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,528✔
223
   }
224
#endif
225

226
#if defined(BOTAN_HAS_ED448)
227
   if(alg_name == "Ed448") {
531✔
228
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
146✔
229
   }
230
#endif
231

232
#if defined(BOTAN_HAS_GOST_34_10_2001)
233
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
590✔
234
      return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
132✔
235
   }
236
#endif
237

238
#if defined(BOTAN_HAS_SM2)
239
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
460✔
240
      return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
30✔
241
   }
242
#endif
243

244
#if defined(BOTAN_HAS_XMSS_RFC8391)
245
   if(alg_name == "XMSS") {
377✔
246
      return std::make_unique<XMSS_PublicKey>(key_bits);
70✔
247
   }
248
#endif
249

250
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
251
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
344✔
252
      return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
168✔
253
   }
254
#endif
255

256
#if defined(BOTAN_HAS_ML_DSA)
257
   if(alg_name.starts_with("ML-DSA-")) {
258✔
258
      return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
120✔
259
   }
260
#endif
261

262
#if defined(BOTAN_HAS_HSS_LMS)
263
   if(alg_name == "HSS-LMS") {
198✔
264
      return std::make_unique<HSS_LMS_PublicKey>(key_bits);
106✔
265
   }
266
#endif
267

268
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
269
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
146✔
270
      return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
48✔
271
   }
272
#endif
273

274
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
275
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
121✔
276
      return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
86✔
277
   }
278
#endif
279

280
#if defined(BOTAN_HAS_CLASSICMCELIECE)
281
   if(alg_name.starts_with("ClassicMcEliece")) {
78✔
282
      return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
40✔
283
   }
284
#endif
285

286
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
116✔
287
}
28,303✔
288

289
std::unique_ptr<Private_Key> load_private_key(const AlgorithmIdentifier& alg_id,
4,990✔
290
                                              [[maybe_unused]] std::span<const uint8_t> key_bits) {
291
   const std::string oid_str = alg_id.oid().to_formatted_string();
4,990✔
292
   const std::vector<std::string> alg_info = split_on(oid_str, '/');
4,990✔
293
   const std::string_view alg_name = alg_info[0];
4,990✔
294

295
#if defined(BOTAN_HAS_RSA)
296
   if(alg_name == "RSA") {
4,990✔
297
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
1,023✔
298
   }
299
#endif
300

301
#if defined(BOTAN_HAS_X25519)
302
   if(alg_name == "X25519" || alg_name == "Curve25519") {
4,013✔
303
      return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
54✔
304
   }
305
#endif
306

307
#if defined(BOTAN_HAS_X448)
308
   if(alg_name == "X448") {
3,939✔
309
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
310
   }
311
#endif
312

313
#if defined(BOTAN_HAS_ECDSA)
314
   if(alg_name == "ECDSA") {
3,933✔
315
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
4,101✔
316
   }
317
#endif
318

319
#if defined(BOTAN_HAS_ECDH)
320
   if(alg_name == "ECDH") {
1,584✔
321
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
226✔
322
   }
323
#endif
324

325
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
326
   if(alg_name == "DH") {
1,454✔
327
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
79✔
328
   }
329
#endif
330

331
#if defined(BOTAN_HAS_DSA)
332
   if(alg_name == "DSA") {
1,408✔
333
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
373✔
334
   }
335
#endif
336

337
#if defined(BOTAN_HAS_FRODOKEM)
338
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
1,096✔
339
      return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
348✔
340
   }
341
#endif
342

343
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
344
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
762✔
345
      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
219✔
346
   }
347
#endif
348

349
#if defined(BOTAN_HAS_ML_KEM)
350
   if(alg_name.starts_with("ML-KEM-")) {
525✔
351
      return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
93✔
352
   }
353
#endif
354

355
#if defined(BOTAN_HAS_MCELIECE)
356
   if(alg_name == "McEliece") {
432✔
357
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
358
   }
359
#endif
360

361
#if defined(BOTAN_HAS_ECGDSA)
362
   if(alg_name == "ECGDSA") {
428✔
363
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
364
   }
365
#endif
366

367
#if defined(BOTAN_HAS_ECKCDSA)
368
   if(alg_name == "ECKCDSA") {
410✔
369
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
370
   }
371
#endif
372

373
#if defined(BOTAN_HAS_ED25519)
374
   if(alg_name == "Ed25519") {
392✔
375
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
376
   }
377
#endif
378

379
#if defined(BOTAN_HAS_ED448)
380
   if(alg_name == "Ed448") {
382✔
381
      return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
36✔
382
   }
383
#endif
384

385
#if defined(BOTAN_HAS_GOST_34_10_2001)
386
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
409✔
387
      return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
24✔
388
   }
389
#endif
390

391
#if defined(BOTAN_HAS_SM2)
392
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
386✔
393
      return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
40✔
394
   }
395
#endif
396

397
#if defined(BOTAN_HAS_ELGAMAL)
398
   if(alg_name == "ElGamal") {
332✔
399
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
400
   }
401
#endif
402

403
#if defined(BOTAN_HAS_XMSS_RFC8391)
404
   if(alg_name == "XMSS") {
318✔
405
      return std::make_unique<XMSS_PrivateKey>(key_bits);
12✔
406
   }
407
#endif
408

409
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
410
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
316✔
411
      return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
55✔
412
   }
413
#endif
414

415
#if defined(BOTAN_HAS_ML_DSA)
416
   if(alg_name.starts_with("ML-DSA-")) {
251✔
417
      return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
24✔
418
   }
419
#endif
420

421
#if defined(BOTAN_HAS_HSS_LMS)
422
   if(alg_name == "HSS-LMS-Private-Key") {
227✔
423
      return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
6✔
424
   }
425
#endif
426

427
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
428
   if(alg_name == "SPHINCS+" || alg_name.starts_with("SphincsPlus-")) {
221✔
429
      return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
72✔
430
   }
431
#endif
432

433
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
434
   if(alg_name.starts_with("SLH-DSA-") || alg_name.starts_with("Hash-SLH-DSA-")) {
149✔
435
      return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
72✔
436
   }
437
#endif
438

439
#if defined(BOTAN_HAS_CLASSICMCELIECE)
440
   if(alg_name.starts_with("ClassicMcEliece")) {
77✔
441
      return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
28✔
442
   }
443
#endif
444

445
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
98✔
446
}
4,990✔
447

448
std::unique_ptr<Private_Key> create_ec_private_key(std::string_view alg_name,
351✔
449
                                                   const EC_Group& ec_group,
450
                                                   RandomNumberGenerator& rng) {
451
   // Potentially unused if all EC algorithms are disabled
452
   BOTAN_UNUSED(alg_name, ec_group, rng);
351✔
453

454
#if defined(BOTAN_HAS_ECDSA)
455
   if(alg_name == "ECDSA") {
351✔
456
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
448✔
457
   }
458
#endif
459

460
#if defined(BOTAN_HAS_ECDH)
461
   if(alg_name == "ECDH") {
127✔
462
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
82✔
463
   }
464
#endif
465

466
#if defined(BOTAN_HAS_ECKCDSA)
467
   if(alg_name == "ECKCDSA") {
86✔
468
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
66✔
469
   }
470
#endif
471

472
#if defined(BOTAN_HAS_GOST_34_10_2001)
473
   if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512") {
65✔
474
      return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
24✔
475
   }
476
#endif
477

478
#if defined(BOTAN_HAS_SM2)
479
   if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc") {
50✔
480
      return std::make_unique<SM2_PrivateKey>(rng, ec_group);
16✔
481
   }
482
#endif
483

484
#if defined(BOTAN_HAS_ECGDSA)
485
   if(alg_name == "ECGDSA") {
33✔
486
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
66✔
487
   }
488
#endif
489

490
   return nullptr;
×
491
}
492

493
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
1,319✔
494
                                                RandomNumberGenerator& rng,
495
                                                std::string_view params,
496
                                                std::string_view provider) {
497
   /*
498
   * Default parameters are chosen for work factor > 2**128 where possible
499
   */
500

501
#if defined(BOTAN_HAS_X25519)
502
   if(alg_name == "X25519" || alg_name == "Curve25519") {
1,596✔
503
      return std::make_unique<X25519_PrivateKey>(rng);
72✔
504
   }
505
#endif
506

507
#if defined(BOTAN_HAS_X448)
508
   if(alg_name == "X448") {
1,283✔
509
      return std::make_unique<X448_PrivateKey>(rng);
10✔
510
   }
511
#endif
512

513
#if defined(BOTAN_HAS_RSA)
514
   if(alg_name == "RSA") {
1,278✔
515
      const size_t modulus_bits = params.empty() ? 3072 : to_u32bit(params);
40✔
516
      return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
40✔
517
   }
518
#endif
519

520
#if defined(BOTAN_HAS_MCELIECE)
521
   if(alg_name == "McEliece") {
1,238✔
522
      const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
2✔
523
         if(params.empty()) {
2✔
524
            return {2960, 57};
×
525
         }
526

527
         const auto mce_params = split_on(params, ',');
2✔
528

529
         if(mce_params.size() != 2) {
2✔
530
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
531
         }
532

533
         const size_t mce_n = to_u32bit(mce_params[0]);
2✔
534
         const size_t mce_t = to_u32bit(mce_params[1]);
2✔
535
         return {mce_n, mce_t};
2✔
536
      }();
4✔
537

538
      return std::make_unique<McEliece_PrivateKey>(rng, n, t);
2✔
539
   }
540
#endif
541
#if defined(BOTAN_HAS_CLASSICMCELIECE)
542
   if(alg_name == "ClassicMcEliece") {
1,236✔
543
      auto cmce_params_set = params.empty() ? Classic_McEliece_Parameter_Set::ClassicMcEliece_6960119f
39✔
544
                                            : Classic_McEliece_Parameter_Set::from_string(params);
39✔
545
      return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
39✔
546
   }
547
#endif
548

549
#if defined(BOTAN_HAS_FRODOKEM)
550
   if(alg_name == "FrodoKEM") {
1,197✔
551
      const auto mode = params.empty() ? FrodoKEMMode::FrodoKEM976_SHAKE : FrodoKEMMode(params);
322✔
552
      return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
322✔
553
   }
554
#endif
555

556
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
557
   if(alg_name == "Kyber") {
875✔
558
      const auto mode = [&]() -> KyberMode {
477✔
559
         if(params.empty()) {
159✔
560
            return KyberMode::Kyber1024_R3;
1✔
561
         }
562
         return KyberMode(params);
158✔
563
      }();
159✔
564

565
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
159✔
566
   }
567
#endif
568

569
#if defined(BOTAN_HAS_ML_KEM)
570
   if(alg_name == "ML-KEM") {
716✔
571
      const auto mode = [&]() -> ML_KEM_Mode {
567✔
572
         if(params.empty()) {
189✔
573
            return ML_KEM_Mode::ML_KEM_768;
1✔
574
         }
575
         return ML_KEM_Mode(params);
188✔
576
      }();
189✔
577

578
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
189✔
579
   }
580
#endif
581

582
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
583
   if(alg_name == "Dilithium" || alg_name.starts_with("Dilithium-")) {
546✔
584
      const auto mode = [&]() -> DilithiumMode {
19✔
585
         if(params.empty()) {
19✔
586
            return DilithiumMode::Dilithium6x5;
587
         }
588
         return DilithiumMode(params);
11✔
589
      }();
19✔
590

591
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
19✔
592
   }
593
#endif
594

595
#if defined(BOTAN_HAS_ML_DSA)
596
   if(alg_name == "ML-DSA") {
508✔
597
      const auto mode = [&]() -> ML_DSA_Mode {
19✔
598
         if(params.empty()) {
19✔
599
            return ML_DSA_Mode::ML_DSA_6x5;
600
         }
601
         return ML_DSA_Mode(params);
11✔
602
      }();
19✔
603

604
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
19✔
605
   }
606
#endif
607

608
#if defined(BOTAN_HAS_HSS_LMS)
609
   if(alg_name == "HSS-LMS") {
489✔
610
      const auto hss_params = [&]() -> std::string {
45✔
611
         if(params.empty()) {
15✔
612
            return "SHA-256,HW(10,1)";
×
613
         } else {
614
            return std::string(params);
15✔
615
         }
616
      }();
15✔
617
      return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
15✔
618
   }
15✔
619
#endif
620

621
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
622
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
474✔
623
      auto sphincs_params = Sphincs_Parameters::create(params);
×
624

625
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
×
626
   }
627
#endif
628

629
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
630
   if(alg_name == "SLH-DSA") {
474✔
631
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
40✔
632

633
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
40✔
634
   }
635
#endif
636

637
#if defined(BOTAN_HAS_XMSS_RFC8391)
638
   if(alg_name == "XMSS") {
434✔
639
      const auto xmss_oid = [&]() -> XMSS_Parameters::xmss_algorithm_t {
15✔
640
         if(params.empty()) {
5✔
641
            return XMSS_Parameters::XMSS_SHA2_10_512;
642
         }
643
         return XMSS_Parameters(params).oid();
10✔
644
      }();
5✔
645

646
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
5✔
647
   }
648
#endif
649

650
#if defined(BOTAN_HAS_ED25519)
651
   if(alg_name == "Ed25519") {
429✔
652
      return std::make_unique<Ed25519_PrivateKey>(rng);
48✔
653
   }
654
#endif
655

656
#if defined(BOTAN_HAS_ED448)
657
   if(alg_name == "Ed448") {
405✔
658
      return std::make_unique<Ed448_PrivateKey>(rng);
26✔
659
   }
660
#endif
661

662
   // ECC crypto
663
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
664

665
   if(alg_name == "ECDSA" || alg_name == "ECDH" || alg_name == "ECKCDSA" || alg_name == "ECGDSA" || alg_name == "SM2" ||
757✔
666
      alg_name == "SM2_Sig" || alg_name == "SM2_Enc" || alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" ||
92✔
667
      alg_name == "GOST-34.10-2012-512") {
43✔
668
      const std::string group_id = [&]() -> std::string {
1,047✔
669
         if(!params.empty()) {
349✔
670
            return std::string(params);
340✔
671
         }
672
         if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig") {
9✔
673
            return "sm2p256v1";
×
674
         }
675
         if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256") {
9✔
676
            return "gost_256A";
×
677
         }
678
         if(alg_name == "GOST-34.10-2012-512") {
9✔
679
            return "gost_512A";
×
680
         }
681
         if(alg_name == "ECGDSA") {
9✔
682
            return "brainpool256r1";
×
683
         }
684
         return "secp256r1";
9✔
685
      }();
349✔
686

687
      if(EC_Group::supports_named_group(group_id)) {
349✔
688
         auto ec_group = EC_Group::from_name(group_id);
349✔
689
         return create_ec_private_key(alg_name, ec_group, rng);
349✔
690
      } else {
349✔
691
         return {};
×
692
      }
693
   }
349✔
694
#endif
695

696
   // DL crypto
697
#if defined(BOTAN_HAS_DL_GROUP)
698
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal") {
86✔
699
      const std::string group_id = [&]() -> std::string {
129✔
700
         if(!params.empty()) {
43✔
701
            return std::string(params);
33✔
702
         }
703
         if(alg_name == "DSA") {
10✔
704
            return "dsa/botan/2048";
8✔
705
         }
706
         return "modp/ietf/2048";
2✔
707
      }();
43✔
708

709
      auto modp_group = DL_Group::from_name(group_id);
43✔
710

711
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
712
      if(alg_name == "DH") {
43✔
713
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
30✔
714
      }
715
   #endif
716

717
   #if defined(BOTAN_HAS_DSA)
718
      if(alg_name == "DSA") {
28✔
719
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
36✔
720
      }
721
   #endif
722

723
   #if defined(BOTAN_HAS_ELGAMAL)
724
      if(alg_name == "ElGamal") {
10✔
725
         return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
20✔
726
      }
727
   #endif
728
   }
43✔
729
#endif
730

731
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
732

733
   return std::unique_ptr<Private_Key>();
×
734
}
735

736
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
112✔
737
                                                    const std::vector<std::string>& possible) {
738
   std::vector<std::string> providers;
112✔
739

740
   for(auto&& prov : possible) {
560✔
741
      if(prov == "base") {
448✔
742
         providers.push_back(prov);
112✔
743
      }
744
   }
745

746
   BOTAN_UNUSED(alg_name);
112✔
747

748
   return providers;
112✔
749
}
×
750
}  // 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