131 [[maybe_unused]] std::span<const uint8_t> key_bits) {
133 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
134 const std::string_view alg_name = alg_info[0];
136#if defined(BOTAN_HAS_RSA)
137 if(alg_name ==
"RSA") {
138 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
142#if defined(BOTAN_HAS_X25519)
143 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
144 return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
148#if defined(BOTAN_HAS_X448)
149 if(alg_name ==
"X448") {
150 return std::make_unique<X448_PublicKey>(alg_id, key_bits);
154#if defined(BOTAN_HAS_MCELIECE)
155 if(alg_name ==
"McEliece") {
156 return std::make_unique<McEliece_PublicKey>(key_bits);
160#if defined(BOTAN_HAS_FRODOKEM)
161 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
162 return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
166#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
167 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
168 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
172#if defined(BOTAN_HAS_ML_KEM)
173 if(alg_name.starts_with(
"ML-KEM-")) {
174 return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
178#if defined(BOTAN_HAS_ECDSA)
179 if(alg_name ==
"ECDSA") {
180 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
184#if defined(BOTAN_HAS_ECDH)
185 if(alg_name ==
"ECDH") {
186 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
190#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
191 if(alg_name ==
"DH") {
192 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
196#if defined(BOTAN_HAS_DSA)
197 if(alg_name ==
"DSA") {
198 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
202#if defined(BOTAN_HAS_ELGAMAL)
203 if(alg_name ==
"ElGamal") {
204 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
208#if defined(BOTAN_HAS_ECGDSA)
209 if(alg_name ==
"ECGDSA") {
210 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
214#if defined(BOTAN_HAS_ECKCDSA)
215 if(alg_name ==
"ECKCDSA") {
216 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
220#if defined(BOTAN_HAS_ED25519)
221 if(alg_name ==
"Ed25519") {
222 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
226#if defined(BOTAN_HAS_ED448)
227 if(alg_name ==
"Ed448") {
228 return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
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") {
234 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
238#if defined(BOTAN_HAS_SM2)
239 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
240 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
244#if defined(BOTAN_HAS_XMSS_RFC8391)
245 if(alg_name ==
"XMSS") {
246 return std::make_unique<XMSS_PublicKey>(key_bits);
250#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
251 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
252 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
256#if defined(BOTAN_HAS_ML_DSA)
257 if(alg_name.starts_with(
"ML-DSA-")) {
258 return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
262#if defined(BOTAN_HAS_HSS_LMS)
263 if(alg_name ==
"HSS-LMS") {
264 return std::make_unique<HSS_LMS_PublicKey>(key_bits);
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-")) {
270 return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
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-")) {
276 return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
280#if defined(BOTAN_HAS_CLASSICMCELIECE)
281 if(alg_name.starts_with(
"ClassicMcEliece")) {
282 return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
286 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
290 [[maybe_unused]] std::span<const uint8_t> key_bits) {
292 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
293 const std::string_view alg_name = alg_info[0];
295#if defined(BOTAN_HAS_RSA)
296 if(alg_name ==
"RSA") {
297 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
301#if defined(BOTAN_HAS_X25519)
302 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
303 return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
307#if defined(BOTAN_HAS_X448)
308 if(alg_name ==
"X448") {
309 return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
313#if defined(BOTAN_HAS_ECDSA)
314 if(alg_name ==
"ECDSA") {
315 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
319#if defined(BOTAN_HAS_ECDH)
320 if(alg_name ==
"ECDH") {
321 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
325#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
326 if(alg_name ==
"DH") {
327 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
331#if defined(BOTAN_HAS_DSA)
332 if(alg_name ==
"DSA") {
333 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
337#if defined(BOTAN_HAS_FRODOKEM)
338 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
339 return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
343#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
344 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
345 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
349#if defined(BOTAN_HAS_ML_KEM)
350 if(alg_name.starts_with(
"ML-KEM-")) {
351 return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
355#if defined(BOTAN_HAS_MCELIECE)
356 if(alg_name ==
"McEliece") {
357 return std::make_unique<McEliece_PrivateKey>(key_bits);
361#if defined(BOTAN_HAS_ECGDSA)
362 if(alg_name ==
"ECGDSA") {
363 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
367#if defined(BOTAN_HAS_ECKCDSA)
368 if(alg_name ==
"ECKCDSA") {
369 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
373#if defined(BOTAN_HAS_ED25519)
374 if(alg_name ==
"Ed25519") {
375 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
379#if defined(BOTAN_HAS_ED448)
380 if(alg_name ==
"Ed448") {
381 return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
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") {
387 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
391#if defined(BOTAN_HAS_SM2)
392 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
393 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
397#if defined(BOTAN_HAS_ELGAMAL)
398 if(alg_name ==
"ElGamal") {
399 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
403#if defined(BOTAN_HAS_XMSS_RFC8391)
404 if(alg_name ==
"XMSS") {
405 return std::make_unique<XMSS_PrivateKey>(key_bits);
409#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
410 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
411 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
415#if defined(BOTAN_HAS_ML_DSA)
416 if(alg_name.starts_with(
"ML-DSA-")) {
417 return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
421#if defined(BOTAN_HAS_HSS_LMS)
422 if(alg_name ==
"HSS-LMS-Private-Key") {
423 return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
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-")) {
429 return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
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-")) {
435 return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
439#if defined(BOTAN_HAS_CLASSICMCELIECE)
440 if(alg_name.starts_with(
"ClassicMcEliece")) {
441 return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
445 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
454#if defined(BOTAN_HAS_ECDSA)
455 if(alg_name ==
"ECDSA") {
456 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
460#if defined(BOTAN_HAS_ECDH)
461 if(alg_name ==
"ECDH") {
462 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
466#if defined(BOTAN_HAS_ECKCDSA)
467 if(alg_name ==
"ECKCDSA") {
468 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
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") {
474 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
478#if defined(BOTAN_HAS_SM2)
479 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
480 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
484#if defined(BOTAN_HAS_ECGDSA)
485 if(alg_name ==
"ECGDSA") {
486 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
495 std::string_view params,
496 std::string_view provider) {
501#if defined(BOTAN_HAS_X25519)
502 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
503 return std::make_unique<X25519_PrivateKey>(rng);
507#if defined(BOTAN_HAS_X448)
508 if(alg_name ==
"X448") {
509 return std::make_unique<X448_PrivateKey>(rng);
513#if defined(BOTAN_HAS_RSA)
514 if(alg_name ==
"RSA") {
515 const size_t modulus_bits = params.empty() ? 3072 :
to_u32bit(params);
516 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
520#if defined(BOTAN_HAS_MCELIECE)
521 if(alg_name ==
"McEliece") {
522 const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
527 const auto mce_params =
split_on(params,
',');
529 if(mce_params.size() != 2) {
530 throw Invalid_Argument(
fmt(
"create_private_key: invalid McEliece parameters '{}'", params));
533 const size_t mce_n =
to_u32bit(mce_params[0]);
534 const size_t mce_t =
to_u32bit(mce_params[1]);
535 return {mce_n, mce_t};
538 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
541#if defined(BOTAN_HAS_CLASSICMCELIECE)
542 if(alg_name ==
"ClassicMcEliece") {
545 return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
549#if defined(BOTAN_HAS_FRODOKEM)
550 if(alg_name ==
"FrodoKEM") {
552 return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
556#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
557 if(alg_name ==
"Kyber") {
565 return std::make_unique<Kyber_PrivateKey>(rng, mode);
569#if defined(BOTAN_HAS_ML_KEM)
570 if(alg_name ==
"ML-KEM") {
578 return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
582#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
583 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
591 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
595#if defined(BOTAN_HAS_ML_DSA)
596 if(alg_name ==
"ML-DSA") {
604 return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
608#if defined(BOTAN_HAS_HSS_LMS)
609 if(alg_name ==
"HSS-LMS") {
610 const auto hss_params = [&]() -> std::string {
612 return "SHA-256,HW(10,1)";
614 return std::string(params);
617 return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
621#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
622 if(alg_name ==
"SPHINCS+" || alg_name ==
"SphincsPlus") {
625 return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
629#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
630 if(alg_name ==
"SLH-DSA") {
631 auto slh_dsa_params = SLH_DSA_Parameters::create(params);
633 return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
637#if defined(BOTAN_HAS_XMSS_RFC8391)
638 if(alg_name ==
"XMSS") {
646 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
650#if defined(BOTAN_HAS_ED25519)
651 if(alg_name ==
"Ed25519") {
652 return std::make_unique<Ed25519_PrivateKey>(rng);
656#if defined(BOTAN_HAS_ED448)
657 if(alg_name ==
"Ed448") {
658 return std::make_unique<Ed448_PrivateKey>(rng);
663#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
665 if(alg_name ==
"ECDSA" || alg_name ==
"ECDH" || alg_name ==
"ECKCDSA" || alg_name ==
"ECGDSA" || alg_name ==
"SM2" ||
666 alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc" || alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" ||
667 alg_name ==
"GOST-34.10-2012-512") {
668 const std::string group_id = [&]() -> std::string {
669 if(!params.empty()) {
670 return std::string(params);
672 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig") {
675 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256") {
678 if(alg_name ==
"GOST-34.10-2012-512") {
681 if(alg_name ==
"ECGDSA") {
682 return "brainpool256r1";
697#if defined(BOTAN_HAS_DL_GROUP)
698 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal") {
699 const std::string group_id = [&]() -> std::string {
700 if(!params.empty()) {
701 return std::string(params);
703 if(alg_name ==
"DSA") {
704 return "dsa/botan/2048";
706 return "modp/ietf/2048";
711 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
712 if(alg_name ==
"DH") {
713 return std::make_unique<DH_PrivateKey>(rng, modp_group);
717 #if defined(BOTAN_HAS_DSA)
718 if(alg_name ==
"DSA") {
719 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
723 #if defined(BOTAN_HAS_ELGAMAL)
724 if(alg_name ==
"ElGamal") {
725 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
733 return std::unique_ptr<Private_Key>();