125 [[maybe_unused]] std::span<const uint8_t> key_bits) {
127 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
128 std::string_view alg_name = alg_info[0];
130#if defined(BOTAN_HAS_RSA)
131 if(alg_name ==
"RSA") {
132 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
136#if defined(BOTAN_HAS_X25519)
137 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
138 return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
142#if defined(BOTAN_HAS_X448)
143 if(alg_name ==
"X448") {
144 return std::make_unique<X448_PublicKey>(alg_id, key_bits);
148#if defined(BOTAN_HAS_MCELIECE)
149 if(alg_name ==
"McEliece") {
150 return std::make_unique<McEliece_PublicKey>(key_bits);
154#if defined(BOTAN_HAS_FRODOKEM)
155 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
156 return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
160#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
161 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
162 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
166#if defined(BOTAN_HAS_ML_KEM)
167 if(alg_name.starts_with(
"ML-KEM-")) {
168 return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
172#if defined(BOTAN_HAS_ECDSA)
173 if(alg_name ==
"ECDSA") {
174 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
178#if defined(BOTAN_HAS_ECDH)
179 if(alg_name ==
"ECDH") {
180 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
184#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
185 if(alg_name ==
"DH") {
186 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
190#if defined(BOTAN_HAS_DSA)
191 if(alg_name ==
"DSA") {
192 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
196#if defined(BOTAN_HAS_ELGAMAL)
197 if(alg_name ==
"ElGamal") {
198 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
202#if defined(BOTAN_HAS_ECGDSA)
203 if(alg_name ==
"ECGDSA") {
204 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
208#if defined(BOTAN_HAS_ECKCDSA)
209 if(alg_name ==
"ECKCDSA") {
210 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
214#if defined(BOTAN_HAS_ED25519)
215 if(alg_name ==
"Ed25519") {
216 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
220#if defined(BOTAN_HAS_ED448)
221 if(alg_name ==
"Ed448") {
222 return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
226#if defined(BOTAN_HAS_GOST_34_10_2001)
227 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
228 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
232#if defined(BOTAN_HAS_SM2)
233 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
234 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
238#if defined(BOTAN_HAS_XMSS_RFC8391)
239 if(alg_name ==
"XMSS") {
240 return std::make_unique<XMSS_PublicKey>(key_bits);
244#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
245 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
246 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
250#if defined(BOTAN_HAS_ML_DSA)
251 if(alg_name.starts_with(
"ML-DSA-")) {
252 return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
256#if defined(BOTAN_HAS_HSS_LMS)
257 if(alg_name ==
"HSS-LMS") {
258 return std::make_unique<HSS_LMS_PublicKey>(key_bits);
262#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
263 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
264 return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
268#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
269 if(alg_name.starts_with(
"SLH-DSA-") || alg_name.starts_with(
"Hash-SLH-DSA-")) {
270 return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
274#if defined(BOTAN_HAS_CLASSICMCELIECE)
275 if(alg_name.starts_with(
"ClassicMcEliece")) {
276 return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
280 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
284 [[maybe_unused]] std::span<const uint8_t> key_bits) {
286 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
287 std::string_view alg_name = alg_info[0];
289#if defined(BOTAN_HAS_RSA)
290 if(alg_name ==
"RSA") {
291 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
295#if defined(BOTAN_HAS_X25519)
296 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
297 return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
301#if defined(BOTAN_HAS_X448)
302 if(alg_name ==
"X448") {
303 return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
307#if defined(BOTAN_HAS_ECDSA)
308 if(alg_name ==
"ECDSA") {
309 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
313#if defined(BOTAN_HAS_ECDH)
314 if(alg_name ==
"ECDH") {
315 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
319#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
320 if(alg_name ==
"DH") {
321 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
325#if defined(BOTAN_HAS_DSA)
326 if(alg_name ==
"DSA") {
327 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
331#if defined(BOTAN_HAS_FRODOKEM)
332 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
333 return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
337#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
338 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
339 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
343#if defined(BOTAN_HAS_ML_KEM)
344 if(alg_name.starts_with(
"ML-KEM-")) {
345 return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
349#if defined(BOTAN_HAS_MCELIECE)
350 if(alg_name ==
"McEliece") {
351 return std::make_unique<McEliece_PrivateKey>(key_bits);
355#if defined(BOTAN_HAS_ECGDSA)
356 if(alg_name ==
"ECGDSA") {
357 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
361#if defined(BOTAN_HAS_ECKCDSA)
362 if(alg_name ==
"ECKCDSA") {
363 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
367#if defined(BOTAN_HAS_ED25519)
368 if(alg_name ==
"Ed25519") {
369 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
373#if defined(BOTAN_HAS_ED448)
374 if(alg_name ==
"Ed448") {
375 return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
379#if defined(BOTAN_HAS_GOST_34_10_2001)
380 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
381 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
385#if defined(BOTAN_HAS_SM2)
386 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
387 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
391#if defined(BOTAN_HAS_ELGAMAL)
392 if(alg_name ==
"ElGamal") {
393 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
397#if defined(BOTAN_HAS_XMSS_RFC8391)
398 if(alg_name ==
"XMSS") {
399 return std::make_unique<XMSS_PrivateKey>(key_bits);
403#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
404 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
405 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
409#if defined(BOTAN_HAS_ML_DSA)
410 if(alg_name.starts_with(
"ML-DSA-")) {
411 return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
415#if defined(BOTAN_HAS_HSS_LMS)
416 if(alg_name ==
"HSS-LMS-Private-Key") {
417 return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
421#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
422 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
423 return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
427#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
428 if(alg_name.starts_with(
"SLH-DSA-") || alg_name.starts_with(
"Hash-SLH-DSA-")) {
429 return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
433#if defined(BOTAN_HAS_CLASSICMCELIECE)
434 if(alg_name.starts_with(
"ClassicMcEliece")) {
435 return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
439 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
448#if defined(BOTAN_HAS_ECDSA)
449 if(alg_name ==
"ECDSA") {
450 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
454#if defined(BOTAN_HAS_ECDH)
455 if(alg_name ==
"ECDH") {
456 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
460#if defined(BOTAN_HAS_ECKCDSA)
461 if(alg_name ==
"ECKCDSA") {
462 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
466#if defined(BOTAN_HAS_GOST_34_10_2001)
467 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
468 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
472#if defined(BOTAN_HAS_SM2)
473 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
474 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
478#if defined(BOTAN_HAS_ECGDSA)
479 if(alg_name ==
"ECGDSA") {
480 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
489 std::string_view params,
490 std::string_view provider) {
495#if defined(BOTAN_HAS_X25519)
496 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
497 return std::make_unique<X25519_PrivateKey>(rng);
501#if defined(BOTAN_HAS_X448)
502 if(alg_name ==
"X448") {
503 return std::make_unique<X448_PrivateKey>(rng);
507#if defined(BOTAN_HAS_RSA)
508 if(alg_name ==
"RSA") {
509 const size_t modulus_bits = params.empty() ? 3072 :
to_u32bit(params);
510 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
514#if defined(BOTAN_HAS_MCELIECE)
515 if(alg_name ==
"McEliece") {
516 const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
521 const auto mce_params =
split_on(params,
',');
523 if(mce_params.size() != 2) {
524 throw Invalid_Argument(
fmt(
"create_private_key: invalid McEliece parameters '{}'", params));
527 const size_t mce_n =
to_u32bit(mce_params[0]);
528 const size_t mce_t =
to_u32bit(mce_params[1]);
529 return {mce_n, mce_t};
532 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
535#if defined(BOTAN_HAS_CLASSICMCELIECE)
536 if(alg_name ==
"ClassicMcEliece") {
539 return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
543#if defined(BOTAN_HAS_FRODOKEM)
544 if(alg_name ==
"FrodoKEM") {
546 return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
550#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
551 if(alg_name ==
"Kyber") {
559 return std::make_unique<Kyber_PrivateKey>(rng, mode);
563#if defined(BOTAN_HAS_ML_KEM)
564 if(alg_name ==
"ML-KEM") {
572 return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
576#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
577 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
585 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
589#if defined(BOTAN_HAS_ML_DSA)
590 if(alg_name ==
"ML-DSA") {
598 return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
602#if defined(BOTAN_HAS_HSS_LMS)
603 if(alg_name ==
"HSS-LMS") {
604 const auto hss_params = [&]() -> std::string {
606 return "SHA-256,HW(10,1)";
608 return std::string(params);
611 return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
615#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
616 if(alg_name ==
"SPHINCS+" || alg_name ==
"SphincsPlus") {
619 return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
623#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
624 if(alg_name ==
"SLH-DSA") {
625 auto slh_dsa_params = SLH_DSA_Parameters::create(params);
627 return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
631#if defined(BOTAN_HAS_XMSS_RFC8391)
632 if(alg_name ==
"XMSS") {
640 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
644#if defined(BOTAN_HAS_ED25519)
645 if(alg_name ==
"Ed25519") {
646 return std::make_unique<Ed25519_PrivateKey>(rng);
650#if defined(BOTAN_HAS_ED448)
651 if(alg_name ==
"Ed448") {
652 return std::make_unique<Ed448_PrivateKey>(rng);
657#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
659 if(alg_name ==
"ECDSA" || alg_name ==
"ECDH" || alg_name ==
"ECKCDSA" || alg_name ==
"ECGDSA" || alg_name ==
"SM2" ||
660 alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc" || alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" ||
661 alg_name ==
"GOST-34.10-2012-512") {
662 const std::string group_id = [&]() -> std::string {
663 if(!params.empty()) {
664 return std::string(params);
666 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig") {
669 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256") {
672 if(alg_name ==
"GOST-34.10-2012-512") {
675 if(alg_name ==
"ECGDSA") {
676 return "brainpool256r1";
691#if defined(BOTAN_HAS_DL_GROUP)
692 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal") {
693 const std::string group_id = [&]() -> std::string {
694 if(!params.empty()) {
695 return std::string(params);
697 if(alg_name ==
"DSA") {
698 return "dsa/botan/2048";
700 return "modp/ietf/2048";
705 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
706 if(alg_name ==
"DH") {
707 return std::make_unique<DH_PrivateKey>(rng, modp_group);
711 #if defined(BOTAN_HAS_DSA)
712 if(alg_name ==
"DSA") {
713 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
717 #if defined(BOTAN_HAS_ELGAMAL)
718 if(alg_name ==
"ElGamal") {
719 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
727 return std::unique_ptr<Private_Key>();