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

randombit / botan / 21244058871

22 Jan 2026 07:50AM UTC coverage: 90.074% (-0.001%) from 90.075%
21244058871

push

github

web-flow
Merge pull request #5254 from Rohde-Schwarz/chore/tls_does_not_depend_on_secp

Avoid hard dependency on `pcurves_secp*` in the TLS module

102104 of 113356 relevant lines covered (90.07%)

11498532.38 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_ECDSA)
41
   #include <botan/ecdsa.h>
42
#endif
43

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

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

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

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

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

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

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

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

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

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

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

88
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
89
   #include <botan/kyber.h>
90
#endif
91

92
#if defined(BOTAN_HAS_ML_KEM)
93
   #include <botan/ml_kem.h>
94
#endif
95

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

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

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

108
#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
109
   #include <botan/dilithium.h>
110
#endif
111

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

116
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
117
   #include <botan/sphincsplus.h>
118
#endif
119

120
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
121
   #include <botan/slh_dsa.h>
122
#endif
123

124
namespace Botan {
125

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

132
#if defined(BOTAN_HAS_RSA)
133
   if(alg_name == "RSA") {
28,281✔
134
      return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
37,672✔
135
   }
136
#endif
137

138
#if defined(BOTAN_HAS_X25519)
139
   if(alg_name == "X25519" || alg_name == "Curve25519") {
9,135✔
140
      return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
78✔
141
   }
142
#endif
143

144
#if defined(BOTAN_HAS_X448)
145
   if(alg_name == "X448") {
8,984✔
146
      return std::make_unique<X448_PublicKey>(alg_id, key_bits);
4✔
147
   }
148
#endif
149

150
#if defined(BOTAN_HAS_MCELIECE)
151
   if(alg_name == "McEliece") {
8,982✔
152
      return std::make_unique<McEliece_PublicKey>(key_bits);
2✔
153
   }
154
#endif
155

156
#if defined(BOTAN_HAS_FRODOKEM)
157
   if(alg_name == "FrodoKEM" || alg_name.starts_with("FrodoKEM-") || alg_name.starts_with("eFrodoKEM-")) {
8,982✔
158
      return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
632✔
159
   }
160
#endif
161

162
#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
163
   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-")) {
15,439✔
164
      return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
324✔
165
   }
166
#endif
167

168
#if defined(BOTAN_HAS_ML_KEM)
169
   if(alg_name.starts_with("ML-KEM-")) {
8,503✔
170
      return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
197✔
171
   }
172
#endif
173

174
#if defined(BOTAN_HAS_ECDSA)
175
   if(alg_name == "ECDSA") {
8,404✔
176
      return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
13,085✔
177
   }
178
#endif
179

180
#if defined(BOTAN_HAS_ECDH)
181
   if(alg_name == "ECDH") {
1,704✔
182
      return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
35✔
183
   }
184
#endif
185

186
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
187
   if(alg_name == "DH") {
1,686✔
188
      return std::make_unique<DH_PublicKey>(alg_id, key_bits);
11✔
189
   }
190
#endif
191

192
#if defined(BOTAN_HAS_DSA)
193
   if(alg_name == "DSA") {
1,678✔
194
      return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
355✔
195
   }
196
#endif
197

198
#if defined(BOTAN_HAS_ELGAMAL)
199
   if(alg_name == "ElGamal") {
1,444✔
200
      return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
8✔
201
   }
202
#endif
203

204
#if defined(BOTAN_HAS_ECGDSA)
205
   if(alg_name == "ECGDSA") {
1,440✔
206
      return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
146✔
207
   }
208
#endif
209

210
#if defined(BOTAN_HAS_ECKCDSA)
211
   if(alg_name == "ECKCDSA") {
1,367✔
212
      return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
144✔
213
   }
214
#endif
215

216
#if defined(BOTAN_HAS_ED25519)
217
   if(alg_name == "Ed25519") {
1,295✔
218
      return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
1,528✔
219
   }
220
#endif
221

222
#if defined(BOTAN_HAS_ED448)
223
   if(alg_name == "Ed448") {
531✔
224
      return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
146✔
225
   }
226
#endif
227

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

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

240
#if defined(BOTAN_HAS_XMSS_RFC8391)
241
   if(alg_name == "XMSS") {
377✔
242
      return std::make_unique<XMSS_PublicKey>(key_bits);
70✔
243
   }
244
#endif
245

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

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

258
#if defined(BOTAN_HAS_HSS_LMS)
259
   if(alg_name == "HSS-LMS") {
198✔
260
      return std::make_unique<HSS_LMS_PublicKey>(key_bits);
106✔
261
   }
262
#endif
263

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

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

276
#if defined(BOTAN_HAS_CLASSICMCELIECE)
277
   if(alg_name.starts_with("ClassicMcEliece")) {
78✔
278
      return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
40✔
279
   }
280
#endif
281

282
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
116✔
283
}
28,281✔
284

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

291
#if defined(BOTAN_HAS_RSA)
292
   if(alg_name == "RSA") {
4,990✔
293
      return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
1,023✔
294
   }
295
#endif
296

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

303
#if defined(BOTAN_HAS_X448)
304
   if(alg_name == "X448") {
3,939✔
305
      return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
12✔
306
   }
307
#endif
308

309
#if defined(BOTAN_HAS_ECDSA)
310
   if(alg_name == "ECDSA") {
3,933✔
311
      return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
4,101✔
312
   }
313
#endif
314

315
#if defined(BOTAN_HAS_ECDH)
316
   if(alg_name == "ECDH") {
1,584✔
317
      return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
226✔
318
   }
319
#endif
320

321
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
322
   if(alg_name == "DH") {
1,454✔
323
      return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
79✔
324
   }
325
#endif
326

327
#if defined(BOTAN_HAS_DSA)
328
   if(alg_name == "DSA") {
1,408✔
329
      return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
373✔
330
   }
331
#endif
332

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

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

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

351
#if defined(BOTAN_HAS_MCELIECE)
352
   if(alg_name == "McEliece") {
432✔
353
      return std::make_unique<McEliece_PrivateKey>(key_bits);
4✔
354
   }
355
#endif
356

357
#if defined(BOTAN_HAS_ECGDSA)
358
   if(alg_name == "ECGDSA") {
428✔
359
      return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
36✔
360
   }
361
#endif
362

363
#if defined(BOTAN_HAS_ECKCDSA)
364
   if(alg_name == "ECKCDSA") {
410✔
365
      return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
36✔
366
   }
367
#endif
368

369
#if defined(BOTAN_HAS_ED25519)
370
   if(alg_name == "Ed25519") {
392✔
371
      return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
17✔
372
   }
373
#endif
374

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

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

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

393
#if defined(BOTAN_HAS_ELGAMAL)
394
   if(alg_name == "ElGamal") {
332✔
395
      return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
28✔
396
   }
397
#endif
398

399
#if defined(BOTAN_HAS_XMSS_RFC8391)
400
   if(alg_name == "XMSS") {
318✔
401
      return std::make_unique<XMSS_PrivateKey>(key_bits);
12✔
402
   }
403
#endif
404

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

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

417
#if defined(BOTAN_HAS_HSS_LMS)
418
   if(alg_name == "HSS-LMS-Private-Key") {
227✔
419
      return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
6✔
420
   }
421
#endif
422

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

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

435
#if defined(BOTAN_HAS_CLASSICMCELIECE)
436
   if(alg_name.starts_with("ClassicMcEliece")) {
77✔
437
      return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
28✔
438
   }
439
#endif
440

441
   throw Decoding_Error(fmt("Unknown or unavailable public key algorithm '{}'", alg_name));
98✔
442
}
4,990✔
443

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

450
#if defined(BOTAN_HAS_ECDSA)
451
   if(alg_name == "ECDSA") {
351✔
452
      return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
448✔
453
   }
454
#endif
455

456
#if defined(BOTAN_HAS_ECDH)
457
   if(alg_name == "ECDH") {
127✔
458
      return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
82✔
459
   }
460
#endif
461

462
#if defined(BOTAN_HAS_ECKCDSA)
463
   if(alg_name == "ECKCDSA") {
86✔
464
      return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
66✔
465
   }
466
#endif
467

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

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

480
#if defined(BOTAN_HAS_ECGDSA)
481
   if(alg_name == "ECGDSA") {
33✔
482
      return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
66✔
483
   }
484
#endif
485

486
   return nullptr;
×
487
}
488

489
std::unique_ptr<Private_Key> create_private_key(std::string_view alg_name,
1,318✔
490
                                                RandomNumberGenerator& rng,
491
                                                std::string_view params,
492
                                                std::string_view provider) {
493
   /*
494
   * Default parameters are chosen for work factor > 2**128 where possible
495
   */
496

497
#if defined(BOTAN_HAS_X25519)
498
   if(alg_name == "X25519" || alg_name == "Curve25519") {
1,594✔
499
      return std::make_unique<X25519_PrivateKey>(rng);
70✔
500
   }
501
#endif
502

503
#if defined(BOTAN_HAS_X448)
504
   if(alg_name == "X448") {
1,283✔
505
      return std::make_unique<X448_PrivateKey>(rng);
10✔
506
   }
507
#endif
508

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

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

523
         const auto mce_params = split_on(params, ',');
2✔
524

525
         if(mce_params.size() != 2) {
2✔
526
            throw Invalid_Argument(fmt("create_private_key: invalid McEliece parameters '{}'", params));
×
527
         }
528

529
         const size_t mce_n = to_u32bit(mce_params[0]);
2✔
530
         const size_t mce_t = to_u32bit(mce_params[1]);
2✔
531
         return {mce_n, mce_t};
2✔
532
      }();
4✔
533

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

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

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

561
      return std::make_unique<Kyber_PrivateKey>(rng, mode);
159✔
562
   }
563
#endif
564

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

574
      return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
189✔
575
   }
576
#endif
577

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

587
      return std::make_unique<Dilithium_PrivateKey>(rng, mode);
19✔
588
   }
589
#endif
590

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

600
      return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
19✔
601
   }
602
#endif
603

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

617
#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
618
   if(alg_name == "SPHINCS+" || alg_name == "SphincsPlus") {
474✔
619
      auto sphincs_params = Sphincs_Parameters::create(params);
×
620

621
      return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
×
622
   }
623
#endif
624

625
#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
626
   if(alg_name == "SLH-DSA") {
474✔
627
      auto slh_dsa_params = SLH_DSA_Parameters::create(params);
40✔
628

629
      return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
40✔
630
   }
631
#endif
632

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

642
      return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
5✔
643
   }
644
#endif
645

646
#if defined(BOTAN_HAS_ED25519)
647
   if(alg_name == "Ed25519") {
429✔
648
      return std::make_unique<Ed25519_PrivateKey>(rng);
48✔
649
   }
650
#endif
651

652
#if defined(BOTAN_HAS_ED448)
653
   if(alg_name == "Ed448") {
405✔
654
      return std::make_unique<Ed448_PrivateKey>(rng);
26✔
655
   }
656
#endif
657

658
   // ECC crypto
659
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
660

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

683
      if(EC_Group::supports_named_group(group_id)) {
349✔
684
         auto ec_group = EC_Group::from_name(group_id);
349✔
685
         return create_ec_private_key(alg_name, ec_group, rng);
349✔
686
      } else {
349✔
687
         return {};
×
688
      }
689
   }
349✔
690
#endif
691

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

705
      auto modp_group = DL_Group::from_name(group_id);
43✔
706

707
   #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
708
      if(alg_name == "DH") {
43✔
709
         return std::make_unique<DH_PrivateKey>(rng, modp_group);
30✔
710
      }
711
   #endif
712

713
   #if defined(BOTAN_HAS_DSA)
714
      if(alg_name == "DSA") {
28✔
715
         return std::make_unique<DSA_PrivateKey>(rng, modp_group);
36✔
716
      }
717
   #endif
718

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

727
   BOTAN_UNUSED(alg_name, rng, params, provider);
×
728

729
   return std::unique_ptr<Private_Key>();
×
730
}
731

732
std::vector<std::string> probe_provider_private_key(std::string_view alg_name,
112✔
733
                                                    const std::vector<std::string>& possible) {
734
   std::vector<std::string> providers;
112✔
735

736
   for(auto&& prov : possible) {
560✔
737
      if(prov == "base") {
448✔
738
         providers.push_back(prov);
112✔
739
      }
740
   }
741

742
   BOTAN_UNUSED(alg_name);
112✔
743

744
   return providers;
112✔
745
}
×
746
}  // 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